252 lines
9.5 KiB
TypeScript
252 lines
9.5 KiB
TypeScript
import { Store, Plus, MapPin, Phone, Mail, ExternalLink, Share2, Copy, ChevronRight, Sparkles } from "lucide-react";
|
|
import { Button } from "../../ui/button";
|
|
import { Card } from "../../ui/card";
|
|
import { Badge } from "../../ui/badge";
|
|
import { Separator } from "../../ui/separator";
|
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "../../ui/dialog";
|
|
import { Input } from "../../ui/input";
|
|
import { Label } from "../../ui/label";
|
|
import { useState } from "react";
|
|
import { toast } from "sonner@2.0.3";
|
|
import { copyWithToast } from "../../utils/clipboard";
|
|
|
|
interface MyRetailersScreenProps {
|
|
onBack: () => void;
|
|
onViewStore: (retailerId: string) => void;
|
|
}
|
|
|
|
const connectedRetailers = [
|
|
{
|
|
id: "1",
|
|
name: "Nova Jewels",
|
|
location: "Mumbai, Maharashtra",
|
|
phone: "+91 98765 43210",
|
|
email: "hello@novajewels.com",
|
|
associate: "Priya Sharma",
|
|
theme: "elegant",
|
|
connectedDate: "Jan 2025",
|
|
status: "active",
|
|
},
|
|
{
|
|
id: "2",
|
|
name: "Sparkle Gems",
|
|
location: "Delhi, NCR",
|
|
phone: "+91 98111 22333",
|
|
email: "contact@sparklegems.com",
|
|
associate: "Amit Kumar",
|
|
theme: "modern",
|
|
connectedDate: "Dec 2024",
|
|
status: "active",
|
|
},
|
|
{
|
|
id: "3",
|
|
name: "Golden Heritage",
|
|
location: "Jaipur, Rajasthan",
|
|
phone: "+91 98444 55666",
|
|
email: "info@goldenheritage.com",
|
|
associate: "Rajesh Verma",
|
|
theme: "royal",
|
|
connectedDate: "Nov 2024",
|
|
status: "active",
|
|
},
|
|
];
|
|
|
|
const DEMO_CODE = "NOVA2025";
|
|
|
|
export function MyRetailersScreen({ onBack, onViewStore }: MyRetailersScreenProps) {
|
|
const [showAddDialog, setShowAddDialog] = useState(false);
|
|
const [showDemoCodeDialog, setShowDemoCodeDialog] = useState(false);
|
|
const [inviteCode, setInviteCode] = useState("");
|
|
|
|
const handleCopyCode = async () => {
|
|
await copyWithToast(DEMO_CODE, "Demo code copied!");
|
|
};
|
|
|
|
const handleAddRetailer = () => {
|
|
if (inviteCode.trim()) {
|
|
toast.success(`Connecting to retailer with code: ${inviteCode}`);
|
|
setShowAddDialog(false);
|
|
setInviteCode("");
|
|
} else {
|
|
toast.error("Please enter an invite code");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="h-full bg-bg-page flex flex-col">
|
|
{/* Header */}
|
|
<div className="bg-gradient-to-br from-primary/5 to-secondary/5 border-b border-border px-4 py-4">
|
|
<div className="flex items-center justify-between mb-1">
|
|
<button onClick={onBack} className="text-[14px] text-primary">
|
|
← Back
|
|
</button>
|
|
<Button size="sm" className="bg-secondary text-secondary-foreground hover:bg-secondary/90" onClick={() => setShowDemoCodeDialog(true)}>
|
|
<Sparkles className="w-4 h-4 mr-1" />
|
|
Demo Code
|
|
</Button>
|
|
</div>
|
|
<h1 className="text-[24px] leading-[32px]">My Retailers</h1>
|
|
<p className="text-[13px] text-muted-foreground">
|
|
{connectedRetailers.length} store{connectedRetailers.length !== 1 ? 's' : ''} connected
|
|
</p>
|
|
</div>
|
|
|
|
{/* Content */}
|
|
<div className="flex-1 overflow-y-auto p-4">
|
|
<div className="space-y-4">
|
|
{/* Add New Retailer Card */}
|
|
<button
|
|
onClick={() => setShowAddDialog(true)}
|
|
className="w-full p-4 rounded-lg border-2 border-dashed border-border hover:border-primary hover:bg-accent/5 transition-all"
|
|
>
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-12 h-12 rounded-full bg-primary/10 flex items-center justify-center">
|
|
<Plus className="w-6 h-6 text-primary" />
|
|
</div>
|
|
<div className="flex-1 text-left">
|
|
<p className="text-[14px] font-medium">Connect New Retailer</p>
|
|
<p className="text-[12px] text-muted-foreground">Enter invite code to connect</p>
|
|
</div>
|
|
<ChevronRight className="w-5 h-5 text-muted-foreground" />
|
|
</div>
|
|
</button>
|
|
|
|
{/* Connected Retailers */}
|
|
{connectedRetailers.map((retailer) => (
|
|
<Card key={retailer.id} className="p-4">
|
|
<div className="flex items-start gap-3 mb-3">
|
|
<div className="w-12 h-12 rounded-lg bg-gradient-to-br from-primary/20 to-secondary/20 flex items-center justify-center flex-shrink-0">
|
|
<Store className="w-6 h-6 text-primary" />
|
|
</div>
|
|
<div className="flex-1 min-w-0">
|
|
<div className="flex items-start justify-between gap-2 mb-1">
|
|
<h3 className="text-[16px] font-medium">{retailer.name}</h3>
|
|
<Badge variant="outline" className="text-[10px] bg-accent-positive/10 text-accent-positive border-accent-positive/20">
|
|
Active
|
|
</Badge>
|
|
</div>
|
|
<div className="flex items-center gap-1 text-[12px] text-muted-foreground mb-1">
|
|
<MapPin className="w-3 h-3" />
|
|
<span>{retailer.location}</span>
|
|
</div>
|
|
<p className="text-[11px] text-muted-foreground">
|
|
Your contact: {retailer.associate}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<Separator className="my-3" />
|
|
|
|
<div className="space-y-2 text-[12px]">
|
|
<div className="flex items-center gap-2 text-muted-foreground">
|
|
<Phone className="w-3.5 h-3.5" />
|
|
<span>{retailer.phone}</span>
|
|
</div>
|
|
<div className="flex items-center gap-2 text-muted-foreground">
|
|
<Mail className="w-3.5 h-3.5" />
|
|
<span>{retailer.email}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<Separator className="my-3" />
|
|
|
|
<div className="flex gap-2">
|
|
<Button
|
|
size="sm"
|
|
className="flex-1"
|
|
onClick={() => onViewStore(retailer.id)}
|
|
>
|
|
<Store className="w-4 h-4 mr-1" />
|
|
View Store
|
|
</Button>
|
|
<Button size="sm" variant="outline" className="flex-1">
|
|
<Phone className="w-4 h-4 mr-1" />
|
|
Contact
|
|
</Button>
|
|
</div>
|
|
|
|
<p className="text-[10px] text-muted-foreground text-center mt-2">
|
|
Connected since {retailer.connectedDate}
|
|
</p>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Add Retailer Dialog */}
|
|
<Dialog open={showAddDialog} onOpenChange={setShowAddDialog}>
|
|
<DialogContent className="max-w-[340px]">
|
|
<DialogHeader>
|
|
<DialogTitle>Connect to Retailer</DialogTitle>
|
|
<DialogDescription>
|
|
Enter the invite code provided by your jeweller
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<div className="space-y-4">
|
|
<div className="space-y-2">
|
|
<Label htmlFor="invite-code">Invite Code</Label>
|
|
<Input
|
|
id="invite-code"
|
|
placeholder="e.g., NOVA2025"
|
|
value={inviteCode}
|
|
onChange={(e) => setInviteCode(e.target.value.toUpperCase())}
|
|
className="text-center tracking-wider"
|
|
/>
|
|
<p className="text-[11px] text-muted-foreground">
|
|
💡 Ask your jeweller for their unique invite code
|
|
</p>
|
|
</div>
|
|
|
|
<div className="flex gap-3">
|
|
<Button variant="outline" onClick={() => setShowAddDialog(false)} className="flex-1">
|
|
Cancel
|
|
</Button>
|
|
<Button onClick={handleAddRetailer} className="flex-1">
|
|
Connect
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
|
|
{/* Demo Code Dialog */}
|
|
<Dialog open={showDemoCodeDialog} onOpenChange={setShowDemoCodeDialog}>
|
|
<DialogContent className="max-w-[340px]">
|
|
<DialogHeader>
|
|
<DialogTitle className="flex items-center gap-2">
|
|
<Sparkles className="w-5 h-5 text-secondary" />
|
|
Demo Retailer Code
|
|
</DialogTitle>
|
|
<DialogDescription>
|
|
Use this code to connect to Nova Jewels demo store
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<div className="space-y-4">
|
|
<div className="p-5 rounded-lg bg-gradient-to-br from-primary/10 to-secondary/10 border-2 border-primary/20 text-center">
|
|
<p className="text-[10px] text-muted-foreground uppercase tracking-wider mb-2">INVITE CODE</p>
|
|
<p className="text-[32px] font-mono tracking-widest font-medium text-primary">{DEMO_CODE}</p>
|
|
</div>
|
|
|
|
<Button className="w-full" onClick={handleCopyCode}>
|
|
<Copy className="w-4 h-4 mr-2" />
|
|
Copy Code
|
|
</Button>
|
|
|
|
<div className="p-4 rounded-lg bg-secondary/5 border border-secondary/20">
|
|
<div className="flex items-start gap-2">
|
|
<Sparkles className="w-4 h-4 text-secondary mt-0.5 flex-shrink-0" />
|
|
<div className="text-[11px] text-muted-foreground">
|
|
<p className="font-medium text-foreground mb-1">How to use:</p>
|
|
<p>Tap "Connect New Retailer" above and paste this code to instantly connect to our demo store with sample jewellery collections.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</div>
|
|
);
|
|
}
|