Initial commit
This commit is contained in:
parent
e2843615d8
commit
5ed5fde98d
|
@ -16,7 +16,10 @@
|
|||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"axios": "^1.8.4",
|
||||
"chart.js": "^4.4.8",
|
||||
"react": "^19.1.0",
|
||||
"react-chartjs-2": "^5.3.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-icons": "^5.5.0",
|
||||
"react-router-dom": "^7.5.0",
|
||||
|
@ -3026,6 +3029,12 @@
|
|||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@kurkle/color": {
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz",
|
||||
"integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@leichtgewicht/ip-codec": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz",
|
||||
|
@ -4969,6 +4978,32 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.8.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz",
|
||||
"integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/axios/node_modules/form-data": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
|
||||
"integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/axobject-query": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
|
||||
|
@ -5603,6 +5638,18 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/chart.js": {
|
||||
"version": "4.4.8",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.8.tgz",
|
||||
"integrity": "sha512-IkGZlVpXP+83QpMm4uxEiGqSI7jFizwVtF3+n5Pc3k7sMO+tkd0qxh2OzLhenM0K80xtmAONWGBn082EiBQSDA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@kurkle/color": "^0.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"pnpm": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/check-types": {
|
||||
"version": "11.2.3",
|
||||
"resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz",
|
||||
|
@ -13701,6 +13748,12 @@
|
|||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/psl": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
|
||||
|
@ -13860,6 +13913,16 @@
|
|||
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-chartjs-2": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.3.0.tgz",
|
||||
"integrity": "sha512-UfZZFnDsERI3c3CZGxzvNJd02SHjaSJ8kgW1djn65H1KK8rehwTjyrRKOG3VTMG8wtHZ5rgAO5oTHtHi9GCCmw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"chart.js": "^4.1.1",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dev-utils": {
|
||||
"version": "12.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
"@testing-library/user-event": "^13.5.0",
|
||||
"axios": "^1.8.4",
|
||||
"react": "^19.1.0",
|
||||
"react-chartjs-2": "^5.3.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-icons": "^5.5.0",
|
||||
"react-router-dom": "^7.5.0",
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
|
@ -15,7 +15,7 @@ import {
|
|||
faQuestionCircle
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import './navbar.css';
|
||||
import logo from '../assets/logo.png';
|
||||
import logo from '../assets/logo2.png';
|
||||
|
||||
const Navbar = ({
|
||||
user,
|
||||
|
@ -93,7 +93,7 @@ const Navbar = ({
|
|||
<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>
|
||||
<span className="navbar-brand">Software License Dashboard </span>
|
||||
</div>
|
||||
|
||||
<form className="search-bar" onSubmit={handleSearch}>
|
||||
|
|
|
@ -1,10 +1,109 @@
|
|||
import React from 'react';
|
||||
import './dashboard.css';
|
||||
|
||||
const LicenseDistributionPage = () => {
|
||||
// Sample data
|
||||
const licenseStats = [
|
||||
{ label: 'Active Licenses', value: '1,245', change: '+5%' },
|
||||
{ label: 'Expired Licenses', value: '89', change: '-2%' },
|
||||
{ label: 'Pending Activations', value: '32', change: '+12%' },
|
||||
{ label: 'Total Revenue', value: '$48,750', change: '+8%' },
|
||||
];
|
||||
|
||||
const recentDistributions = [
|
||||
{ id: 'LIC-1001', product: 'Business Suite', distributor: 'TechDistro', date: '2023-05-15', status: 'Active' },
|
||||
{ id: 'LIC-1002', product: 'Security Pro', distributor: 'SoftLink', date: '2023-05-14', status: 'Pending' },
|
||||
{ id: 'LIC-1003', product: 'Design Master', distributor: 'DigitalOne', date: '2023-05-12', status: 'Active' },
|
||||
{ id: 'LIC-1004', product: 'Business Suite', distributor: 'TechDistro', date: '2023-05-10', status: 'Expired' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Lisans Dağıtımı</h2>
|
||||
<p>Lisans dağıtım işlemleri detayları.</p>
|
||||
<div className="dashboard-container">
|
||||
<h2 className="dashboard-header">License Distribution Management</h2>
|
||||
|
||||
<div className="stats-grid">
|
||||
{licenseStats.map((stat, index) => (
|
||||
<div key={index} className="stat-card">
|
||||
<div className="stat-value">{stat.value}</div>
|
||||
<div className="stat-label">{stat.label}</div>
|
||||
<small style={{ color: stat.change.startsWith('+') ? '#27ae60' : '#e74c3c' }}>
|
||||
{stat.change} from last month
|
||||
</small>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="dashboard-card">
|
||||
<h3 className="card-title">Recent License Distributions</h3>
|
||||
<div className="search-filter">
|
||||
<input type="text" className="search-box" placeholder="Search licenses..." />
|
||||
<select className="filter-select">
|
||||
<option>All Status</option>
|
||||
<option>Active</option>
|
||||
<option>Pending</option>
|
||||
<option>Expired</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="table-container">
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>License ID</th>
|
||||
<th>Product</th>
|
||||
<th>Distributor</th>
|
||||
<th>Date</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{recentDistributions.map((license, index) => (
|
||||
<tr key={index}>
|
||||
<td>{license.id}</td>
|
||||
<td>{license.product}</td>
|
||||
<td>{license.distributor}</td>
|
||||
<td>{license.date}</td>
|
||||
<td>
|
||||
<span style={{
|
||||
padding: '4px 8px',
|
||||
borderRadius: '12px',
|
||||
backgroundColor:
|
||||
license.status === 'Active' ? '#d5f5e3' :
|
||||
license.status === 'Pending' ? '#fef9e7' : '#fadbd8',
|
||||
color:
|
||||
license.status === 'Active' ? '#27ae60' :
|
||||
license.status === 'Pending' ? '#f39c12' : '#e74c3c'
|
||||
}}>
|
||||
{license.status}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button className="action-btn">View</button>
|
||||
<button className="action-btn secondary">Edit</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="dashboard-card">
|
||||
<h3 className="card-title">License Distribution Analytics</h3>
|
||||
<div className="chart-container">
|
||||
{/* This would be replaced with an actual chart component */}
|
||||
<div style={{
|
||||
background: '#f8f9fa',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: '#7f8c8d'
|
||||
}}>
|
||||
[License Distribution Chart - Monthly Trends]
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,10 +1,168 @@
|
|||
import React from 'react';
|
||||
|
||||
import './dashboard.css';
|
||||
const OrderManagementPage = () => {
|
||||
const orderStats = [
|
||||
{ label: 'Total Orders', value: '328', change: '+15%' },
|
||||
{ label: 'Pending Orders', value: '24', change: '-3%' },
|
||||
{ label: 'Completed Orders', value: '289', change: '+18%' },
|
||||
{ label: 'Avg. Processing Time', value: '2.4 days', change: '-0.5' },
|
||||
];
|
||||
|
||||
const recentOrders = [
|
||||
{ id: 'ORD-2023-1056', customer: 'ABC Corp', product: 'Business Suite', amount: '$1,200', date: '2023-05-15', status: 'Processing' },
|
||||
{ id: 'ORD-2023-1055', customer: 'XYZ Ltd', product: 'Security Pro', amount: '$850', date: '2023-05-14', status: 'Shipped' },
|
||||
{ id: 'ORD-2023-1054', customer: 'Acme Inc', product: 'Design Master', amount: '$650', date: '2023-05-13', status: 'Completed' },
|
||||
{ id: 'ORD-2023-1053', customer: 'Global Tech', product: 'Business Suite', amount: '$2,400', date: '2023-05-12', status: 'Completed' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Sipariş Yönetimi</h2>
|
||||
<p>Sipariş yönetimi ile ilgili içerikler.</p>
|
||||
<div className="dashboard-container">
|
||||
<h2 className="dashboard-header">Order Management System</h2>
|
||||
|
||||
<div className="stats-grid">
|
||||
{orderStats.map((stat, index) => (
|
||||
<div key={index} className="stat-card">
|
||||
<div className="stat-value">{stat.value}</div>
|
||||
<div className="stat-label">{stat.label}</div>
|
||||
<small style={{ color: stat.change.startsWith('+') ? '#27ae60' : stat.change.startsWith('-') ? '#e74c3c' : '#3498db' }}>
|
||||
{stat.change.startsWith('-') ? stat.change : `+${stat.change}`} from last month
|
||||
</small>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="dashboard-card">
|
||||
<h3 className="card-title">Recent Orders</h3>
|
||||
<div className="search-filter">
|
||||
<input type="text" className="search-box" placeholder="Search orders..." />
|
||||
<select className="filter-select">
|
||||
<option>All Status</option>
|
||||
<option>Processing</option>
|
||||
<option>Shipped</option>
|
||||
<option>Completed</option>
|
||||
<option>Cancelled</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="table-container">
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Order ID</th>
|
||||
<th>Customer</th>
|
||||
<th>Product</th>
|
||||
<th>Amount</th>
|
||||
<th>Date</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{recentOrders.map((order, index) => (
|
||||
<tr key={index}>
|
||||
<td>{order.id}</td>
|
||||
<td>{order.customer}</td>
|
||||
<td>{order.product}</td>
|
||||
<td>{order.amount}</td>
|
||||
<td>{order.date}</td>
|
||||
<td>
|
||||
<span style={{
|
||||
padding: '4px 8px',
|
||||
borderRadius: '12px',
|
||||
backgroundColor:
|
||||
order.status === 'Completed' ? '#d5f5e3' :
|
||||
order.status === 'Processing' ? '#fef9e7' :
|
||||
order.status === 'Shipped' ? '#d6eaf8' : '#fadbd8',
|
||||
color:
|
||||
order.status === 'Completed' ? '#27ae60' :
|
||||
order.status === 'Processing' ? '#f39c12' :
|
||||
order.status === 'Shipped' ? '#3498db' : '#e74c3c'
|
||||
}}>
|
||||
{order.status}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button className="action-btn">Details</button>
|
||||
<button className="action-btn secondary">Track</button>
|
||||
{order.status === 'Processing' && (
|
||||
<button className="action-btn danger">Cancel</button>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="dashboard-card">
|
||||
<h3 className="card-title">Order Fulfillment Workflow</h3>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', marginTop: '20px' }}>
|
||||
<div style={{ textAlign: 'center', flex: 1 }}>
|
||||
<div style={{
|
||||
width: '60px',
|
||||
height: '60px',
|
||||
borderRadius: '50%',
|
||||
backgroundColor: '#3498db',
|
||||
color: 'white',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
margin: '0 auto 10px',
|
||||
fontSize: '24px'
|
||||
}}>1</div>
|
||||
<h4>Order Received</h4>
|
||||
<p style={{ color: '#7f8c8d' }}>Customer places order</p>
|
||||
</div>
|
||||
<div style={{ textAlign: 'center', flex: 1 }}>
|
||||
<div style={{
|
||||
width: '60px',
|
||||
height: '60px',
|
||||
borderRadius: '50%',
|
||||
backgroundColor: '#3498db',
|
||||
color: 'white',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
margin: '0 auto 10px',
|
||||
fontSize: '24px'
|
||||
}}>2</div>
|
||||
<h4>Processing</h4>
|
||||
<p style={{ color: '#7f8c8d' }}>Verification & preparation</p>
|
||||
</div>
|
||||
<div style={{ textAlign: 'center', flex: 1 }}>
|
||||
<div style={{
|
||||
width: '60px',
|
||||
height: '60px',
|
||||
borderRadius: '50%',
|
||||
backgroundColor: '#3498db',
|
||||
color: 'white',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
margin: '0 auto 10px',
|
||||
fontSize: '24px'
|
||||
}}>3</div>
|
||||
<h4>License Generation</h4>
|
||||
<p style={{ color: '#7f8c8d' }}>Create & validate license</p>
|
||||
</div>
|
||||
<div style={{ textAlign: 'center', flex: 1 }}>
|
||||
<div style={{
|
||||
width: '60px',
|
||||
height: '60px',
|
||||
borderRadius: '50%',
|
||||
backgroundColor: '#3498db',
|
||||
color: 'white',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
margin: '0 auto 10px',
|
||||
fontSize: '24px'
|
||||
}}>4</div>
|
||||
<h4>Delivery</h4>
|
||||
<p style={{ color: '#7f8c8d' }}>Send to customer</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,10 +1,162 @@
|
|||
import React from 'react';
|
||||
|
||||
import './dashboard.css';
|
||||
const PaymentBillingPage = () => {
|
||||
const paymentStats = [
|
||||
{ label: 'Total Revenue', value: '$86,450', change: '+12%' },
|
||||
{ label: 'Pending Payments', value: '$5,720', change: '-3%' },
|
||||
{ label: 'Avg. Payment Time', value: '2.1 days', change: '-0.3' },
|
||||
{ label: 'Successful Transactions', value: '94.7%', change: '+1.2%' },
|
||||
];
|
||||
|
||||
const recentTransactions = [
|
||||
{ id: 'TXN-58741', invoice: 'INV-2023-1056', amount: '$1,200', date: '2023-05-15', method: 'Credit Card', status: 'Completed' },
|
||||
{ id: 'TXN-58740', invoice: 'INV-2023-1055', amount: '$850', date: '2023-05-14', method: 'PayPal', status: 'Completed' },
|
||||
{ id: 'TXN-58739', invoice: 'INV-2023-1054', amount: '$650', date: '2023-05-13', method: 'Bank Transfer', status: 'Pending' },
|
||||
{ id: 'TXN-58738', invoice: 'INV-2023-1053', amount: '$2,400', date: '2023-05-12', method: 'Credit Card', status: 'Failed' },
|
||||
];
|
||||
|
||||
const upcomingInvoices = [
|
||||
{ invoice: 'INV-2023-1057', client: 'ABC Corp', amount: '$1,500', dueDate: '2023-05-20', status: 'Unpaid' },
|
||||
{ invoice: 'INV-2023-1058', client: 'XYZ Ltd', amount: '$950', dueDate: '2023-05-21', status: 'Unpaid' },
|
||||
{ invoice: 'INV-2023-1059', client: 'Acme Inc', amount: '$2,100', dueDate: '2023-05-22', status: 'Unpaid' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Ödeme & Fatura</h2>
|
||||
<p>Ödeme ve fatura işlemleri bilgileri.</p>
|
||||
<div className="dashboard-container">
|
||||
<h2 className="dashboard-header">Payment & Billing Management</h2>
|
||||
|
||||
<div className="stats-grid">
|
||||
{paymentStats.map((stat, index) => (
|
||||
<div key={index} className="stat-card">
|
||||
<div className="stat-value">{stat.value}</div>
|
||||
<div className="stat-label">{stat.label}</div>
|
||||
<small style={{ color: stat.change.startsWith('+') ? '#27ae60' : stat.change.startsWith('-') ? '#e74c3c' : '#3498db' }}>
|
||||
{stat.change.startsWith('-') ? stat.change : `+${stat.change}`} from last month
|
||||
</small>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="dashboard-card">
|
||||
<h3 className="card-title">Recent Transactions</h3>
|
||||
<div className="search-filter">
|
||||
<input type="text" className="search-box" placeholder="Search transactions..." />
|
||||
<select className="filter-select">
|
||||
<option>All Status</option>
|
||||
<option>Completed</option>
|
||||
<option>Pending</option>
|
||||
<option>Failed</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="table-container">
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Transaction ID</th>
|
||||
<th>Invoice</th>
|
||||
<th>Amount</th>
|
||||
<th>Date</th>
|
||||
<th>Method</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{recentTransactions.map((txn, index) => (
|
||||
<tr key={index}>
|
||||
<td>{txn.id}</td>
|
||||
<td>{txn.invoice}</td>
|
||||
<td>{txn.amount}</td>
|
||||
<td>{txn.date}</td>
|
||||
<td>{txn.method}</td>
|
||||
<td>
|
||||
<span style={{
|
||||
padding: '4px 8px',
|
||||
borderRadius: '12px',
|
||||
backgroundColor:
|
||||
txn.status === 'Completed' ? '#d5f5e3' :
|
||||
txn.status === 'Pending' ? '#fef9e7' : '#fadbd8',
|
||||
color:
|
||||
txn.status === 'Completed' ? '#27ae60' :
|
||||
txn.status === 'Pending' ? '#f39c12' : '#e74c3c'
|
||||
}}>
|
||||
{txn.status}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button className="action-btn">Details</button>
|
||||
{txn.status === 'Pending' && (
|
||||
<button className="action-btn secondary">Remind</button>
|
||||
)}
|
||||
{txn.status === 'Failed' && (
|
||||
<button className="action-btn danger">Retry</button>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="dashboard-card">
|
||||
<h3 className="card-title">Upcoming Invoices</h3>
|
||||
<div className="table-container">
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Invoice</th>
|
||||
<th>Client</th>
|
||||
<th>Amount</th>
|
||||
<th>Due Date</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{upcomingInvoices.map((invoice, index) => (
|
||||
<tr key={index}>
|
||||
<td>{invoice.invoice}</td>
|
||||
<td>{invoice.client}</td>
|
||||
<td>{invoice.amount}</td>
|
||||
<td>{invoice.dueDate}</td>
|
||||
<td>
|
||||
<span style={{
|
||||
padding: '4px 8px',
|
||||
borderRadius: '12px',
|
||||
backgroundColor: '#fef9e7',
|
||||
color: '#f39c12'
|
||||
}}>
|
||||
{invoice.status}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button className="action-btn">View</button>
|
||||
<button className="action-btn secondary">Send Reminder</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="dashboard-card">
|
||||
<h3 className="card-title">Revenue Analytics</h3>
|
||||
<div className="chart-container">
|
||||
{/* This would be replaced with an actual chart component */}
|
||||
<div style={{
|
||||
background: '#f8f9fa',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: '#7f8c8d'
|
||||
}}>
|
||||
[Revenue Chart - Monthly Trends by Payment Method]
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,10 +1,186 @@
|
|||
import React from 'react';
|
||||
|
||||
import './dashboard.css';
|
||||
const RetailerFeedbackPage = () => {
|
||||
const feedbackStats = [
|
||||
{ label: 'Total Feedback', value: '142', change: '+8%' },
|
||||
{ label: 'Average Rating', value: '4.2/5', change: '+0.1' },
|
||||
{ label: 'Positive Feedback', value: '87%', change: '+3%' },
|
||||
{ label: 'Response Rate', value: '92%', change: '+2%' },
|
||||
];
|
||||
|
||||
const recentFeedback = [
|
||||
{ id: 'FB-1056', retailer: 'Tech Haven', rating: 5, comment: 'Excellent service and fast response times!', date: '2023-05-15', status: 'Responded' },
|
||||
{ id: 'FB-1055', retailer: 'Digital World', rating: 4, comment: 'Good products but delivery could be faster', date: '2023-05-14', status: 'Pending' },
|
||||
{ id: 'FB-1054', retailer: 'Software Plus', rating: 3, comment: 'Had some issues with license activation', date: '2023-05-13', status: 'In Progress' },
|
||||
{ id: 'FB-1053', retailer: 'CompuZone', rating: 5, comment: 'Best software distributor we work with', date: '2023-05-12', status: 'Responded' },
|
||||
];
|
||||
|
||||
const ratingDistribution = [
|
||||
{ stars: 5, count: 85, percent: 60 },
|
||||
{ stars: 4, count: 32, percent: 22 },
|
||||
{ stars: 3, count: 15, percent: 10 },
|
||||
{ stars: 2, count: 6, percent: 4 },
|
||||
{ stars: 1, count: 4, percent: 3 },
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Perakende Geri Bildirim</h2>
|
||||
<p>Perakende ile gelen geri bildirimler.</p>
|
||||
<div className="dashboard-container">
|
||||
<h2 className="dashboard-header">Retailer Feedback Management</h2>
|
||||
|
||||
<div className="stats-grid">
|
||||
{feedbackStats.map((stat, index) => (
|
||||
<div key={index} className="stat-card">
|
||||
<div className="stat-value">{stat.value}</div>
|
||||
<div className="stat-label">{stat.label}</div>
|
||||
<small style={{ color: stat.change.startsWith('+') ? '#27ae60' : '#e74c3c' }}>
|
||||
{stat.change} from last month
|
||||
</small>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="dashboard-card">
|
||||
<h3 className="card-title">Recent Feedback</h3>
|
||||
<div className="search-filter">
|
||||
<input type="text" className="search-box" placeholder="Search feedback..." />
|
||||
<select className="filter-select">
|
||||
<option>All Status</option>
|
||||
<option>Responded</option>
|
||||
<option>Pending</option>
|
||||
<option>In Progress</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="table-container">
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Feedback ID</th>
|
||||
<th>Retailer</th>
|
||||
<th>Rating</th>
|
||||
<th>Comment</th>
|
||||
<th>Date</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{recentFeedback.map((feedback, index) => (
|
||||
<tr key={index}>
|
||||
<td>{feedback.id}</td>
|
||||
<td>{feedback.retailer}</td>
|
||||
<td>
|
||||
<div style={{ display: 'flex' }}>
|
||||
{[...Array(5)].map((_, i) => (
|
||||
<span key={i} style={{
|
||||
color: i < feedback.rating ? '#f39c12' : '#ddd',
|
||||
fontSize: '18px'
|
||||
}}>★</span>
|
||||
))}
|
||||
</div>
|
||||
</td>
|
||||
<td style={{ maxWidth: '300px' }}>{feedback.comment}</td>
|
||||
<td>{feedback.date}</td>
|
||||
<td>
|
||||
<span style={{
|
||||
padding: '4px 8px',
|
||||
borderRadius: '12px',
|
||||
backgroundColor:
|
||||
feedback.status === 'Responded' ? '#d5f5e3' :
|
||||
feedback.status === 'Pending' ? '#fadbd8' : '#fef9e7',
|
||||
color:
|
||||
feedback.status === 'Responded' ? '#27ae60' :
|
||||
feedback.status === 'Pending' ? '#e74c3c' : '#f39c12'
|
||||
}}>
|
||||
{feedback.status}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button className="action-btn">View</button>
|
||||
{feedback.status !== 'Responded' && (
|
||||
<button className="action-btn secondary">Respond</button>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '20px' }}>
|
||||
<div className="dashboard-card">
|
||||
<h3 className="card-title">Rating Distribution</h3>
|
||||
<div style={{ marginTop: '20px' }}>
|
||||
{ratingDistribution.map((item, index) => (
|
||||
<div key={index} style={{ marginBottom: '10px' }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '5px' }}>
|
||||
<span>
|
||||
{[...Array(item.stars)].map((_, i) => (
|
||||
<span key={i} style={{ color: '#f39c12' }}>★</span>
|
||||
))}
|
||||
</span>
|
||||
<span>{item.count} ({item.percent}%)</span>
|
||||
</div>
|
||||
<div style={{
|
||||
height: '10px',
|
||||
backgroundColor: '#ecf0f1',
|
||||
borderRadius: '5px',
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
<div style={{
|
||||
width: `${item.percent}%`,
|
||||
height: '100%',
|
||||
backgroundColor: '#f39c12',
|
||||
borderRadius: '5px'
|
||||
}}></div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="dashboard-card">
|
||||
<h3 className="card-title">Feedback Response</h3>
|
||||
<div style={{
|
||||
height: '250px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}>
|
||||
{/* This would be replaced with an actual chart component */}
|
||||
<div style={{
|
||||
background: '#f8f9fa',
|
||||
width: '100%',
|
||||
height: '200px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: '#7f8c8d'
|
||||
}}>
|
||||
[Response Time and Satisfaction Chart]
|
||||
</div>
|
||||
</div>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-around',
|
||||
marginTop: '20px',
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
<div>
|
||||
<div style={{ fontSize: '24px', fontWeight: 'bold', color: '#27ae60' }}>92%</div>
|
||||
<div style={{ color: '#7f8c8d' }}>Response Rate</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontSize: '24px', fontWeight: 'bold', color: '#3498db' }}>6.2h</div>
|
||||
<div style={{ color: '#7f8c8d' }}>Avg. Response Time</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontSize: '24px', fontWeight: 'bold', color: '#f39c12' }}>87%</div>
|
||||
<div style={{ color: '#7f8c8d' }}>Satisfaction After Response</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,10 +1,82 @@
|
|||
// SalesPerformancePage.jsx
|
||||
import React from 'react';
|
||||
import { Line } from 'react-chartjs-2';
|
||||
import { Chart as ChartJS } from 'chart.js/auto';
|
||||
|
||||
const SalesPerformancePage = () => {
|
||||
const salesData = {
|
||||
labels: ['Ocak', 'Şubat', 'Mart', 'Nisan', 'Mayıs', 'Haziran'],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Aylık Satışlar (TL)',
|
||||
data: [65000, 59000, 80000, 81000, 56000, 95000],
|
||||
borderColor: '#4A90E2',
|
||||
tension: 0.4,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const regionalSales = {
|
||||
'İstanbul': 45,
|
||||
'Ankara': 25,
|
||||
'İzmir': 15,
|
||||
'Diğer': 15
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Satış Performansı</h2>
|
||||
<p>Satış performans analizleri burada.</p>
|
||||
<div className="dashboard-page">
|
||||
<h2 className="page-title">Satış Performansı</h2>
|
||||
|
||||
<div className="grid-container">
|
||||
<div className="chart-card">
|
||||
<h3>Aylık Satış Trendi</h3>
|
||||
<Line data={salesData} />
|
||||
</div>
|
||||
|
||||
<div className="metrics-card">
|
||||
<h3>Bölgesel Dağılım</h3>
|
||||
<div className="regional-distribution">
|
||||
{Object.entries(regionalSales).map(([region, percent]) => (
|
||||
<div key={region} className="region-item">
|
||||
<div className="region-label">
|
||||
<span>{region}</span>
|
||||
<span>{percent}%</span>
|
||||
</div>
|
||||
<div className="progress-bar">
|
||||
<div
|
||||
className="progress-fill"
|
||||
style={{ width: `${percent}%` }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="recent-sales">
|
||||
<h3>Son İşlemler</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tarih</th>
|
||||
<th>Ürün</th>
|
||||
<th>Miktar</th>
|
||||
<th>Durum</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{[...Array(5)].map((_, i) => (
|
||||
<tr key={i}>
|
||||
<td>2023-0{i+1}-15</td>
|
||||
<td>Yazılım Paketi {i+1}</td>
|
||||
<td>{(i+1)*1450} TL</td>
|
||||
<td><span className="status completed">Tamamlandı</span></td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,10 +1,88 @@
|
|||
import React from 'react';
|
||||
// SalesReportsPage.jsx
|
||||
import React, { useState } from 'react';
|
||||
|
||||
const SalesReportsPage = () => {
|
||||
const [filters, setFilters] = useState({
|
||||
dateRange: 'month',
|
||||
productCategory: 'all',
|
||||
region: 'all'
|
||||
});
|
||||
|
||||
const reports = [...Array(8)].map((_, i) => ({
|
||||
id: i+1,
|
||||
date: `2023-Q${Math.floor(i/2)+1}`,
|
||||
product: `Ürün Kategorisi ${i%3+1}`,
|
||||
region: ['İstanbul', 'Ankara', 'İzmir'][i%3],
|
||||
total: (i+1)*17500,
|
||||
status: ['pending', 'completed'][i%2]
|
||||
}));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Satış Raporları</h2>
|
||||
<p>Satış raporlarına ait detaylar.</p>
|
||||
<div className="dashboard-page">
|
||||
<h2 className="page-title">Satış Raporları</h2>
|
||||
|
||||
<div className="report-filters">
|
||||
<select
|
||||
value={filters.dateRange}
|
||||
onChange={(e) => setFilters({...filters, dateRange: e.target.value})}
|
||||
>
|
||||
<option value="week">Son 1 Hafta</option>
|
||||
<option value="month">Son 1 Ay</option>
|
||||
<option value="quarter">Son 3 Ay</option>
|
||||
</select>
|
||||
|
||||
<select
|
||||
value={filters.productCategory}
|
||||
onChange={(e) => setFilters({...filters, productCategory: e.target.value})}
|
||||
>
|
||||
<option value="all">Tüm Kategoriler</option>
|
||||
<option value="1">ERP Çözümleri</option>
|
||||
<option value="2">Bulut Hizmetleri</option>
|
||||
</select>
|
||||
|
||||
<select
|
||||
value={filters.region}
|
||||
onChange={(e) => setFilters({...filters, region: e.target.value})}
|
||||
>
|
||||
<option value="all">Tüm Bölgeler</option>
|
||||
<option value="istanbul">İstanbul</option>
|
||||
<option value="ankara">Ankara</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="report-table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Çeyrek</th>
|
||||
<th>Ürün Kategorisi</th>
|
||||
<th>Bölge</th>
|
||||
<th>Toplam Satış</th>
|
||||
<th>Durum</th>
|
||||
<th>İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{reports.map(report => (
|
||||
<tr key={report.id}>
|
||||
<td>{report.date}</td>
|
||||
<td>{report.product}</td>
|
||||
<td>{report.region}</td>
|
||||
<td>{report.total.toLocaleString()} TL</td>
|
||||
<td>
|
||||
<span className={`status ${report.status}`}>
|
||||
{report.status === 'completed' ? 'Tamamlandı' : 'Beklemede'}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button className="export-btn pdf">PDF Al</button>
|
||||
<button className="export-btn excel">Excel'e Aktar</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,10 +1,104 @@
|
|||
import React from 'react';
|
||||
// StockCampaignManagementPage.jsx
|
||||
import React, { useState } from 'react';
|
||||
|
||||
const StockCampaignManagementPage = () => {
|
||||
const [stock] = useState([
|
||||
{ id: 1, product: 'ERP Pro Lisans', stock: 45, threshold: 50 },
|
||||
{ id: 2, product: 'Bulut Depolama 100GB', stock: 23, threshold: 30 },
|
||||
{ id: 3, product: 'E-Ticaret Entegrasyon', stock: 12, threshold: 20 }
|
||||
]);
|
||||
|
||||
const [campaigns, setCampaigns] = useState([
|
||||
{ id: 1, name: 'Yazılım Paket İndirimi', status: 'active', discount: 15 },
|
||||
{ id: 2, name: 'Bulut Depolama Kampanyası', status: 'planned', discount: 20 }
|
||||
]);
|
||||
|
||||
const [newCampaign, setNewCampaign] = useState({
|
||||
name: '',
|
||||
discount: '',
|
||||
startDate: '',
|
||||
endDate: ''
|
||||
});
|
||||
|
||||
const handleAddCampaign = (e) => {
|
||||
e.preventDefault();
|
||||
// Kampanya ekleme mantığı
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Stok & Kampanya Yönetimi</h2>
|
||||
<p>Stok ve kampanya yönetimi bilgileri.</p>
|
||||
<div className="dashboard-page">
|
||||
<h2 className="page-title">Stok & Kampanya Yönetimi</h2>
|
||||
|
||||
<div className="management-container">
|
||||
<div className="stock-section">
|
||||
<h3>Stok Durumu</h3>
|
||||
<div className="stock-list">
|
||||
{stock.map(item => (
|
||||
<div key={item.id} className="stock-item">
|
||||
<div className="stock-info">
|
||||
<span className="product-name">{item.product}</span>
|
||||
<span className={`stock-quantity ${item.stock < item.threshold ? 'low' : ''}`}>
|
||||
{item.stock} Adet
|
||||
</span>
|
||||
</div>
|
||||
<div className="progress-bar">
|
||||
<div
|
||||
className="progress-fill"
|
||||
style={{ width: `${(item.stock / item.threshold) * 100}%` }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="campaign-section">
|
||||
<h3>Aktif Kampanyalar</h3>
|
||||
<div className="campaign-list">
|
||||
{campaigns.map(campaign => (
|
||||
<div key={campaign.id} className={`campaign-card ${campaign.status}`}>
|
||||
<div className="campaign-header">
|
||||
<h4>{campaign.name}</h4>
|
||||
<span className="status-dot"></span>
|
||||
</div>
|
||||
<div className="campaign-details">
|
||||
<span>İndirim: %{campaign.discount}</span>
|
||||
<span>Durum: {campaign.status === 'active' ? 'Aktif' : 'Planlanan'}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleAddCampaign} className="campaign-form">
|
||||
<h4>Yeni Kampanya Ekle</h4>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Kampanya Adı"
|
||||
value={newCampaign.name}
|
||||
onChange={(e) => setNewCampaign({...newCampaign, name: e.target.value})}
|
||||
/>
|
||||
<input
|
||||
type="number"
|
||||
placeholder="İndirim Oranı (%)"
|
||||
value={newCampaign.discount}
|
||||
onChange={(e) => setNewCampaign({...newCampaign, discount: e.target.value})}
|
||||
/>
|
||||
<div className="date-inputs">
|
||||
<input
|
||||
type="date"
|
||||
value={newCampaign.startDate}
|
||||
onChange={(e) => setNewCampaign({...newCampaign, startDate: e.target.value})}
|
||||
/>
|
||||
<input
|
||||
type="date"
|
||||
value={newCampaign.endDate}
|
||||
onChange={(e) => setNewCampaign({...newCampaign, endDate: e.target.value})}
|
||||
/>
|
||||
</div>
|
||||
<button type="submit" className="add-button">Kampanya Ekle</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,298 @@
|
|||
/* styles/dashboard.css */
|
||||
.dashboard-container {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.dashboard-header {
|
||||
color: #2c3e50;
|
||||
border-bottom: 2px solid #3498db;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.dashboard-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
padding: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
color: #2980b9;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
border-left: 4px solid #3498db;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
color: #7f8c8d;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.data-table th {
|
||||
background-color: #3498db;
|
||||
color: white;
|
||||
padding: 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.data-table td {
|
||||
padding: 10px 12px;
|
||||
border-bottom: 1px solid #ecf0f1;
|
||||
}
|
||||
|
||||
.data-table tr:hover {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
background-color: #3498db;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
margin-right: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.action-btn.secondary {
|
||||
background-color: #95a5a6;
|
||||
}
|
||||
|
||||
.action-btn.danger {
|
||||
background-color: #e74c3c;
|
||||
}
|
||||
|
||||
.action-btn:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
height: 300px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.search-filter {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.filter-select {
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
background: white;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.page-title {
|
||||
color: #2c3e50;
|
||||
border-bottom: 3px solid #4A90E2;
|
||||
padding-bottom: 0.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.chart-card, .metrics-card {
|
||||
background: white;
|
||||
padding: 1.5rem;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 15px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.recent-sales table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
th, td {
|
||||
text-align: left;
|
||||
padding: 12px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.status {
|
||||
display: inline-block;
|
||||
padding: 5px 12px;
|
||||
border-radius: 20px;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.status.completed {
|
||||
background: #e8f5e9;
|
||||
color: #2e7d32;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 8px;
|
||||
background: #eee;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background: #4A90E2;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
/* Sales Reports Specific */
|
||||
.report-filters {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.report-filters select {
|
||||
padding: 8px 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.export-btn {
|
||||
padding: 6px 12px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
margin: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.export-btn.pdf { background: #ff4757; color: white; }
|
||||
.export-btn.excel { background: #2ed573; color: white; }
|
||||
|
||||
/* Stock & Campaign Management */
|
||||
.management-container {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1.5fr;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.stock-item {
|
||||
background: white;
|
||||
padding: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.stock-quantity.low { color: #e74c3c; }
|
||||
|
||||
.campaign-card {
|
||||
background: white;
|
||||
padding: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
border-left: 4px solid;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.campaign-card.active { border-color: #4A90E2; }
|
||||
.campaign-card.planned { border-color: #f1c40f; }
|
||||
|
||||
.campaign-form {
|
||||
background: #f9f9f9;
|
||||
padding: 1.5rem;
|
||||
border-radius: 8px;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.campaign-form input {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
margin: 8px 0;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.add-button {
|
||||
background: #4A90E2;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.management-container {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.grid-container {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -12,31 +12,31 @@ const LoginPage = ({ onLogin }) => {
|
|||
};
|
||||
|
||||
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">
|
||||
<div style={styles.loginContainer}>
|
||||
<div style={styles.loginBox}>
|
||||
<h1 style={styles.loginTitle}>Software License Dashboard</h1>
|
||||
<div style={styles.buttonContainer}>
|
||||
<button
|
||||
onClick={() => handleLogin('admin')}
|
||||
className="w-full py-2 px-4 bg-blue-500 text-white rounded hover:bg-blue-600 transition"
|
||||
style={{ ...styles.loginButton, ...styles.admin }}
|
||||
>
|
||||
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"
|
||||
style={{ ...styles.loginButton, ...styles.distributor }}
|
||||
>
|
||||
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"
|
||||
style={{ ...styles.loginButton, ...styles.retailer }}
|
||||
>
|
||||
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"
|
||||
style={{ ...styles.loginButton, ...styles.customer }}
|
||||
>
|
||||
Login as Customer
|
||||
</button>
|
||||
|
@ -46,4 +46,78 @@ const LoginPage = ({ onLogin }) => {
|
|||
);
|
||||
};
|
||||
|
||||
const styles = {
|
||||
loginContainer: {
|
||||
minHeight: '100vh',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
background: 'linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%)',
|
||||
padding: '20px',
|
||||
},
|
||||
loginBox: {
|
||||
background: 'rgba(255, 255, 255, 0.95)',
|
||||
padding: '2.5rem',
|
||||
borderRadius: '15px',
|
||||
boxShadow: '0 8px 30px rgba(0, 0, 0, 0.12)',
|
||||
width: '100%',
|
||||
maxWidth: '400px',
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
animation: 'fadeInUp 0.6s ease',
|
||||
},
|
||||
loginTitle: {
|
||||
fontSize: '1.8rem',
|
||||
fontWeight: 700,
|
||||
color: '#2d3748',
|
||||
textAlign: 'center',
|
||||
marginBottom: '2rem',
|
||||
position: 'relative',
|
||||
},
|
||||
buttonContainer: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '1rem',
|
||||
},
|
||||
loginButton: {
|
||||
width: '100%',
|
||||
padding: '0.8rem',
|
||||
border: 'none',
|
||||
borderRadius: '8px',
|
||||
fontSize: '1rem',
|
||||
fontWeight: '500',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 0.3s ease',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: '0.5rem',
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
loginButtonHover: {
|
||||
transform: 'translateY(-2px)',
|
||||
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
|
||||
},
|
||||
loginButtonActive: {
|
||||
transform: 'translateY(0)',
|
||||
},
|
||||
admin: {
|
||||
background: '#4299e1',
|
||||
color: 'white',
|
||||
},
|
||||
distributor: {
|
||||
background: '#48bb78',
|
||||
color: 'white',
|
||||
},
|
||||
retailer: {
|
||||
background: '#9f7aea',
|
||||
color: 'white',
|
||||
},
|
||||
customer: {
|
||||
background: '#ed8936',
|
||||
color: 'white',
|
||||
},
|
||||
};
|
||||
|
||||
export default LoginPage;
|
|
@ -15,7 +15,7 @@ const DistributorRoutes = () => {
|
|||
<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="/stock-campaign" element={<StockCampaignManagementPage />} />
|
||||
<Route path="/payment-billing" element={<PaymentBillingPage />} />
|
||||
<Route path="/retailer-feedback" element={<RetailerFeedbackPage />} />
|
||||
<Route path="/sales-reports" element={<SalesReportsPage />} />
|
||||
|
|
Loading…
Reference in New Issue