diff --git a/package-lock.json b/package-lock.json index a171492..b746390 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index b273cc8..5de1da2 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/assets/logo2.png b/src/assets/logo2.png new file mode 100644 index 0000000..5b416c3 Binary files /dev/null and b/src/assets/logo2.png differ diff --git a/src/components/Navbar.js b/src/components/Navbar.js index 150983a..08ca8c2 100644 --- a/src/components/Navbar.js +++ b/src/components/Navbar.js @@ -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 = ({
navigate('/dashboard')}> Company Logo - Priente Software License Dashboard + Software License Dashboard
diff --git a/src/pages/Distributor/LicenseDistributionPage.js b/src/pages/Distributor/LicenseDistributionPage.js index 7c897cf..a254be2 100644 --- a/src/pages/Distributor/LicenseDistributionPage.js +++ b/src/pages/Distributor/LicenseDistributionPage.js @@ -1,12 +1,111 @@ 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 ( -
-

Lisans Dağıtımı

-

Lisans dağıtım işlemleri detayları.

+
+

License Distribution Management

+ +
+ {licenseStats.map((stat, index) => ( +
+
{stat.value}
+
{stat.label}
+ + {stat.change} from last month + +
+ ))} +
+ +
+

Recent License Distributions

+
+ + +
+
+ + + + + + + + + + + + + {recentDistributions.map((license, index) => ( + + + + + + + + + ))} + +
License IDProductDistributorDateStatusActions
{license.id}{license.product}{license.distributor}{license.date} + + {license.status} + + + + +
+
+
+ +
+

License Distribution Analytics

+
+ {/* This would be replaced with an actual chart component */} +
+ [License Distribution Chart - Monthly Trends] +
+
+
); }; -export default LicenseDistributionPage; +export default LicenseDistributionPage; \ No newline at end of file diff --git a/src/pages/Distributor/OrderManagementPage.js b/src/pages/Distributor/OrderManagementPage.js index 36bd9bd..a8ca97f 100644 --- a/src/pages/Distributor/OrderManagementPage.js +++ b/src/pages/Distributor/OrderManagementPage.js @@ -1,12 +1,170 @@ 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 ( -
-

Sipariş Yönetimi

-

Sipariş yönetimi ile ilgili içerikler.

+
+

Order Management System

+ +
+ {orderStats.map((stat, index) => ( +
+
{stat.value}
+
{stat.label}
+ + {stat.change.startsWith('-') ? stat.change : `+${stat.change}`} from last month + +
+ ))} +
+ +
+

Recent Orders

+
+ + +
+
+ + + + + + + + + + + + + + {recentOrders.map((order, index) => ( + + + + + + + + + + ))} + +
Order IDCustomerProductAmountDateStatusActions
{order.id}{order.customer}{order.product}{order.amount}{order.date} + + {order.status} + + + + + {order.status === 'Processing' && ( + + )} +
+
+
+ +
+

Order Fulfillment Workflow

+
+
+
1
+

Order Received

+

Customer places order

+
+
+
2
+

Processing

+

Verification & preparation

+
+
+
3
+

License Generation

+

Create & validate license

+
+
+
4
+

Delivery

+

Send to customer

+
+
+
); }; -export default OrderManagementPage; +export default OrderManagementPage; \ No newline at end of file diff --git a/src/pages/Distributor/PaymentBillingPage.js b/src/pages/Distributor/PaymentBillingPage.js index 1ce78bd..dec527b 100644 --- a/src/pages/Distributor/PaymentBillingPage.js +++ b/src/pages/Distributor/PaymentBillingPage.js @@ -1,12 +1,164 @@ 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 ( -
-

Ödeme & Fatura

-

Ödeme ve fatura işlemleri bilgileri.

+
+

Payment & Billing Management

+ +
+ {paymentStats.map((stat, index) => ( +
+
{stat.value}
+
{stat.label}
+ + {stat.change.startsWith('-') ? stat.change : `+${stat.change}`} from last month + +
+ ))} +
+ +
+

Recent Transactions

+
+ + +
+
+ + + + + + + + + + + + + + {recentTransactions.map((txn, index) => ( + + + + + + + + + + ))} + +
Transaction IDInvoiceAmountDateMethodStatusActions
{txn.id}{txn.invoice}{txn.amount}{txn.date}{txn.method} + + {txn.status} + + + + {txn.status === 'Pending' && ( + + )} + {txn.status === 'Failed' && ( + + )} +
+
+
+ +
+

Upcoming Invoices

+
+ + + + + + + + + + + + + {upcomingInvoices.map((invoice, index) => ( + + + + + + + + + ))} + +
InvoiceClientAmountDue DateStatusActions
{invoice.invoice}{invoice.client}{invoice.amount}{invoice.dueDate} + + {invoice.status} + + + + +
+
+
+ +
+

Revenue Analytics

+
+ {/* This would be replaced with an actual chart component */} +
+ [Revenue Chart - Monthly Trends by Payment Method] +
+
+
); }; -export default PaymentBillingPage; +export default PaymentBillingPage; \ No newline at end of file diff --git a/src/pages/Distributor/RetailerFeedbackPage.js b/src/pages/Distributor/RetailerFeedbackPage.js index ca495b8..d497f37 100644 --- a/src/pages/Distributor/RetailerFeedbackPage.js +++ b/src/pages/Distributor/RetailerFeedbackPage.js @@ -1,12 +1,188 @@ 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 ( -
-

Perakende Geri Bildirim

-

Perakende ile gelen geri bildirimler.

+
+

Retailer Feedback Management

+ +
+ {feedbackStats.map((stat, index) => ( +
+
{stat.value}
+
{stat.label}
+ + {stat.change} from last month + +
+ ))} +
+ +
+

Recent Feedback

+
+ + +
+
+ + + + + + + + + + + + + + {recentFeedback.map((feedback, index) => ( + + + + + + + + + + ))} + +
Feedback IDRetailerRatingCommentDateStatusActions
{feedback.id}{feedback.retailer} +
+ {[...Array(5)].map((_, i) => ( + + ))} +
+
{feedback.comment}{feedback.date} + + {feedback.status} + + + + {feedback.status !== 'Responded' && ( + + )} +
+
+
+ +
+
+

Rating Distribution

+
+ {ratingDistribution.map((item, index) => ( +
+
+ + {[...Array(item.stars)].map((_, i) => ( + + ))} + + {item.count} ({item.percent}%) +
+
+
+
+
+ ))} +
+
+ +
+

Feedback Response

+
+ {/* This would be replaced with an actual chart component */} +
+ [Response Time and Satisfaction Chart] +
+
+
+
+
92%
+
Response Rate
+
+
+
6.2h
+
Avg. Response Time
+
+
+
87%
+
Satisfaction After Response
+
+
+
+
); }; -export default RetailerFeedbackPage; +export default RetailerFeedbackPage; \ No newline at end of file diff --git a/src/pages/Distributor/SalesPerformancePage.js b/src/pages/Distributor/SalesPerformancePage.js index 3b107c8..b156216 100644 --- a/src/pages/Distributor/SalesPerformancePage.js +++ b/src/pages/Distributor/SalesPerformancePage.js @@ -1,12 +1,84 @@ +// 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 ( -
-

Satış Performansı

-

Satış performans analizleri burada.

+
+

Satış Performansı

+ +
+
+

Aylık Satış Trendi

+ +
+ +
+

Bölgesel Dağılım

+
+ {Object.entries(regionalSales).map(([region, percent]) => ( +
+
+ {region} + {percent}% +
+
+
+
+
+ ))} +
+
+ +
+

Son İşlemler

+ + + + + + + + + + + {[...Array(5)].map((_, i) => ( + + + + + + + ))} + +
TarihÜrünMiktarDurum
2023-0{i+1}-15Yazılım Paketi {i+1}{(i+1)*1450} TLTamamlandı
+
+
); }; -export default SalesPerformancePage; +export default SalesPerformancePage; \ No newline at end of file diff --git a/src/pages/Distributor/SalesReportsPage.js b/src/pages/Distributor/SalesReportsPage.js index 4ed6417..2a28a00 100644 --- a/src/pages/Distributor/SalesReportsPage.js +++ b/src/pages/Distributor/SalesReportsPage.js @@ -1,12 +1,90 @@ -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 ( -
-

Satış Raporları

-

Satış raporlarına ait detaylar.

+
+

Satış Raporları

+ +
+ + + + + +
+ +
+ + + + + + + + + + + + + {reports.map(report => ( + + + + + + + + + ))} + +
ÇeyrekÜrün KategorisiBölgeToplam SatışDurumİşlemler
{report.date}{report.product}{report.region}{report.total.toLocaleString()} TL + + {report.status === 'completed' ? 'Tamamlandı' : 'Beklemede'} + + + + +
+
); }; -export default SalesReportsPage; +export default SalesReportsPage; \ No newline at end of file diff --git a/src/pages/Distributor/StockCampaignManagementPage.js b/src/pages/Distributor/StockCampaignManagementPage.js index 2d792a8..62b4129 100644 --- a/src/pages/Distributor/StockCampaignManagementPage.js +++ b/src/pages/Distributor/StockCampaignManagementPage.js @@ -1,12 +1,106 @@ -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 ( -
-

Stok & Kampanya Yönetimi

-

Stok ve kampanya yönetimi bilgileri.

+
+

Stok & Kampanya Yönetimi

+ +
+
+

Stok Durumu

+
+ {stock.map(item => ( +
+
+ {item.product} + + {item.stock} Adet + +
+
+
+
+
+ ))} +
+
+ +
+

Aktif Kampanyalar

+
+ {campaigns.map(campaign => ( +
+
+

{campaign.name}

+ +
+
+ İndirim: %{campaign.discount} + Durum: {campaign.status === 'active' ? 'Aktif' : 'Planlanan'} +
+
+ ))} +
+ + +

Yeni Kampanya Ekle

+ setNewCampaign({...newCampaign, name: e.target.value})} + /> + setNewCampaign({...newCampaign, discount: e.target.value})} + /> +
+ setNewCampaign({...newCampaign, startDate: e.target.value})} + /> + setNewCampaign({...newCampaign, endDate: e.target.value})} + /> +
+ + +
+
); }; -export default StockCampaignManagementPage; +export default StockCampaignManagementPage; \ No newline at end of file diff --git a/src/pages/Distributor/dashboard.css b/src/pages/Distributor/dashboard.css new file mode 100644 index 0000000..e97a5bb --- /dev/null +++ b/src/pages/Distributor/dashboard.css @@ -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; + } + } + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/pages/LoginPage.js b/src/pages/LoginPage.js index ce26156..eb80e0a 100644 --- a/src/pages/LoginPage.js +++ b/src/pages/LoginPage.js @@ -12,31 +12,31 @@ const LoginPage = ({ onLogin }) => { }; return ( -
-
-

Software License Dashboard

-
+
+
+

Software License Dashboard

+
@@ -46,4 +46,78 @@ const LoginPage = ({ onLogin }) => { ); }; -export default LoginPage; \ No newline at end of file +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; diff --git a/src/roles/DistributorRoutes.js b/src/roles/DistributorRoutes.js index 9557b7b..ff4bd1e 100644 --- a/src/roles/DistributorRoutes.js +++ b/src/roles/DistributorRoutes.js @@ -15,7 +15,7 @@ const DistributorRoutes = () => { } /> } /> } /> - } /> + } /> } /> } /> } />