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 - - @@ -50,8 +50,8 @@ const ActiveDisputeQueue = ({ data, onRowClick, onFilterClick, onSortClick }) => {data.map((row, i) => ( - onRowClick(row.id)} className={`border-b border-neutral-dark/5 hover:bg-neutral-dark/5 transition-colors cursor-pointer group/row ${i === data.length - 1 ? 'border-b-0' : ''}`} > diff --git a/frontend/src/components/admin/ApplicationsTable.jsx b/frontend/src/components/admin/ApplicationsTable.jsx index b13a895..bbac8a5 100644 --- a/frontend/src/components/admin/ApplicationsTable.jsx +++ b/frontend/src/components/admin/ApplicationsTable.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { Filter, Download, ChevronRight } from 'lucide-react'; -import Pagination from '../seller/Pagination'; +import Pagination from './Pagination'; const StatusBadge = ({ status }) => { const isFlagged = status === 'FLAGGED'; @@ -21,7 +21,7 @@ const ScoreBar = ({ score }) => { {score} - @@ -37,13 +37,13 @@ const ApplicationsTable = ({ data, onFilterClick, onDownloadClick, onRowClick }) Applications Overview - - @@ -67,8 +67,8 @@ const ApplicationsTable = ({ data, onFilterClick, onDownloadClick, onRowClick }) {data.map((row, i) => ( - onRowClick(row.name)} className={`border-b border-neutral-dark/5 hover:bg-neutral-dark/5 transition-colors group/row cursor-pointer ${i === data.length - 1 ? 'border-b-0' : ''}`} > diff --git a/frontend/src/components/admin/ModerationTable.jsx b/frontend/src/components/admin/ModerationTable.jsx index a8a6be1..06a9d54 100644 --- a/frontend/src/components/admin/ModerationTable.jsx +++ b/frontend/src/components/admin/ModerationTable.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { ChevronDown, Download } from 'lucide-react'; -import Pagination from '../seller/Pagination'; +import Pagination from './Pagination'; const ViolationBadge = ({ type }) => { let styleClass = "bg-neutral-dark/10 text-neutral-dark/60"; // Default @@ -33,7 +33,7 @@ const SeverityBar = ({ score }) => { {score} - @@ -67,14 +67,14 @@ const ModerationTable = ({ data, onFilterClick, onDownloadClick, onReviewClick } Moderation Queue - onFilterClick('Violation')} className="flex items-center gap-2 px-3 py-1.5 rounded-md border border-neutral-dark/10 bg-neutral-dark/5 hover:bg-neutral-dark/10 text-[11px] font-sans font-bold text-neutral-dark transition-colors uppercase tracking-wider" > ALL VIOLATION TYPES - onFilterClick('Severity')} className="flex items-center gap-2 px-3 py-1.5 rounded-md border border-neutral-dark/10 bg-neutral-dark/5 hover:bg-neutral-dark/10 text-[11px] font-sans font-bold text-neutral-dark transition-colors uppercase tracking-wider" > @@ -82,7 +82,7 @@ const ModerationTable = ({ data, onFilterClick, onDownloadClick, onReviewClick } - @@ -106,8 +106,8 @@ const ModerationTable = ({ data, onFilterClick, onDownloadClick, onReviewClick } {data.map((row, i) => ( - @@ -145,7 +145,7 @@ const ModerationTable = ({ data, onFilterClick, onDownloadClick, onReviewClick } - onReviewClick(row.productName)} className="px-4 py-1.5 rounded-md border border-neutral-dark/20 text-neutral-dark text-[11px] font-sans font-bold hover:bg-neutral-dark/5 transition-colors shadow-sm bg-background shrink-0" > diff --git a/frontend/src/components/admin/Pagination.jsx b/frontend/src/components/admin/Pagination.jsx new file mode 100644 index 0000000..a4ed84a --- /dev/null +++ b/frontend/src/components/admin/Pagination.jsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { ChevronLeft, ChevronRight } from 'lucide-react'; + +const Pagination = () => { + return ( + + {/* Previous Button */} + + + + + {/* Page Numbers */} + + 1 + + + 2 + + + 3 + + + {/* Ellipsis */} + + ... + + + + 12 + + + {/* 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 - onFilterClick('Role')} className="flex items-center gap-2 px-3 py-1.5 rounded-md border border-neutral-dark/10 bg-neutral-dark/5 hover:bg-neutral-dark/10 text-[11px] font-sans font-bold text-neutral-dark transition-colors uppercase tracking-wider" > ALL ROLES - onFilterClick('Status')} className="flex items-center gap-2 px-3 py-1.5 rounded-md border border-neutral-dark/10 bg-neutral-dark/5 hover:bg-neutral-dark/10 text-[11px] font-sans font-bold text-neutral-dark transition-colors uppercase tracking-wider" > @@ -67,8 +67,8 @@ const UserDirectoryTable = ({ data, onFilterClick, onActionClick }) => { {data.map((row, i) => ( - @@ -96,7 +96,7 @@ const UserDirectoryTable = ({ data, onFilterClick, onActionClick }) => { {/* Common Edit Action */} - onActionClick('Edit', row.name)} className="text-neutral-dark/40 hover:text-neutral-dark transition-colors outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm" > @@ -105,14 +105,14 @@ const UserDirectoryTable = ({ data, onFilterClick, onActionClick }) => { {/* Role-specific Action */} {row.role === 'SELLER' ? ( - onActionClick('View Shop', row.name)} className="text-[#8C5233] hover:text-[#7E4A2E] transition-colors outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm" > ) : row.status === 'PENDING' ? ( - onActionClick('Approve', row.name)} className="text-primary hover:text-primary-dark transition-colors outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm" > @@ -124,14 +124,14 @@ const UserDirectoryTable = ({ data, onFilterClick, onActionClick }) => { {/* Status-specific Action (Suspend / Restore) */} {row.status === 'SUSPENDED' ? ( - onActionClick('Restore', row.name)} className="text-primary hover:text-primary-dark transition-colors outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm" > ) : ( - onActionClick('Suspend', row.name)} className="text-destructive hover:text-red-700 transition-colors outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm" > diff --git a/frontend/src/index.css b/frontend/src/index.css index 3965264..bf60557 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -431,6 +431,9 @@ h6 { --input: rgba(54, 46, 37, 0.15); --ring: #A0522D; + --muted: rgba(54, 46, 37, 0.05); + --muted-foreground: rgba(54, 46, 37, 0.55); + --chart-1: #A0522D; --chart-2: #3D5A3E; --chart-3: #8B6914; @@ -488,6 +491,9 @@ h6 { --input: rgba(245, 240, 232, 0.12); --ring: #C8744C; + --muted: rgba(245, 240, 232, 0.05); + --muted-foreground: rgba(245, 240, 232, 0.55); + --sidebar: #241F1B; --sidebar-foreground: #F5F0E8; diff --git a/frontend/src/layouts/SharedSidebar.jsx b/frontend/src/layouts/SharedSidebar.jsx index 1f7287a..82cdd4b 100644 --- a/frontend/src/layouts/SharedSidebar.jsx +++ b/frontend/src/layouts/SharedSidebar.jsx @@ -1,5 +1,5 @@ import { Link } from 'react-router-dom'; -import { User, X } from 'lucide-react'; +import { User, X, LogOut } from 'lucide-react'; /** * SharedSidebar @@ -65,7 +65,7 @@ export const SharedSidebar = ({ sidebarContent, isSidebarOpen, setIsSidebarOpen {/* Profile footer */} - + Profile + + + + Sign Out + > diff --git a/frontend/src/pages/buyer/BuyerProfile.jsx b/frontend/src/pages/buyer/BuyerProfile.jsx new file mode 100644 index 0000000..dea4d82 --- /dev/null +++ b/frontend/src/pages/buyer/BuyerProfile.jsx @@ -0,0 +1,300 @@ +import React, { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Upload, CheckCircle, Save, MapPin, User, FileText, LogOut, ShieldCheck, Mail, Phone, Camera } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { Map, MapMarker, MapControls, MarkerContent, MarkerLabel } from '@/components/ui/map'; + +const BuyerProfile = () => { + const navigate = useNavigate(); + const [isSaved, setIsSaved] = useState(false); + + const [formData, setFormData] = useState(() => { + const saved = localStorage.getItem('buyerProfile'); + if (saved) { + try { return JSON.parse(saved); } catch (e) {} + } + return { + firstName: '', + middleName: '', + lastName: '', + email: '', + phone: '', + address: { + street: '', + city: '', + state: '', + zipCode: '', + }, + idFile: null, + location: { + lng: 121.0215, + lat: 14.5995, + } + }; + }); + + const [mapViewport, setMapViewport] = useState({ + center: [formData.location.lng, formData.location.lat], + zoom: 12, + }); + + const handleInputChange = (e) => setFormData({ ...formData, [e.target.name]: e.target.value }); + + const handleAddressChange = (e) => setFormData({ + ...formData, + address: { ...formData.address, [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 handleSave = (e) => { + e.preventDefault(); + const dataToSave = { ...formData, idFile: null }; + localStorage.setItem('buyerProfile', JSON.stringify(dataToSave)); + setIsSaved(true); + setTimeout(() => setIsSaved(false), 3000); + }; + + const handleLogout = () => { + // Clear any auth tokens or user context here if they exist + navigate('/login'); + }; + + const initials = `${formData.firstName?.charAt(0) || ''}${formData.lastName?.charAt(0) || ''}`.toUpperCase() || 'U'; + + return ( + + {/* Header Banner */} + + + + + + + + {/* Left Sidebar Profile Summary */} + + + + {/* Avatar */} + + + + {initials} + + + + + + + + + + + + {formData.firstName || formData.lastName ? `${formData.firstName} ${formData.lastName}` : 'Guest User'} + + + Verified Buyer + + + + + + + + + + {formData.email || 'No email provided'} + + + + + + {formData.phone || 'No phone provided'} + + + + + + + + Sign Out Account + + + + + {/* Right Form Content */} + + + + {/* Personal Information */} + + + + + + Personal Details + + + + First Name + + + + Middle Name (Optional) + + + + Last Name + + + + Email Address + + + + Phone Number + + + + + + {/* Delivery Address & Location */} + + + + + + Delivery Address + + + + + Street Address + + + + + City / Municipality + + + + State / Province + + + + + ZIP / Postal Code + + + + + + + Pin Delivery Point + Drag pin to adjust + + + + + + + + + + Deliver Here + + + + + + + + {/* Verification Document */} + + + + + + Identity Verification + + + Valid Government ID + For secure transactions, we require a valid government-issued ID. + + + + + + + + + Click to upload + or drag and drop + handleFileChange(e, 'idFile')} /> + + + PNG, JPG, PDF up to 10MB + + {formData.idFile && ( + + + {formData.idFile.name} + + )} + + + + + + + + {isSaved ? ( + <> + Profile Updated + + > + ) : ( + <> + Save Changes + + > + )} + + + + + + + + ); +}; + +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 */} { + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + + const handleSubmit = (e) => { + e.preventDefault(); + // Handle login logic here + console.log('Login attempt', { email, password }); + }; + + return ( + + + {/* Decorative background elements */} + + + + + + + + + + + + Welcome Back + + + Sign in to continue your journey. + + + + + + + Email Address + + + setEmail(e.target.value)} + className="pl-10" + placeholder="name@example.com" + /> + + + + + + Password + + Forgot password? + + + + + setPassword(e.target.value)} + className="pl-10" + placeholder="••••••••" + /> + + + + + + Sign In + + + + + + 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. + + + + + Go to Dashboard + + + + + + ); + } + + 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 && ( + + + + First Name + + + + Middle Name + + + + Last Name + + + + + + Phone Number + + + + )} + + {/* Step 2: Store Basics */} + {step === 2 && ( + + + Store Name + + + + + Category + + + + + Store Description + + + + )} + + {/* Step 3: Location */} + {step === 3 && ( + + + + Street Address + + + + + City + + + + State / Province + + + + + ZIP / Postal Code + + + + + + + Pin Location + Drag pin to adjust + + + + + + + + Your Store + + + + + + + )} + + {/* Step 4: Documents */} + {step === 4 && ( + + + Business Permit + + + + + + Upload a file + handleFileChange(e, 'permitFile')} /> + + + PNG, JPG, PDF up to 10MB + {formData.permitFile && ( + + + {formData.permitFile.name} + + )} + + + + + + Valid Government ID + + + + + + Upload a file + handleFileChange(e, 'idFile')} /> + + + PNG, JPG, PDF up to 10MB + {formData.idFile && ( + + + {formData.idFile.name} + + )} + + + + + )} + + + {step > 1 && ( + + + Back + + )} + + {step < 4 ? ( + + Next Step + + + ) : ( + + Submit Application + + + )} + + + + + + + ); +}; + +export default SellerVerification; diff --git a/frontend/src/pages/shared/Signup.jsx b/frontend/src/pages/shared/Signup.jsx new file mode 100644 index 0000000..0fb2b16 --- /dev/null +++ b/frontend/src/pages/shared/Signup.jsx @@ -0,0 +1,192 @@ +import React, { useState } from 'react'; +import { Link } from 'react-router-dom'; +import { Mail, Lock, User, Store, ShoppingBag, ArrowRight } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; + +const Signup = () => { + const [role, setRole] = useState('buyer'); // 'buyer' or 'seller' + const [formData, setFormData] = useState({ + firstName: '', + middleName: '', + lastName: '', + email: '', + password: '', + }); + + const handleChange = (e) => { + setFormData({ ...formData, [e.target.name]: e.target.value }); + }; + + const handleSubmit = (e) => { + e.preventDefault(); + // Handle signup logic here + console.log('Signup attempt', { ...formData, role }); + }; + + return ( + + + {/* Decorative background elements */} + + + + + + + + + + + + Create an Account + + + Join Artisan Hub today. + + + + + + {/* Role Toggle */} + + setRole('buyer')} + className={`flex-1 flex items-center justify-center gap-2 py-2.5 text-xs font-bold font-sans rounded-lg transition-all duration-300 ${ + role === 'buyer' + ? 'bg-white shadow-sm text-foreground border border-border/50' + : 'text-muted-foreground hover:text-foreground hover:bg-white/50' + }`} + > + + Buyer + + setRole('seller')} + className={`flex-1 flex items-center justify-center gap-2 py-2.5 text-xs font-bold font-sans rounded-lg transition-all duration-300 ${ + role === 'seller' + ? 'bg-white shadow-sm text-foreground border border-border/50' + : 'text-muted-foreground hover:text-foreground hover:bg-white/50' + }`} + > + + Seller + + + + + + + First Name + + + + + + + Middle Name + + + + + + + + Last Name + + + + + + + + Email Address + + + + + + + + Password + + + + + Must be at least 8 characters. + + + + + Create {role === 'seller' ? 'Seller ' : ''}Account + + + + + + Already have an account?{' '} + + Sign in securely + + + + + + + + ); +}; + +export default Signup; \ No newline at end of file
+ Verified Buyer +
For secure transactions, we require a valid government-issued ID.
PNG, JPG, PDF up to 10MB
+ Sign in to continue your journey. +
+ Don't have an account?{' '} + + Create one now + +
+ 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. +
+ {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."} +
+ Join Artisan Hub today. +
Must be at least 8 characters.
+ Already have an account?{' '} + + Sign in securely + +