diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index e93756d..17722f5 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -7,8 +7,14 @@ import { } from './components/RoleBasedSidebar'; import WorkspaceView from './components/WorkspaceView'; + import { CartProvider } from './context/CartContext'; +// Auth Pages +import Login from './pages/shared/Login'; +import Signup from './pages/shared/Signup'; +import SellerVerification from './pages/shared/SellerVerification'; + // Buyer Pages import MapDiscovery from './pages/buyer/MapDiscovery'; import Discover from './pages/buyer/Discover'; @@ -18,6 +24,7 @@ import ProductDetail from './pages/buyer/ProductDetail'; import Cart from './pages/buyer/Cart'; import Checkout from './pages/buyer/Checkout'; import Orders from './pages/buyer/Orders'; +import BuyerProfile from './pages/buyer/BuyerProfile'; // Seller Pages import Dashboard from './pages/seller/dashboard'; @@ -34,10 +41,43 @@ import Users from './pages/admin/users'; import Logs from './pages/admin/logs'; import Disputes from './pages/admin/disputes'; +// Admin Pages +import Overview from './pages/admin/overview'; +import Verify from './pages/admin/verify'; +import Moderate from './pages/admin/moderate'; +import Users from './pages/admin/users'; +import Logs from './pages/admin/logs'; +import Disputes from './pages/admin/disputes'; + const App = () => ( + + + } />} > + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + } />}> + } /> + + + } />}> + } /> + + + + } /> + } /> + } /> + {/* Admin Routes */} ( } /> } /> } /> + } /> } /> diff --git a/frontend/src/components/RoleBasedSidebar.jsx b/frontend/src/components/RoleBasedSidebar.jsx index 7fa1f17..901b221 100644 --- a/frontend/src/components/RoleBasedSidebar.jsx +++ b/frontend/src/components/RoleBasedSidebar.jsx @@ -15,6 +15,7 @@ import { Truck, DollarSign, Compass, + User, } from 'lucide-react'; const SidebarNavItem = ({ diff --git a/frontend/src/components/admin/ActiveDisputeQueue.jsx b/frontend/src/components/admin/ActiveDisputeQueue.jsx index 1095c11..aad0851 100644 --- a/frontend/src/components/admin/ActiveDisputeQueue.jsx +++ b/frontend/src/components/admin/ActiveDisputeQueue.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { ArrowUpDown, SlidersHorizontal } from 'lucide-react'; -import Pagination from '../seller/Pagination'; +import Pagination from './Pagination'; const ReasonBadge = ({ reason }) => { return ( @@ -17,13 +17,13 @@ const ActiveDisputeQueue = ({ data, onRowClick, onFilterClick, onSortClick }) =>

Active Dispute Queue

- -
-
@@ -37,13 +37,13 @@ const ApplicationsTable = ({ data, onFilterClick, onDownloadClick, onRowClick })

Applications Overview

- -
-
@@ -67,14 +67,14 @@ const ModerationTable = ({ data, onFilterClick, onDownloadClick, onReviewClick }

Moderation Queue

- -
- + + {/* Page Numbers */} + + + + + {/* Ellipsis */} + + ... + + + + + {/* Next Button */} + +
+ ); +}; + +export default Pagination; diff --git a/frontend/src/components/admin/TransactionLogsTable.jsx b/frontend/src/components/admin/TransactionLogsTable.jsx index 2d697d4..d59395c 100644 --- a/frontend/src/components/admin/TransactionLogsTable.jsx +++ b/frontend/src/components/admin/TransactionLogsTable.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { ChevronDown, Eye } from 'lucide-react'; -import Pagination from '../seller/Pagination'; +import Pagination from './Pagination'; const TypeBadge = ({ type }) => { return ( diff --git a/frontend/src/components/admin/UserDirectoryTable.jsx b/frontend/src/components/admin/UserDirectoryTable.jsx index 2780e01..073265b 100644 --- a/frontend/src/components/admin/UserDirectoryTable.jsx +++ b/frontend/src/components/admin/UserDirectoryTable.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { ChevronDown, Pencil, Store, Ban, CheckCircle, RefreshCw } from 'lucide-react'; -import Pagination from '../seller/Pagination'; +import Pagination from './Pagination'; const RoleBadge = ({ role }) => { return ( @@ -32,14 +32,14 @@ const UserDirectoryTable = ({ data, onFilterClick, onActionClick }) => {

Directory

- - ) : row.status === 'PENDING' ? ( - ) : ( - +
+
+ + {/* Right Form Content */} +
+
+ + {/* Personal Information */} +
+
+
+ +
+

Personal Details

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + {/* Delivery Address & Location */} +
+
+
+ +
+

Delivery Address

+
+ +
+
+ + +
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ +
+
+ + Drag pin to adjust +
+
+ + + + +
+
+
+ Deliver Here + + + +
+
+
+ + {/* Verification Document */} +
+
+
+ +
+

Identity Verification

+
+
+ +

For secure transactions, we require a valid government-issued ID.

+ +
+
+
+ +
+
+ +
+

PNG, JPG, PDF up to 10MB

+ + {formData.idFile && ( +
+ + {formData.idFile.name} +
+ )} +
+
+
+
+ +
+ +
+ +
+
+
+
+ ); +}; + +export default BuyerProfile; diff --git a/frontend/src/pages/buyer/Checkout.jsx b/frontend/src/pages/buyer/Checkout.jsx index 82f7462..e22ec99 100644 --- a/frontend/src/pages/buyer/Checkout.jsx +++ b/frontend/src/pages/buyer/Checkout.jsx @@ -66,21 +66,29 @@ const Checkout = () => { const [step, setStep] = useState('delivery'); // 'delivery', 'payment', 'review' const [isProcessing, setIsProcessing] = useState(false); const [paymentMethod, setPaymentMethod] = useState('card'); // 'card', 'gcash', 'cod' - const [formData, setFormData] = useState({ - firstName: '', - lastName: '', - email: '', - phone: '', - address: '', - city: '', - province: '', - zipCode: '', - region: '', - deliveryNotes: '', - cardNumber: '', - cardExpiry: '', - cardCvv: '', - cardholderName: '' + const [formData, setFormData] = useState(() => { + const savedProfile = localStorage.getItem('buyerProfile'); + let parsed = null; + if (savedProfile) { + try { parsed = JSON.parse(savedProfile); } catch (e) {} + } + + return { + firstName: parsed?.firstName || '', + lastName: parsed?.lastName || '', + email: parsed?.email || '', + phone: parsed?.phone || '', + address: parsed?.address?.street || '', + city: parsed?.address?.city || '', + province: parsed?.address?.state || '', + zipCode: parsed?.address?.zipCode || '', + region: '', + deliveryNotes: '', + cardNumber: '', + cardExpiry: '', + cardCvv: '', + cardholderName: parsed ? `${parsed.firstName} ${parsed.lastName}`.trim().toUpperCase() : '' + }; }); const handleChange = (e) => setFormData((p) => ({ ...p, [e.target.name]: e.target.value })); diff --git a/frontend/src/pages/buyer/ProductDetail.jsx b/frontend/src/pages/buyer/ProductDetail.jsx index 2bdedf2..96ba55a 100644 --- a/frontend/src/pages/buyer/ProductDetail.jsx +++ b/frontend/src/pages/buyer/ProductDetail.jsx @@ -57,7 +57,7 @@ const ProductDetail = () => { return (
-
+
{/* Back button */} + +
+

+ Don't have an account?{' '} + + Create one now + +

+
+ +
+
+
+ ); +}; + +export default Login; \ No newline at end of file diff --git a/frontend/src/pages/shared/SellerVerification.jsx b/frontend/src/pages/shared/SellerVerification.jsx new file mode 100644 index 0000000..c6624a9 --- /dev/null +++ b/frontend/src/pages/shared/SellerVerification.jsx @@ -0,0 +1,403 @@ +import React, { useState } from 'react'; +import { Upload, MapPin, Store, FileText, CheckCircle, ArrowRight, ArrowLeft, ShieldCheck, Map as MapIcon, User } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Textarea } from '@/components/ui/textarea'; +import { Label } from '@/components/ui/label'; +import { Map, MapMarker, MapControls, MarkerContent, MarkerLabel } from '@/components/ui/map'; +import { Link } from 'react-router-dom'; + +const SellerVerification = () => { + const [step, setStep] = useState(1); + const [isSubmitted, setIsSubmitted] = useState(false); + const [formData, setFormData] = useState({ + firstName: '', + middleName: '', + lastName: '', + phone: '', + storeName: '', + category: '', + description: '', + address: { + street: '', + city: '', + state: '', + zipCode: '', + }, + permitFile: null, + idFile: null, + location: { + lng: 121.0215, // Manila coordinates + lat: 14.5995, + } + }); + + const handleAddressChange = (e) => { + setFormData({ + ...formData, + address: { + ...formData.address, + [e.target.name]: e.target.value + } + }); + }; + + const [mapViewport, setMapViewport] = useState({ + center: [121.0215, 14.5995], + zoom: 12, + }); + + const handleInputChange = (e) => { + setFormData({ ...formData, [e.target.name]: e.target.value }); + }; + + const handleFileChange = (e, field) => { + if (e.target.files && e.target.files[0]) { + setFormData({ ...formData, [field]: e.target.files[0] }); + } + }; + + const handleDragEnd = (e) => { + setFormData({ + ...formData, + location: { lng: e.lng, lat: e.lat } + }); + }; + + const handleLocate = (coords) => { + setFormData({ + ...formData, + location: { lng: coords.longitude, lat: coords.latitude } + }); + setMapViewport({ + center: [coords.longitude, coords.latitude], + zoom: 15, + }); + }; + + const nextStep = () => setStep(step + 1); + const prevStep = () => setStep(step - 1); + + const handleSubmit = (e) => { + e.preventDefault(); + console.log('Seller Verification Submitted', formData); + setIsSubmitted(true); + }; + + if (isSubmitted) { + return ( +
+
+
+
+ +
+
+

Application Received

+

+ Thank you for applying to become a seller. We are reviewing your documents and store information. You will be notified once your store is approved. +

+
+ + + +
+
+
+ ); + } + + return ( +
+ + {/* Decorative background elements */} +
+
+ +
+
+ +
+
+
= 1 ? 'w-8 bg-primary/80' : 'w-4 bg-muted'}`} /> +
= 2 ? 'w-8 bg-primary/80' : 'w-4 bg-muted'}`} /> +
= 3 ? 'w-8 bg-primary/80' : 'w-4 bg-muted'}`} /> +
= 4 ? 'w-8 bg-primary/80' : 'w-4 bg-muted'}`} /> +
+
+ +
+

+ {step === 1 && "Seller Identity"} + {step === 2 && "Store Basics"} + {step === 3 && "Store Location"} + {step === 4 && "Verification Documents"} +

+

+ {step === 1 && "Please provide your authentic legal identification details."} + {step === 2 && "Tell us about the craft you sell."} + {step === 3 && "Where can buyers find your physical store or workshop?"} + {step === 4 && "Upload necessary IDs and permits to verify your identity."} +

+
+ +
e.preventDefault()} className="space-y-8"> + + {/* Step 1: Personal Identity */} + {step === 1 && ( +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+ )} + + {/* Step 2: Store Basics */} + {step === 2 && ( +
+
+ + +
+ +
+ + +
+ +
+ +