İlk commit
This commit is contained in:
commit
c325e6ca79
|
@ -0,0 +1,23 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
|
@ -0,0 +1,70 @@
|
|||
# Getting Started with Create React App
|
||||
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm start`
|
||||
|
||||
Runs the app in the development mode.\
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
|
||||
|
||||
The page will reload when you make changes.\
|
||||
You may also see any lint errors in the console.
|
||||
|
||||
### `npm test`
|
||||
|
||||
Launches the test runner in the interactive watch mode.\
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `build` folder.\
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.\
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
### `npm run eject`
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
|
||||
|
||||
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
|
||||
|
||||
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
|
||||
### Code Splitting
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
|
||||
|
||||
### `npm run build` fails to minify
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"name": "my-dashboard",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.7.2",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.7.2",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.7.2",
|
||||
"@fortawesome/react-fontawesome": "^0.2.2",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-icons": "^5.5.0",
|
||||
"react-router-dom": "^7.5.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.21",
|
||||
"postcss": "^8.5.3",
|
||||
"tailwindcss": "^4.1.3"
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Software License Dashboard</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
|
@ -0,0 +1,53 @@
|
|||
import React, { useState } from 'react';
|
||||
import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom';
|
||||
import LoginPage from './pages/LoginPage'; // Login sayfası
|
||||
import Navbar from './components/Navbar'; // Navbar bileşeni
|
||||
import Sidebar from './components/Sidebar'; // Sidebar bileşeni
|
||||
import AdminRoutes from './roles/AdminRoutes'; // Admin route bileşenleri
|
||||
import DistributorRoutes from './roles/DistributorRoutes'; // Distributor route bileşenleri
|
||||
import RetailerRoutes from './roles/RetailerRoutes'; // Retailer route bileşenleri
|
||||
import CustomerRoutes from './roles/CustomerRoutes'; // Customer route bileşenleri
|
||||
|
||||
function App() {
|
||||
const [user, setUser] = useState(null); // Kullanıcı verisini tutan durum
|
||||
|
||||
const handleLogin = (userData) => {
|
||||
setUser(userData); // Giriş yapan kullanıcının verilerini ayarlıyoruz
|
||||
};
|
||||
|
||||
const handleLogout = () => {
|
||||
setUser(null); // Kullanıcı çıkışı yaparsa, veriyi sıfırlıyoruz
|
||||
};
|
||||
|
||||
return (
|
||||
<Router>
|
||||
{/* Eğer kullanıcı giriş yapmamışsa, giriş sayfası gösterilsin */}
|
||||
{!user ? (
|
||||
<LoginPage onLogin={handleLogin} />
|
||||
) : (
|
||||
<div className="flex h-screen bg-gray-100">
|
||||
{/* Sidebar, kullanıcı rolüne göre gösterilecek */}
|
||||
<Sidebar user={user} onLogout={handleLogout} />
|
||||
<div className="flex-1 flex flex-col overflow-hidden">
|
||||
{/* Navbar, kullanıcı bilgisi ve çıkış fonksiyonu ile birlikte */}
|
||||
<Navbar user={user} onLogout={handleLogout} />
|
||||
<main className="flex-1 overflow-x-hidden overflow-y-auto bg-gray-200 p-4">
|
||||
{/* Kullanıcının rolüne göre yönlendirmeler */}
|
||||
<Routes>
|
||||
{user.role === 'admin' && <Route path="/*" element={<AdminRoutes />} />}
|
||||
{user.role === 'distributor' && <Route path="/*" element={<DistributorRoutes />} />}
|
||||
{user.role === 'retailer' && <Route path="/*" element={<RetailerRoutes />} />}
|
||||
{user.role === 'customer' && <Route path="/*" element={<CustomerRoutes />} />}
|
||||
|
||||
{/* Tanımlanmayan yollar için yönlendirme */}
|
||||
<Route path="*" element={<Navigate to="/" />} />
|
||||
</Routes>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
|
@ -0,0 +1,253 @@
|
|||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import {
|
||||
faBell,
|
||||
faUser,
|
||||
faCog,
|
||||
faSignOutAlt,
|
||||
faChevronDown,
|
||||
faChevronUp,
|
||||
faSearch,
|
||||
faMoon,
|
||||
faSun,
|
||||
faQuestionCircle
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import './navbar.css';
|
||||
import logo from '../assets/logo.png';
|
||||
|
||||
const Navbar = ({
|
||||
user,
|
||||
onLogout,
|
||||
notificationCount = 0,
|
||||
unreadMessages = 0,
|
||||
onThemeChange,
|
||||
currentTheme = 'light'
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const [showDropdown, setShowDropdown] = useState(false);
|
||||
const [showNotifications, setShowNotifications] = useState(false);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const dropdownRef = useRef(null);
|
||||
const notificationsRef = useRef(null);
|
||||
|
||||
// Close dropdowns when clicking outside
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event) => {
|
||||
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
||||
setShowDropdown(false);
|
||||
}
|
||||
if (notificationsRef.current && !notificationsRef.current.contains(event.target)) {
|
||||
setShowNotifications(false);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
return () => document.removeEventListener('mousedown', handleClickOutside);
|
||||
}, []);
|
||||
|
||||
// Close dropdowns when route changes
|
||||
useEffect(() => {
|
||||
setShowDropdown(false);
|
||||
setShowNotifications(false);
|
||||
}, [location.pathname]);
|
||||
|
||||
const handleProfileClick = () => {
|
||||
if (user?.role) {
|
||||
navigate(`/${user.role.toLowerCase()}/profile`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleLogout = () => {
|
||||
setShowDropdown(false);
|
||||
onLogout();
|
||||
};
|
||||
|
||||
const toggleDropdown = () => {
|
||||
setShowDropdown(!showDropdown);
|
||||
setShowNotifications(false);
|
||||
};
|
||||
|
||||
const toggleNotifications = () => {
|
||||
setShowNotifications(!showNotifications);
|
||||
setShowDropdown(false);
|
||||
};
|
||||
|
||||
const handleSearch = (e) => {
|
||||
e.preventDefault();
|
||||
if (searchQuery.trim()) {
|
||||
navigate(`/search?query=${encodeURIComponent(searchQuery)}`);
|
||||
setSearchQuery('');
|
||||
}
|
||||
};
|
||||
|
||||
const toggleTheme = () => {
|
||||
onThemeChange(currentTheme === 'light' ? 'dark' : 'light');
|
||||
};
|
||||
|
||||
return (
|
||||
<nav className={`navbar ${currentTheme}`}>
|
||||
{/* Left Section */}
|
||||
<div className="navbar-left">
|
||||
<div className="logo-container" onClick={() => navigate('/dashboard')}>
|
||||
<img src={logo} alt="Company Logo" className="navbar-logo" />
|
||||
<span className="navbar-brand">Priente Software License Dashboard </span>
|
||||
</div>
|
||||
|
||||
<form className="search-bar" onSubmit={handleSearch}>
|
||||
<button type="submit" className="search-button">
|
||||
<FontAwesomeIcon icon={faSearch} />
|
||||
</button>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search licenses, users..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{/* Right Section */}
|
||||
<div className="navbar-right">
|
||||
<div className="nav-icon" onClick={toggleTheme}>
|
||||
<FontAwesomeIcon icon={currentTheme === 'light' ? faMoon : faSun} />
|
||||
</div>
|
||||
|
||||
<div className="nav-icon" onClick={() => navigate('/help')}>
|
||||
<FontAwesomeIcon icon={faQuestionCircle} />
|
||||
</div>
|
||||
|
||||
<div className="notification-wrapper" ref={notificationsRef}>
|
||||
<div
|
||||
className={`notification-icon ${notificationCount > 0 ? 'has-notifications' : ''}`}
|
||||
onClick={toggleNotifications}
|
||||
>
|
||||
<FontAwesomeIcon icon={faBell} />
|
||||
{notificationCount > 0 && (
|
||||
<span className="notification-badge">
|
||||
{notificationCount > 9 ? '9+' : notificationCount}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{showNotifications && (
|
||||
<div className="notifications-dropdown">
|
||||
<div className="notifications-header">
|
||||
<h3>Notifications ({notificationCount})</h3>
|
||||
<button className="mark-all-read">Mark all as read</button>
|
||||
</div>
|
||||
<div className="notifications-list">
|
||||
{/* Sample notification items */}
|
||||
<div className="notification-item unread">
|
||||
<div className="notification-icon">
|
||||
<div className="alert-dot"></div>
|
||||
</div>
|
||||
<div className="notification-content">
|
||||
<p>New license request from John Doe</p>
|
||||
<small>2 minutes ago</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="notification-item">
|
||||
<div className="notification-icon"></div>
|
||||
<div className="notification-content">
|
||||
<p>Your subscription will renew soon</p>
|
||||
<small>1 hour ago</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="notifications-footer">
|
||||
<button onClick={() => navigate('/notifications')}>View All</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="user-dropdown" ref={dropdownRef}>
|
||||
<div
|
||||
className="user-profile"
|
||||
onClick={toggleDropdown}
|
||||
>
|
||||
<div className="avatar-container">
|
||||
<img
|
||||
src={user?.avatar || 'https://i.pravatar.cc/150?img=3'}
|
||||
alt="User"
|
||||
className="user-avatar"
|
||||
/>
|
||||
{unreadMessages > 0 && (
|
||||
<span className="message-badge">{unreadMessages}</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="user-info">
|
||||
<span className="user-name">{user?.name || 'Guest'}</span>
|
||||
<span className="user-role">{user?.role || 'User'}</span>
|
||||
</div>
|
||||
<FontAwesomeIcon
|
||||
icon={showDropdown ? faChevronUp : faChevronDown}
|
||||
className="dropdown-chevron"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{showDropdown && (
|
||||
<div className="dropdown-menu">
|
||||
<div className="dropdown-header">
|
||||
<div className="dropdown-avatar">
|
||||
<img
|
||||
src={user?.avatar || 'https://i.pravatar.cc/150?img=3'}
|
||||
alt="User"
|
||||
/>
|
||||
</div>
|
||||
<div className="dropdown-user-info">
|
||||
<h4>{user?.name || 'Guest'}</h4>
|
||||
<p>{user?.email || 'user@example.com'}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="dropdown-divider"></div>
|
||||
|
||||
<div className="dropdown-item" onClick={handleProfileClick}>
|
||||
<FontAwesomeIcon icon={faUser} />
|
||||
<span>My Profile</span>
|
||||
</div>
|
||||
|
||||
<div className="dropdown-item" onClick={() => navigate('/settings')}>
|
||||
<FontAwesomeIcon icon={faCog} />
|
||||
<span>Account Settings</span>
|
||||
</div>
|
||||
|
||||
<div className="dropdown-divider"></div>
|
||||
|
||||
<div className="dropdown-item logout-item" onClick={handleLogout}>
|
||||
<FontAwesomeIcon icon={faSignOutAlt} />
|
||||
<span>Sign Out</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
Navbar.propTypes = {
|
||||
user: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
role: PropTypes.string,
|
||||
avatar: PropTypes.string,
|
||||
email: PropTypes.string
|
||||
}),
|
||||
onLogout: PropTypes.func.isRequired,
|
||||
notificationCount: PropTypes.number,
|
||||
unreadMessages: PropTypes.number,
|
||||
onThemeChange: PropTypes.func,
|
||||
currentTheme: PropTypes.oneOf(['light', 'dark'])
|
||||
};
|
||||
|
||||
Navbar.defaultProps = {
|
||||
notificationCount: 0,
|
||||
unreadMessages: 0,
|
||||
currentTheme: 'light'
|
||||
};
|
||||
|
||||
export default Navbar;
|
|
@ -0,0 +1,105 @@
|
|||
import React, { useState } from 'react';
|
||||
import { NavLink, useLocation } from 'react-router-dom';
|
||||
import { FaChevronDown, FaChevronRight, FaTachometerAlt, FaChartLine, FaMoneyBillWave, FaSearchDollar, FaBullhorn, FaKey, FaHeadset, FaBoxOpen, FaCartPlus, FaSyncAlt, FaFileInvoiceDollar, FaPercentage, FaCommentAlt, FaChartPie, FaFileAlt, FaClipboardList, FaTruck, FaCreditCard, FaWarehouse, FaComments, FaUserTag, FaChartBar, FaShareSquare, FaTruckLoading, FaMoneyCheckAlt, FaAd, FaStarHalfAlt, FaQuestionCircle } from 'react-icons/fa';
|
||||
import './sidebar.css';
|
||||
|
||||
const Sidebar = ({ user }) => {
|
||||
const location = useLocation();
|
||||
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
|
||||
|
||||
// Role-based menu items
|
||||
const menuItems = {
|
||||
admin: [
|
||||
{ path: '/admin/dashboard', name: 'Dashboard', icon: <FaTachometerAlt /> },
|
||||
{ path: '/admin/general-sales', name: 'General Sales', icon: <FaChartLine /> },
|
||||
{ path: '/admin/finance', name: 'Finance', icon: <FaMoneyBillWave /> },
|
||||
{ path: '/admin/market-analysis', name: 'Market Analysis', icon: <FaSearchDollar /> },
|
||||
{ path: '/admin/campaigns', name: 'Campaigns', icon: <FaBullhorn /> },
|
||||
{ path: '/admin/license-management', name: 'License Management', icon: <FaKey /> },
|
||||
{ path: '/admin/support', name: 'Support', icon: <FaHeadset /> }
|
||||
],
|
||||
customer: [
|
||||
{ path: '/customer/dashboard', name: 'Dashboard', icon: <FaTachometerAlt /> },
|
||||
{ path: '/customer/purchased-software', name: 'My Software', icon: <FaBoxOpen /> },
|
||||
{ path: '/customer/software-purchase', name: 'Purchase', icon: <FaCartPlus /> },
|
||||
{ path: '/customer/license-updates', name: 'License Updates', icon: <FaSyncAlt /> },
|
||||
{ path: '/customer/payment-invoice', name: 'Payments & Invoices', icon: <FaFileInvoiceDollar /> },
|
||||
{ path: '/customer/promotions', name: 'Promotions', icon: <FaPercentage /> },
|
||||
{ path: '/customer/support-feedback', name: 'Support & Feedback', icon: <FaCommentAlt /> }
|
||||
],
|
||||
distributor: [
|
||||
{ path: '/distributor/dashboard', name: 'Dashboard', icon: <FaTachometerAlt /> },
|
||||
{ path: '/distributor/sales-performance', name: 'Sales Performance', icon: <FaChartPie /> },
|
||||
{ path: '/distributor/sales-reports', name: 'Sales Reports', icon: <FaFileAlt /> },
|
||||
{ path: '/distributor/order-management', name: 'Order Management', icon: <FaClipboardList /> },
|
||||
{ path: '/distributor/license-distribution', name: 'License Distribution', icon: <FaTruck /> },
|
||||
{ path: '/distributor/payment-billing', name: 'Payment & Billing', icon: <FaCreditCard /> },
|
||||
{ path: '/distributor/stock-campaign', name: 'Stock & Campaigns', icon: <FaWarehouse /> },
|
||||
{ path: '/distributor/retailer-feedback', name: 'Retailer Feedback', icon: <FaComments /> }
|
||||
],
|
||||
retailer: [
|
||||
{ path: '/retailer/dashboard', name: 'Dashboard', icon: <FaTachometerAlt /> },
|
||||
{ path: '/retailer/customer-sales', name: 'Customer Sales', icon: <FaUserTag /> },
|
||||
{ path: '/retailer/sales-reports', name: 'Sales Reports', icon: <FaChartBar /> },
|
||||
{ path: '/retailer/license-distribution', name: 'License Distribution', icon: <FaShareSquare /> },
|
||||
{ path: '/retailer/distributor-orders', name: 'Distributor Orders', icon: <FaTruckLoading /> },
|
||||
{ path: '/retailer/payment-collection', name: 'Payment Collection', icon: <FaMoneyCheckAlt /> },
|
||||
{ path: '/retailer/campaign-management', name: 'Campaigns', icon: <FaAd /> },
|
||||
{ path: '/retailer/customer-feedback', name: 'Customer Feedback', icon: <FaStarHalfAlt /> },
|
||||
{ path: '/retailer/sales-support', name: 'Support Requests', icon: <FaQuestionCircle /> }
|
||||
]
|
||||
};
|
||||
|
||||
const currentRole = user?.role?.toLowerCase() || 'customer';
|
||||
const currentMenu = menuItems[currentRole] || [];
|
||||
|
||||
const toggleSidebar = () => {
|
||||
setSidebarCollapsed(!sidebarCollapsed);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`sidebar ${sidebarCollapsed ? 'collapsed' : ''}`}>
|
||||
<button className="sidebar-toggle" onClick={toggleSidebar}>
|
||||
{sidebarCollapsed ? <FaChevronRight /> : <FaChevronDown />}
|
||||
</button>
|
||||
|
||||
<div className="sidebar-header">
|
||||
<div className="logo-container">
|
||||
<img
|
||||
src={user?.companyLogo || 'https://via.placeholder.com/40x40?text=Logo'}
|
||||
alt="Company Logo"
|
||||
className="company-logo"
|
||||
/>
|
||||
{!sidebarCollapsed && <h3>{user?.role || 'User'} Panel</h3>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav className="sidebar-nav">
|
||||
<ul>
|
||||
{currentMenu.map((item, index) => (
|
||||
<li key={index}>
|
||||
<NavLink
|
||||
to={item.path}
|
||||
className={({ isActive }) =>
|
||||
`nav-link ${isActive ? 'active' : ''} ${sidebarCollapsed ? 'collapsed' : ''}`
|
||||
}
|
||||
>
|
||||
{({ isActive }) => (
|
||||
<>
|
||||
<span className="nav-icon">{item.icon}</span>
|
||||
{!sidebarCollapsed && <span className="nav-text">{item.name}</span>}
|
||||
{!sidebarCollapsed && isActive && <div className="active-indicator"></div>}
|
||||
</>
|
||||
)}
|
||||
</NavLink>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sidebar;
|
|
@ -0,0 +1,485 @@
|
|||
:root {
|
||||
--primary-color: #4361ee;
|
||||
--secondary-color: #3a0ca3;
|
||||
--accent-color: #7209b7;
|
||||
--text-color: #2b2d42;
|
||||
--text-light: #8d99ae;
|
||||
--bg-color: #ffffff;
|
||||
--bg-secondary: #f8f9fa;
|
||||
--border-color: #e9ecef;
|
||||
--success-color: #4cc9f0;
|
||||
--warning-color: #f8961e;
|
||||
--danger-color: #f72585;
|
||||
--shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
--transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* Dark theme variables */
|
||||
.dark {
|
||||
--primary-color: #4895ef;
|
||||
--secondary-color: #560bad;
|
||||
--accent-color: #b5179e;
|
||||
--text-color: #f8f9fa;
|
||||
--text-light: #adb5bd;
|
||||
--bg-color: #212529;
|
||||
--bg-secondary: #343a40;
|
||||
--border-color: #495057;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 2rem;
|
||||
height: 70px;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
box-shadow: var(--shadow);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
transition: var(--transition);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.navbar-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.logo-container:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.navbar-logo {
|
||||
height: 32px;
|
||||
width: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: var(--primary-color);
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
position: relative;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.search-bar input {
|
||||
width: 100%;
|
||||
padding: 0.6rem 1rem 0.6rem 2.5rem;
|
||||
border-radius: 20px;
|
||||
border: 1px solid var(--border-color);
|
||||
background-color: var(--bg-secondary);
|
||||
color: var(--text-color);
|
||||
transition: var(--transition);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.search-bar input:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: 0 0 0 2px rgba(67, 97, 238, 0.2);
|
||||
}
|
||||
|
||||
.search-button {
|
||||
position: absolute;
|
||||
left: 0.75rem;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--text-light);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.navbar-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
font-size: 1.1rem;
|
||||
color: var(--text-light);
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 50%;
|
||||
transition: var(--transition);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.nav-icon:hover {
|
||||
background-color: var(--bg-secondary);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.notification-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.notification-icon {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 50%;
|
||||
transition: var(--transition);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.notification-icon:hover {
|
||||
background-color: var(--bg-secondary);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.notification-icon.has-notifications {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.notification-badge {
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
right: -2px;
|
||||
background-color: var(--danger-color);
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 0.6rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.notifications-dropdown {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 120%;
|
||||
width: 350px;
|
||||
background-color: var(--bg-color);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
|
||||
border: 1px solid var(--border-color);
|
||||
z-index: 1001;
|
||||
transform-origin: top right;
|
||||
animation: fadeIn 0.2s ease-out;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.notifications-header {
|
||||
padding: 1rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.notifications-header h3 {
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.mark-all-read {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--primary-color);
|
||||
font-size: 0.8rem;
|
||||
cursor: pointer;
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.mark-all-read:hover {
|
||||
background-color: rgba(67, 97, 238, 0.1);
|
||||
}
|
||||
|
||||
.notifications-list {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.notification-item {
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.notification-item:hover {
|
||||
background-color: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.notification-item.unread {
|
||||
background-color: rgba(67, 97, 238, 0.05);
|
||||
}
|
||||
|
||||
.notification-icon {
|
||||
position: relative;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.alert-dot {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: var(--danger-color);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.notification-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.notification-content p {
|
||||
margin: 0 0 0.25rem 0;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.notification-content small {
|
||||
color: var(--text-light);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.notifications-footer {
|
||||
padding: 0.75rem;
|
||||
text-align: center;
|
||||
border-top: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.notifications-footer button {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--primary-color);
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-dropdown {
|
||||
position: relative;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.user-profile {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-radius: 24px;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.user-profile:hover {
|
||||
background-color: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.avatar-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 2px solid var(--primary-color);
|
||||
}
|
||||
|
||||
.message-badge {
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
right: -5px;
|
||||
background-color: var(--danger-color);
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 0.6rem;
|
||||
font-weight: bold;
|
||||
border: 2px solid var(--bg-color);
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-weight: 500;
|
||||
font-size: 0.9rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.user-role {
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-light);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dropdown-chevron {
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-light);
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 120%;
|
||||
width: 260px;
|
||||
background-color: var(--bg-color);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
|
||||
border: 1px solid var(--border-color);
|
||||
z-index: 1001;
|
||||
transform-origin: top right;
|
||||
animation: fadeIn 0.2s ease-out;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dropdown-header {
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
background-color: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.dropdown-avatar img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 2px solid var(--primary-color);
|
||||
}
|
||||
|
||||
.dropdown-user-info h4 {
|
||||
margin: 0;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.dropdown-user-info p {
|
||||
margin: 0.25rem 0 0 0;
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.dropdown-divider {
|
||||
height: 1px;
|
||||
background-color: var(--border-color);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
padding: 0.75rem 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background-color: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.dropdown-item svg {
|
||||
width: 16px;
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.dropdown-item.logout-item {
|
||||
color: var(--danger-color);
|
||||
}
|
||||
|
||||
.dropdown-item.logout-item svg {
|
||||
color: var(--danger-color);
|
||||
}
|
||||
|
||||
.dropdown-item.logout-item:hover {
|
||||
background-color: rgba(247, 37, 133, 0.1);
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.95) translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 1024px) {
|
||||
.search-bar {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.navbar {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.user-name, .user-role {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.user-profile {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
width: 220px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.nav-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.notification-wrapper {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,292 @@
|
|||
:root {
|
||||
--sidebar-width: 280px;
|
||||
--sidebar-collapsed-width: 80px;
|
||||
--primary-color: #4361ee;
|
||||
--primary-light: #e6e9ff;
|
||||
--secondary-color: #3a0ca3;
|
||||
--text-color: #2b2d42;
|
||||
--text-light: #6c757d;
|
||||
--bg-color: #ffffff;
|
||||
--sidebar-bg: #ffffff;
|
||||
--border-color: #e9ecef;
|
||||
--shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
--transition: all 0.3s ease;
|
||||
--sidebar-transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
/* Dark theme variables */
|
||||
.dark-sidebar {
|
||||
--text-color: #f8f9fa;
|
||||
--text-light: #adb5bd;
|
||||
--sidebar-bg: #212529;
|
||||
--bg-color: #343a40;
|
||||
--border-color: #495057;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: var(--sidebar-width);
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background: var(--sidebar-bg);
|
||||
box-shadow: var(--shadow);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 100;
|
||||
transition: var(--sidebar-transition);
|
||||
border-right: 1px solid var(--border-color);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar.collapsed {
|
||||
width: var(--sidebar-collapsed-width);
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
background: var(--primary-light);
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
color: var(--primary-color);
|
||||
z-index: 101;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.sidebar-toggle:hover {
|
||||
background: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
padding: 1.5rem 1rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.company-logo {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
object-fit: contain;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.sidebar-header h3 {
|
||||
margin: 0;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: var(--primary-color);
|
||||
white-space: nowrap;
|
||||
transition: var(--sidebar-transition);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.sidebar.collapsed .sidebar-header h3 {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.sidebar-nav {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
.sidebar-nav ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sidebar-nav li {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 8px;
|
||||
color: var(--text-color);
|
||||
text-decoration: none;
|
||||
transition: var(--transition);
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.nav-link:hover:not(.active) {
|
||||
background-color: rgba(67, 97, 238, 0.1);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.nav-link.active {
|
||||
background-color: var(--primary-light);
|
||||
color: var(--primary-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.nav-link.collapsed {
|
||||
justify-content: center;
|
||||
padding: 0.75rem 0;
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
font-size: 1.1rem;
|
||||
margin-right: 0.75rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 24px;
|
||||
transition: var(--sidebar-transition);
|
||||
}
|
||||
|
||||
.sidebar.collapsed .nav-icon {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.nav-text {
|
||||
transition: var(--sidebar-transition);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.sidebar.collapsed .nav-text {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.active-indicator {
|
||||
position: absolute;
|
||||
right: 1rem;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: var(--primary-color);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.sidebar-footer {
|
||||
padding: 1rem;
|
||||
border-top: 1px solid var(--border-color);
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
transition: var(--sidebar-transition);
|
||||
}
|
||||
|
||||
.user-info.collapsed {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 2px solid var(--primary-color);
|
||||
}
|
||||
|
||||
.user-details {
|
||||
transition: var(--sidebar-transition);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
font-size: 0.9rem;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.user-email {
|
||||
margin: 0.1rem 0 0 0;
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.user-role {
|
||||
margin: 0.1rem 0 0 0;
|
||||
font-size: 0.7rem;
|
||||
color: var(--primary-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sidebar.collapsed .user-details {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* Scrollbar styling */
|
||||
.sidebar-nav::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.sidebar-nav::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.sidebar-nav::-webkit-scrollbar-thumb {
|
||||
background-color: rgba(155, 155, 155, 0.5);
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
/* Animation for sidebar items */
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-nav li {
|
||||
animation: fadeIn 0.3s ease forwards;
|
||||
}
|
||||
|
||||
.sidebar-nav li:nth-child(1) { animation-delay: 0.1s; }
|
||||
.sidebar-nav li:nth-child(2) { animation-delay: 0.15s; }
|
||||
.sidebar-nav li:nth-child(3) { animation-delay: 0.2s; }
|
||||
.sidebar-nav li:nth-child(4) { animation-delay: 0.25s; }
|
||||
.sidebar-nav li:nth-child(5) { animation-delay: 0.3s; }
|
||||
.sidebar-nav li:nth-child(6) { animation-delay: 0.35s; }
|
||||
.sidebar-nav li:nth-child(7) { animation-delay: 0.4s; }
|
||||
.sidebar-nav li:nth-child(8) { animation-delay: 0.45s; }
|
||||
.sidebar-nav li:nth-child(9) { animation-delay: 0.5s; }
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 992px) {
|
||||
.sidebar {
|
||||
transform: translateX(-100%);
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.sidebar.collapsed {
|
||||
transform: translateX(0);
|
||||
width: var(--sidebar-collapsed-width);
|
||||
}
|
||||
|
||||
.sidebar.active {
|
||||
transform: translateX(0);
|
||||
width: var(--sidebar-width);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
/* Main Content Styling */
|
||||
.main-content {
|
||||
margin-left: 250px;
|
||||
margin-top: 70px;
|
||||
padding: 20px;
|
||||
min-height: calc(100vh - 70px);
|
||||
background-color: #f5f7fa;
|
||||
transition: margin-left 0.3s;
|
||||
}
|
||||
|
||||
/* Cards */
|
||||
.dashboard-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
transition: transform 0.3s, box-shadow 0.3s;
|
||||
}
|
||||
|
||||
.dashboard-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.card-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.card-actions button {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #7f8c8d;
|
||||
cursor: pointer;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* Grid Layout */
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
.dashboard-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.dashboard-table th,
|
||||
.dashboard-table td {
|
||||
padding: 12px 15px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.dashboard-table th {
|
||||
background-color: #f8f9fa;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.dashboard-table tr:hover {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.btn {
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #3498db;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #2980b9;
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background-color: #2ecc71;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-success:hover {
|
||||
background-color: #27ae60;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background-color: #e74c3c;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-danger:hover {
|
||||
background-color: #c0392b;
|
||||
}
|
||||
|
||||
/* Forms */
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: 500;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
outline: none;
|
||||
border-color: #3498db;
|
||||
box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.main-content {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.grid-container {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById("root"));
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
|
@ -0,0 +1,69 @@
|
|||
import React from 'react';
|
||||
import './DashboardStyles.css';
|
||||
|
||||
const CampaignsPage = () => {
|
||||
const campaigns = [
|
||||
{ id: 1, name: 'Yaz İndirimi', status: 'Aktif', budget: '₺15,000', clicks: 1245, conversions: 89 },
|
||||
{ id: 2, name: 'Back to School', status: 'Planlanıyor', budget: '₺8,500', clicks: 0, conversions: 0 },
|
||||
{ id: 3, name: 'Kara Cuma', status: 'Tamamlandı', budget: '₺25,000', clicks: 3560, conversions: 210 },
|
||||
{ id: 4, name: 'Yılbaşı Kampanyası', status: 'Aktif', budget: '₺12,000', clicks: 980, conversions: 67 },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="dashboard-page">
|
||||
<h2 className="page-title">Kampanya Yönetimi</h2>
|
||||
<div className="stats-container">
|
||||
<div className="stat-card">
|
||||
<h3>Aktif Kampanyalar</h3>
|
||||
<p className="stat-value">2</p>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<h3>Toplam Harcama</h3>
|
||||
<p className="stat-value">₺27,000</p>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<h3>Toplam Dönüşüm</h3>
|
||||
<p className="stat-value">156</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="table-container">
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Kampanya Adı</th>
|
||||
<th>Durum</th>
|
||||
<th>Bütçe</th>
|
||||
<th>Tıklanma</th>
|
||||
<th>Dönüşüm</th>
|
||||
<th>İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{campaigns.map(campaign => (
|
||||
<tr key={campaign.id}>
|
||||
<td>{campaign.name}</td>
|
||||
<td>
|
||||
<span className={`status-badge ${campaign.status.toLowerCase()}`}>
|
||||
{campaign.status}
|
||||
</span>
|
||||
</td>
|
||||
<td>{campaign.budget}</td>
|
||||
<td>{campaign.clicks}</td>
|
||||
<td>{campaign.conversions}</td>
|
||||
<td>
|
||||
<button className="action-btn edit">Düzenle</button>
|
||||
<button className="action-btn delete">Sil</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<button className="add-new-btn">Yeni Kampanya Ekle</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CampaignsPage;
|
|
@ -0,0 +1,387 @@
|
|||
/* Genel Stiller */
|
||||
.dashboard-page {
|
||||
padding: 20px;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
color: #333;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
color: #2c3e50;
|
||||
margin-bottom: 25px;
|
||||
font-size: 28px;
|
||||
border-bottom: 2px solid #eee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Kart ve İstatistik Stilleri */
|
||||
.stats-container {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin-bottom: 30px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.stat-card.large {
|
||||
flex: 1.5;
|
||||
}
|
||||
|
||||
.stat-card h3 {
|
||||
font-size: 16px;
|
||||
color: #7f8c8d;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.stat-change {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.positive {
|
||||
color: #27ae60;
|
||||
}
|
||||
|
||||
.negative {
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
/* Tablo Stilleri */
|
||||
.table-container {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
padding: 20px;
|
||||
margin-bottom: 30px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.table-container h3 {
|
||||
margin-top: 0;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.data-table th {
|
||||
background-color: #f8f9fa;
|
||||
padding: 12px 15px;
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
border-bottom: 2px solid #eee;
|
||||
}
|
||||
|
||||
.data-table td {
|
||||
padding: 12px 15px;
|
||||
border-bottom: 1px solid #eee;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.data-table tr:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
/* Durum Etiketleri */
|
||||
.status-badge {
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.status-badge.aktif, .status-badge.active, .status-badge.açık, .status-badge.cevaplandı {
|
||||
background-color: #d5f5e3;
|
||||
color: #27ae60;
|
||||
}
|
||||
|
||||
.status-badge.inaktif, .status-badge.süresi-dolmuş, .status-badge.tamamlandı, .status-badge.çözüldü {
|
||||
background-color: #fadbd8;
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
.status-badge.planlanıyor {
|
||||
background-color: #fdebd0;
|
||||
color: #f39c12;
|
||||
}
|
||||
|
||||
/* Öncelik Etiketleri */
|
||||
.priority-badge {
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.priority-badge.yüksek {
|
||||
background-color: #fadbd8;
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
.priority-badge.orta {
|
||||
background-color: #fdebd0;
|
||||
color: #f39c12;
|
||||
}
|
||||
|
||||
.priority-badge.düşük {
|
||||
background-color: #d5f5e3;
|
||||
color: #27ae60;
|
||||
}
|
||||
|
||||
/* Buton Stilleri */
|
||||
.action-btn {
|
||||
border: none;
|
||||
padding: 6px 12px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
margin-right: 5px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.action-btn.edit {
|
||||
background-color: #3498db;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.action-btn.delete {
|
||||
background-color: #e74c3c;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.action-btn.view {
|
||||
background-color: #2ecc71;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.action-btn.assign {
|
||||
background-color: #9b59b6;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.action-btn.renew {
|
||||
background-color: #f39c12;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.action-btn.compare {
|
||||
background-color: #1abc9c;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.action-btn:hover {
|
||||
opacity: 0.9;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.add-new-btn, .generate-btn, .new-ticket-btn {
|
||||
background-color: #2ecc71;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.export-btn, .knowledge-base-btn {
|
||||
background-color: #3498db;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
margin-left: 10px;
|
||||
margin-bottom: 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* Grafik Alanları */
|
||||
.chart-container {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
padding: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.chart-container h3 {
|
||||
margin-top: 0;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.placeholder-chart {
|
||||
height: 300px;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #7f8c8d;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
/* Finans Kartları */
|
||||
.finance-overview {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin-bottom: 30px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.finance-card {
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.finance-card.income {
|
||||
background: linear-gradient(135deg, #2ecc71, #27ae60);
|
||||
}
|
||||
|
||||
.finance-card.expense {
|
||||
background: linear-gradient(135deg, #e74c3c, #c0392b);
|
||||
}
|
||||
|
||||
.finance-card.net {
|
||||
background: linear-gradient(135deg, #3498db, #2980b9);
|
||||
}
|
||||
|
||||
.finance-card h3 {
|
||||
margin-top: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.amount {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
/* Pazar Analizi Kartları */
|
||||
.market-overview {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin-bottom: 30px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.market-card {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.market-card h3 {
|
||||
font-size: 16px;
|
||||
color: #7f8c8d;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.market-value {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.market-change {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Değerlendirme Yıldızları */
|
||||
.rating-stars {
|
||||
color: #f1c40f;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.rating-value {
|
||||
color: #7f8c8d;
|
||||
font-size: 12px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/* Bilgi Kartları */
|
||||
.insight-card {
|
||||
background: #fff;
|
||||
border-left: 4px solid #3498db;
|
||||
border-radius: 4px;
|
||||
padding: 15px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.insight-card p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Son Aktivite Listesi */
|
||||
.recent-activity {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.activity-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.activity-list li {
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.activity-time {
|
||||
color: #7f8c8d;
|
||||
width: 80px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.activity-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Responsive Düzen */
|
||||
@media (max-width: 768px) {
|
||||
.stats-container, .finance-overview, .market-overview {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.stat-card, .finance-card, .market-card {
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
import React from 'react';
|
||||
import './DashboardStyles.css';
|
||||
|
||||
const FinancePage = () => {
|
||||
const transactions = [
|
||||
{ id: 1, date: '15.04.2023', description: 'Ürün Satışı', amount: '₺1,250.00', type: 'Gelir' },
|
||||
{ id: 2, date: '14.04.2023', description: 'Reklam Harcaması', amount: '₺-500.00', type: 'Gider' },
|
||||
{ id: 3, date: '13.04.2023', description: 'Üyelik Geliri', amount: '₺750.00', type: 'Gelir' },
|
||||
{ id: 4, date: '12.04.2023', description: 'Ofis Kirası', amount: '₺-2,000.00', type: 'Gider' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="dashboard-page">
|
||||
<h2 className="page-title">Finansal İşlemler</h2>
|
||||
|
||||
<div className="finance-overview">
|
||||
<div className="finance-card income">
|
||||
<h3>Toplam Gelir</h3>
|
||||
<p className="amount">₺12,450.00</p>
|
||||
<p className="change positive">+15% geçen aya göre</p>
|
||||
</div>
|
||||
<div className="finance-card expense">
|
||||
<h3>Toplam Gider</h3>
|
||||
<p className="amount">₺8,200.00</p>
|
||||
<p className="change negative">-5% geçen aya göre</p>
|
||||
</div>
|
||||
<div className="finance-card net">
|
||||
<h3>Net Kar</h3>
|
||||
<p className="amount">₺4,250.00</p>
|
||||
<p className="change positive">+22% geçen aya göre</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="chart-container">
|
||||
<h3>Son 6 Ay Finansal Performans</h3>
|
||||
<div className="placeholder-chart">
|
||||
{/* Buraya gerçek bir chart component'i eklenebilir */}
|
||||
<p>Grafik alanı (Chart.js veya benzeri kullanılabilir)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="table-container">
|
||||
<h3>Son İşlemler</h3>
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tarih</th>
|
||||
<th>Açıklama</th>
|
||||
<th>Tutar</th>
|
||||
<th>Tür</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{transactions.map(transaction => (
|
||||
<tr key={transaction.id}>
|
||||
<td>{transaction.date}</td>
|
||||
<td>{transaction.description}</td>
|
||||
<td className={transaction.type === 'Gelir' ? 'positive' : 'negative'}>
|
||||
{transaction.amount}
|
||||
</td>
|
||||
<td>{transaction.type}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FinancePage;
|
|
@ -0,0 +1,71 @@
|
|||
import React from 'react';
|
||||
import './DashboardStyles.css';
|
||||
|
||||
const GeneralSalesPage = () => {
|
||||
const salesData = [
|
||||
{ id: 1, product: 'Premium Üyelik', sales: 45, revenue: '₺4,500', change: '+12%' },
|
||||
{ id: 2, product: 'Temel Ürün Paketi', sales: 89, revenue: '₺8,900', change: '+5%' },
|
||||
{ id: 3, product: 'Pro Paket', sales: 32, revenue: '₺6,400', change: '+18%' },
|
||||
{ id: 4, product: 'Eğitim Seti', sales: 56, revenue: '₺2,800', change: '-3%' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="dashboard-page">
|
||||
<h2 className="page-title">Genel Satış Analizi</h2>
|
||||
|
||||
<div className="stats-container">
|
||||
<div className="stat-card large">
|
||||
<h3>Toplam Satış</h3>
|
||||
<p className="stat-value">222</p>
|
||||
<p className="stat-change positive">+8% geçen aya göre</p>
|
||||
</div>
|
||||
<div className="stat-card large">
|
||||
<h3>Toplam Gelir</h3>
|
||||
<p className="stat-value">₺22,600</p>
|
||||
<p className="stat-change positive">+12% geçen aya göre</p>
|
||||
</div>
|
||||
<div className="stat-card large">
|
||||
<h3>Ortalama Sipariş Değeri</h3>
|
||||
<p className="stat-value">₺101.80</p>
|
||||
<p className="stat-change positive">+4% geçen aya göre</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="chart-container">
|
||||
<h3>Aylık Satış Trendi</h3>
|
||||
<div className="placeholder-chart">
|
||||
{/* Buraya gerçek bir chart component'i eklenebilir */}
|
||||
<p>Satış grafiği alanı</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="table-container">
|
||||
<h3>Ürün Bazlı Satışlar</h3>
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Ürün Adı</th>
|
||||
<th>Satış Adedi</th>
|
||||
<th>Toplam Gelir</th>
|
||||
<th>Değişim</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{salesData.map(item => (
|
||||
<tr key={item.id}>
|
||||
<td>{item.product}</td>
|
||||
<td>{item.sales}</td>
|
||||
<td>{item.revenue}</td>
|
||||
<td className={item.change.startsWith('+') ? 'positive' : 'negative'}>
|
||||
{item.change}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default GeneralSalesPage;
|
|
@ -0,0 +1,73 @@
|
|||
import React from 'react';
|
||||
import './DashboardStyles.css';
|
||||
|
||||
const LicenseManagementPage = () => {
|
||||
const licenses = [
|
||||
{ id: 1, key: 'LXN-7890-ABCD-1234', type: 'Premium', owner: 'ABC Şirketi', expiry: '15.10.2023', status: 'Aktif' },
|
||||
{ id: 2, key: 'LXN-5678-EFGH-9012', type: 'Standart', owner: 'XYZ Ltd.', expiry: '30.09.2023', status: 'Aktif' },
|
||||
{ id: 3, key: 'LXN-3456-IJKL-7890', type: 'Trial', owner: 'Test Kullanıcı', expiry: '15.05.2023', status: 'Süresi Dolmuş' },
|
||||
{ id: 4, key: 'LXN-1234-MNOP-5678', type: 'Enterprise', owner: 'Büyük Şirket A.Ş.', expiry: '31.12.2024', status: 'Aktif' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="dashboard-page">
|
||||
<h2 className="page-title">Lisans Yönetim Paneli</h2>
|
||||
|
||||
<div className="license-stats">
|
||||
<div className="stat-card">
|
||||
<h3>Aktif Lisanslar</h3>
|
||||
<p className="stat-value">3</p>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<h3>Süresi Dolanlar</h3>
|
||||
<p className="stat-value">1</p>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<h3>Toplam Lisans</h3>
|
||||
<p className="stat-value">4</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="table-container">
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Lisans Anahtarı</th>
|
||||
<th>Tür</th>
|
||||
<th>Sahip</th>
|
||||
<th>Son Kullanma</th>
|
||||
<th>Durum</th>
|
||||
<th>İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{licenses.map(license => (
|
||||
<tr key={license.id}>
|
||||
<td>{license.key}</td>
|
||||
<td>{license.type}</td>
|
||||
<td>{license.owner}</td>
|
||||
<td>{license.expiry}</td>
|
||||
<td>
|
||||
<span className={`status-badge ${license.status === 'Aktif' ? 'aktif' : 'inaktif'}`}>
|
||||
{license.status}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button className="action-btn edit">Düzenle</button>
|
||||
<button className="action-btn renew">Yenile</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="license-actions">
|
||||
<button className="generate-btn">Yeni Lisans Oluştur</button>
|
||||
<button className="export-btn">Lisansları Dışa Aktar</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LicenseManagementPage;
|
|
@ -0,0 +1,91 @@
|
|||
import React from 'react';
|
||||
import './DashboardStyles.css';
|
||||
|
||||
const MarketAnalysisPage = () => {
|
||||
const competitors = [
|
||||
{ id: 1, name: 'Rakip A', marketShare: '32%', growth: '+4%', rating: 4.2 },
|
||||
{ id: 2, name: 'Rakip B', marketShare: '28%', growth: '+2%', rating: 3.8 },
|
||||
{ id: 3, name: 'Rakip C', marketShare: '18%', growth: '-1%', rating: 3.5 },
|
||||
{ id: 4, name: 'Rakip D', marketShare: '12%', growth: '+1%', rating: 3.2 },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="dashboard-page">
|
||||
<h2 className="page-title">Pazar Analiz Paneli</h2>
|
||||
|
||||
<div className="market-overview">
|
||||
<div className="market-card">
|
||||
<h3>Pazar Payımız</h3>
|
||||
<p className="market-value">10%</p>
|
||||
<p className="market-change positive">+3% geçen yıla göre</p>
|
||||
</div>
|
||||
<div className="market-card">
|
||||
<h3>Yıllık Büyüme</h3>
|
||||
<p className="market-value">25%</p>
|
||||
<p className="market-change positive">Sektör ort: 8%</p>
|
||||
</div>
|
||||
<div className="market-card">
|
||||
<h3>Müşteri Memnuniyeti</h3>
|
||||
<p className="market-value">4.5/5</p>
|
||||
<p className="market-change positive">Sektör ort: 3.7</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="chart-container">
|
||||
<h3>Pazar Payı Dağılımı</h3>
|
||||
<div className="placeholder-chart">
|
||||
{/* Buraya gerçek bir pie chart component'i eklenebilir */}
|
||||
<p>Pasta grafik alanı</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="table-container">
|
||||
<h3>Rakip Analizi</h3>
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Rakip Adı</th>
|
||||
<th>Pazar Payı</th>
|
||||
<th>Büyüme</th>
|
||||
<th>Puan</th>
|
||||
<th>Karşılaştırma</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{competitors.map(competitor => (
|
||||
<tr key={competitor.id}>
|
||||
<td>{competitor.name}</td>
|
||||
<td>{competitor.marketShare}</td>
|
||||
<td className={competitor.growth.startsWith('+') ? 'positive' : 'negative'}>
|
||||
{competitor.growth}
|
||||
</td>
|
||||
<td>
|
||||
<div className="rating-stars">
|
||||
{'★'.repeat(Math.floor(competitor.rating))}
|
||||
{'☆'.repeat(5 - Math.floor(competitor.rating))}
|
||||
<span className="rating-value">({competitor.rating})</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button className="action-btn compare">Karşılaştır</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="market-insights">
|
||||
<h3>Pazar Öngörüleri</h3>
|
||||
<div className="insight-card">
|
||||
<p>Son 3 ayda müşteri taleplerinde %15 artış gözlemlendi.</p>
|
||||
</div>
|
||||
<div className="insight-card">
|
||||
<p>Rakip firmaların fiyat indirimine gitmesi pazar payımızı etkileyebilir.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MarketAnalysisPage;
|
|
@ -0,0 +1,101 @@
|
|||
import React from 'react';
|
||||
import './DashboardStyles.css';
|
||||
|
||||
const SupportPage = () => {
|
||||
const tickets = [
|
||||
{ id: 1, subject: 'Üyelik sorunu', customer: 'Ahmet Yılmaz', date: '15.04.2023', status: 'Açık', priority: 'Yüksek' },
|
||||
{ id: 2, subject: 'Ödeme problemi', customer: 'Ayşe Kaya', date: '14.04.2023', status: 'Cevaplandı', priority: 'Orta' },
|
||||
{ id: 3, subject: 'Ürün iade', customer: 'Mehmet Demir', date: '13.04.2023', status: 'Çözüldü', priority: 'Düşük' },
|
||||
{ id: 4, subject: 'Teknik destek', customer: 'Zeynep Şahin', date: '12.04.2023', status: 'Açık', priority: 'Yüksek' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="dashboard-page">
|
||||
<h2 className="page-title">Müşteri Destek Yönetimi</h2>
|
||||
|
||||
<div className="support-stats">
|
||||
<div className="stat-card">
|
||||
<h3>Açık Destek Talepleri</h3>
|
||||
<p className="stat-value">5</p>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<h3>Bugünkü Talepler</h3>
|
||||
<p className="stat-value">3</p>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<h3>Ortalama Yanıt Süresi</h3>
|
||||
<p className="stat-value">4.2 saat</p>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<h3>Çözüm Oranı</h3>
|
||||
<p className="stat-value">92%</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="table-container">
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Talep No</th>
|
||||
<th>Konu</th>
|
||||
<th>Müşteri</th>
|
||||
<th>Tarih</th>
|
||||
<th>Durum</th>
|
||||
<th>Öncelik</th>
|
||||
<th>İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{tickets.map(ticket => (
|
||||
<tr key={ticket.id}>
|
||||
<td>#{ticket.id}</td>
|
||||
<td>{ticket.subject}</td>
|
||||
<td>{ticket.customer}</td>
|
||||
<td>{ticket.date}</td>
|
||||
<td>
|
||||
<span className={`status-badge ${ticket.status.toLowerCase()}`}>
|
||||
{ticket.status}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span className={`priority-badge ${ticket.priority.toLowerCase()}`}>
|
||||
{ticket.priority}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button className="action-btn view">Görüntüle</button>
|
||||
<button className="action-btn assign">Ata</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="support-actions">
|
||||
<button className="new-ticket-btn">Yeni Talep Oluştur</button>
|
||||
<button className="knowledge-base-btn">Bilgi Bankası</button>
|
||||
</div>
|
||||
|
||||
<div className="recent-activity">
|
||||
<h3>Son Aktivite</h3>
|
||||
<ul className="activity-list">
|
||||
<li>
|
||||
<span className="activity-time">10:30</span>
|
||||
<span className="activity-text">Ahmet Yılmaz'ın talebi cevaplandı</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="activity-time">09:45</span>
|
||||
<span className="activity-text">Yeni destek talebi oluşturuldu (#1245)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="activity-time">Dün 17:20</span>
|
||||
<span className="activity-text">3 talep çözüldü</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SupportPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const LicenseUpdatesPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Lisans Güncellemeleri</h2>
|
||||
<p>Müşteri lisans güncellemeleri bilgileri.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LicenseUpdatesPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const PaymentinvoiceTrackingPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Ödeme & Fatura Takibi</h2>
|
||||
<p>Ödeme ve fatura takibi bilgileri.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PaymentinvoiceTrackingPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const PromotionsSuggestionsPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Kampanya ve Öneriler</h2>
|
||||
<p>Kampanya öneri detayları burada.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PromotionsSuggestionsPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const PromotionsSuggestionsPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Kampanya ve Öneriler</h2>
|
||||
<p>Kampanya öneri detayları burada.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PromotionsSuggestionsPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const SoftwarePurchasePage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Yazılım Satın Alma</h2>
|
||||
<p>Yazılım satın alma süreci ve bilgileri.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SoftwarePurchasePage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const SupportFeedbackPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Destek & Geri Bildirim</h2>
|
||||
<p>Müşteri geri bildirimleri buraya gelecek.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SupportFeedbackPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const LicenseDistributionPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Lisans Dağıtımı</h2>
|
||||
<p>Lisans dağıtım işlemleri detayları.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LicenseDistributionPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const OrderManagementPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Sipariş Yönetimi</h2>
|
||||
<p>Sipariş yönetimi ile ilgili içerikler.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default OrderManagementPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const PaymentBillingPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Ödeme & Fatura</h2>
|
||||
<p>Ödeme ve fatura işlemleri bilgileri.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PaymentBillingPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const RetailerFeedbackPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Perakende Geri Bildirim</h2>
|
||||
<p>Perakende ile gelen geri bildirimler.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default RetailerFeedbackPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const SalesPerformancePage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Satış Performansı</h2>
|
||||
<p>Satış performans analizleri burada.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SalesPerformancePage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const SalesReportsPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Satış Raporları</h2>
|
||||
<p>Satış raporlarına ait detaylar.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SalesReportsPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const StockCampaignManagementPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Stok & Kampanya Yönetimi</h2>
|
||||
<p>Stok ve kampanya yönetimi bilgileri.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default StockCampaignManagementPage;
|
|
@ -0,0 +1,49 @@
|
|||
import React from 'react';
|
||||
|
||||
const LoginPage = ({ onLogin }) => {
|
||||
const handleLogin = (role) => {
|
||||
const users = {
|
||||
admin: { name: 'Admin User', role: 'admin' },
|
||||
distributor: { name: 'Distributor User', role: 'distributor' },
|
||||
retailer: { name: 'Retailer User', role: 'retailer' },
|
||||
customer: { name: 'Customer User', role: 'customer' },
|
||||
};
|
||||
onLogin(users[role]);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gray-100">
|
||||
<div className="bg-white p-8 rounded-lg shadow-md w-96">
|
||||
<h1 className="text-2xl font-bold text-center mb-6">Software License Dashboard</h1>
|
||||
<div className="space-y-4">
|
||||
<button
|
||||
onClick={() => handleLogin('admin')}
|
||||
className="w-full py-2 px-4 bg-blue-500 text-white rounded hover:bg-blue-600 transition"
|
||||
>
|
||||
Login as Admin
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleLogin('distributor')}
|
||||
className="w-full py-2 px-4 bg-green-500 text-white rounded hover:bg-green-600 transition"
|
||||
>
|
||||
Login as Distributor
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleLogin('retailer')}
|
||||
className="w-full py-2 px-4 bg-purple-500 text-white rounded hover:bg-purple-600 transition"
|
||||
>
|
||||
Login as Retailer
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleLogin('customer')}
|
||||
className="w-full py-2 px-4 bg-orange-500 text-white rounded hover:bg-orange-600 transition"
|
||||
>
|
||||
Login as Customer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const CampaignManagementPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Kampanya Yönetimi</h2>
|
||||
<p>Perakende kampanya yönetimi içerikleri.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CampaignManagementPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const CustomerFeedbackPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Müşteri Geri Bildirimi</h2>
|
||||
<p>Perakende müşteri geri bildirimleri burada.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomerFeedbackPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const CustomerSalesPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Müşteri Satışları</h2>
|
||||
<p>Müşteri satış detayları burada.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomerSalesPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const DistributorOrderManagementPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Distribütör Sipariş Yönetimi</h2>
|
||||
<p>Distributor sipariş yönetim bilgileri.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DistributorOrderManagementPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const LicenseDistributionPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Lisans Dağıtımı</h2>
|
||||
<p>Perakende lisans dağıtım işlemleri.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LicenseDistributionPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const PaymentCollectionPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Ödeme Tahsilatı</h2>
|
||||
<p>Ödeme tahsilatı süreçleri burada.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PaymentCollectionPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const SalesReportsPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Satış Raporları</h2>
|
||||
<p>Perakende satış raporları bilgileri.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SalesReportsPage;
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const SalesSupportRequestsPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Satış Destek Talepleri</h2>
|
||||
<p>Satış destek talepleri ile ilgili içerikler.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SalesSupportRequestsPage;
|
|
@ -0,0 +1,24 @@
|
|||
import React from 'react';
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
import GeneralSalesPage from '../pages/Admin/GeneralSalesPage';
|
||||
import MarketAnalysisPage from '../pages/Admin/MarketAnalysisPage';
|
||||
import LicenseManagementPage from '../pages/Admin/LicenseManagementPage';
|
||||
import FinancePage from '../pages/Admin/FinancePage';
|
||||
import CampaignsPage from '../pages/Admin/CampaignsPage';
|
||||
import SupportPage from '../pages/Admin/SupportPage';
|
||||
|
||||
const AdminRoutes = () => {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/" element={<GeneralSalesPage />} />
|
||||
<Route path="/general-sales" element={<GeneralSalesPage />} />
|
||||
<Route path="/market-analysis" element={<MarketAnalysisPage />} />
|
||||
<Route path="/license-management" element={<LicenseManagementPage />} />
|
||||
<Route path="/finance" element={<FinancePage />} />
|
||||
<Route path="/campaigns" element={<CampaignsPage />} />
|
||||
<Route path="/support" element={<SupportPage />} />
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
export default AdminRoutes;
|
|
@ -0,0 +1,24 @@
|
|||
import React from 'react';
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
import PurchasedSoftwarePage from '../pages/Customer/PurchasedSoftwarePage';
|
||||
import SoftwarePurchasePage from '../pages/Customer/SoftwarePurchasePage';
|
||||
import PaymentInvoiceTrackingPage from '../pages/Customer/PaymentInvoiceTrackingPage';
|
||||
import LicenseUpdatesPage from '../pages/Customer/LicenseUpdatesPage';
|
||||
import PromotionsSuggestionsPage from '../pages/Customer/PromotionsSuggestionsPage';
|
||||
import SupportFeedbackPage from '../pages/Customer/SupportFeedbackPage';
|
||||
|
||||
const CustomerRoutes = () => {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/" element={<PurchasedSoftwarePage />} />
|
||||
<Route path="/purchased-software" element={<PurchasedSoftwarePage />} />
|
||||
<Route path="/software-purchase" element={<SoftwarePurchasePage />} />
|
||||
<Route path="/payment-invoices" element={<PaymentInvoiceTrackingPage />} />
|
||||
<Route path="/license-updates" element={<LicenseUpdatesPage />} />
|
||||
<Route path="/promotions" element={<PromotionsSuggestionsPage />} />
|
||||
<Route path="/support-feedback" element={<SupportFeedbackPage />} />
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomerRoutes;
|
|
@ -0,0 +1,26 @@
|
|||
import React from 'react';
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
import SalesPerformancePage from '../pages/Distributor/SalesPerformancePage';
|
||||
import OrderManagementPage from '../pages/Distributor/OrderManagementPage';
|
||||
import LicenseDistributionPage from '../pages/Distributor/LicenseDistributionPage';
|
||||
import StockCampaignManagementPage from '../pages/Distributor/StockCampaignManagementPage';
|
||||
import PaymentBillingPage from '../pages/Distributor/PaymentBillingPage';
|
||||
import RetailerFeedbackPage from '../pages/Distributor/RetailerFeedbackPage';
|
||||
import SalesReportsPage from '../pages/Distributor/SalesReportsPage';
|
||||
|
||||
const DistributorRoutes = () => {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/" element={<SalesPerformancePage />} />
|
||||
<Route path="/sales-performance" element={<SalesPerformancePage />} />
|
||||
<Route path="/order-management" element={<OrderManagementPage />} />
|
||||
<Route path="/license-distribution" element={<LicenseDistributionPage />} />
|
||||
<Route path="/stock-management" element={<StockCampaignManagementPage />} />
|
||||
<Route path="/payment-billing" element={<PaymentBillingPage />} />
|
||||
<Route path="/retailer-feedback" element={<RetailerFeedbackPage />} />
|
||||
<Route path="/sales-reports" element={<SalesReportsPage />} />
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
export default DistributorRoutes;
|
|
@ -0,0 +1,28 @@
|
|||
import React from 'react';
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
import DistributorOrderManagementPage from '../pages/Retailer/DistributorOrderManagementPage';
|
||||
import CustomerSalesPage from '../pages/Retailer/CustomerSalesPage';
|
||||
import LicenseDistributionPage from '../pages/Retailer/LicenseDistributionPage';
|
||||
import CampaignManagementPage from '../pages/Retailer/CampaignManagementPage';
|
||||
import SalesReportsPage from '../pages/Retailer/SalesReportsPage';
|
||||
import PaymentCollectionPage from '../pages/Retailer/PaymentCollectionPage';
|
||||
import CustomerFeedbackPage from '../pages/Retailer/CustomerFeedbackPage';
|
||||
import SalesSupportRequestsPage from '../pages/Retailer/SalesSupportRequestsPage';
|
||||
|
||||
const RetailerRoutes = () => {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/" element={<DistributorOrderManagementPage />} />
|
||||
<Route path="/distributor-orders" element={<DistributorOrderManagementPage />} />
|
||||
<Route path="/customer-sales" element={<CustomerSalesPage />} />
|
||||
<Route path="/license-distribution" element={<LicenseDistributionPage />} />
|
||||
<Route path="/campaign-management" element={<CampaignManagementPage />} />
|
||||
<Route path="/sales-reports" element={<SalesReportsPage />} />
|
||||
<Route path="/payment-collection" element={<PaymentCollectionPage />} />
|
||||
<Route path="/customer-feedback" element={<CustomerFeedbackPage />} />
|
||||
<Route path="/support-requests" element={<SalesSupportRequestsPage />} />
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
export default RetailerRoutes;
|
Loading…
Reference in New Issue