LocationsView.tsx 9.58 KB
import React, { useState } from 'react';
import { 
  Search, 
  Plus, 
  Download, 
  Upload, 
  Edit, 
  MapPin, 
  Phone, 
  Mail, 
  MoreHorizontal 
} from 'lucide-react';
import { Button } from "../ui/button";
import { Input } from "../ui/input";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "../ui/table";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "../ui/dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "../ui/select";
import { Label } from "../ui/label";
import { Badge } from "../ui/badge";
import { Switch } from "../ui/switch";

// --- Mock Data ---

const MOCK_LOCATIONS = [
  { 
    id: '12345', 
    name: 'Downtown Store', 
    address: '123 Main St, New York, NY', 
    phone: '+1 (555) 123-4567', 
    email: 'downtown@example.com', 
    gps: '40.7128° N, 74.0060° W',
    status: 'active'
  },
  { 
    id: '12335', 
    name: 'Uptown Market', 
    address: '456 High St, New York, NY', 
    phone: '+1 (555) 987-6543', 
    email: 'uptown@example.com', 
    gps: '40.7580° N, 73.9855° W',
    status: 'active'
  },
  { 
    id: '12445', 
    name: 'Airport Kiosk', 
    address: 'Terminal 4, JFK Airport', 
    phone: '+1 (555) 555-5555', 
    email: 'jfk@example.com', 
    gps: '40.6413° N, 73.7781° W',
    status: 'active'
  },
  { 
    id: '12555', 
    name: 'Suburban Outlet', 
    address: '789 Country Rd, Long Island', 
    phone: '+1 (555) 111-2222', 
    email: 'suburb@example.com', 
    gps: '40.8500° N, 73.2000° W',
    status: 'inactive'
  },
];

export function LocationsView() {
  const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);
  const [locations, setLocations] = useState(MOCK_LOCATIONS);

  return (
    <div className="h-full flex flex-col bg-white">
      {/* Header / Top Bar:无白色背景,与 Labels 一致仅依赖 Layout p-8 外边距 */}
      <div className="border-b border-gray-200 py-4 bg-gray-50">
        <div className="flex flex-nowrap items-center gap-2 overflow-x-auto min-w-0">
          <Input
            placeholder="Search"
            className="border border-black rounded-lg h-9 w-32 shrink-0 bg-white text-black"
          />
          <Select defaultValue="partner-a">
            <SelectTrigger className="w-[140px] h-9 rounded-lg border border-black bg-white font-medium text-black shrink-0">
              <SelectValue placeholder="Partner" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="partner-a">Partner A</SelectItem>
            </SelectContent>
          </Select>
          <Select defaultValue="group-b">
            <SelectTrigger className="w-[140px] h-9 rounded-lg border border-black bg-white font-medium text-black shrink-0">
              <SelectValue placeholder="Group" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="group-b">Group B</SelectItem>
            </SelectContent>
          </Select>
          <Select defaultValue="all">
            <SelectTrigger className="w-[140px] h-9 rounded-lg border border-black bg-white font-medium text-black shrink-0">
              <SelectValue placeholder="Location" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All Locations</SelectItem>
              <SelectItem value="loc-1">Location 1</SelectItem>
            </SelectContent>
          </Select>
          <div className="flex-1 min-w-0" />
          <Button variant="outline" className="h-9 border border-black rounded-lg text-black px-4 bg-white hover:bg-gray-50 shrink-0">
            Bulk Import
          </Button>
          <Button variant="outline" className="h-9 border border-black rounded-lg text-black px-4 bg-white hover:bg-gray-50 shrink-0">
            Bulk Export
          </Button>
          <Button variant="outline" className="h-9 border border-black rounded-lg text-black px-4 bg-white hover:bg-gray-50 shrink-0">
            Bulk Edit
          </Button>
          <Button
            className="h-9 bg-blue-600 hover:bg-blue-700 text-white rounded-lg px-6 font-medium border-0 shrink-0"
            onClick={() => setIsCreateDialogOpen(true)}
          >
            New+
          </Button>
        </div>
      </div>

      {/* Content Area:上下左右间距与 Labels 一致(由 Layout main p-8 控制) */}
      <div className="flex-1 overflow-auto bg-gray-50">
        <div className="bg-white border border-gray-200 shadow-sm rounded-sm overflow-hidden">
          <Table>
            <TableHeader>
              <TableRow className="bg-gray-100 hover:bg-gray-100">
                <TableHead className="text-gray-900 font-bold border-r">Location ID</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">Location Name</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">Address</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">Phone</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">Email</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">GPS</TableHead>
                <TableHead className="text-gray-900 font-bold text-center">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {locations.map((loc) => (
                <TableRow key={loc.id}>
                  <TableCell className="border-r font-mono text-gray-600">{loc.id}</TableCell>
                  <TableCell className="border-r font-medium text-black">{loc.name}</TableCell>
                  <TableCell className="border-r text-gray-600 truncate max-w-[200px]">{loc.address}</TableCell>
                  <TableCell className="border-r text-gray-600 whitespace-nowrap">{loc.phone}</TableCell>
                  <TableCell className="border-r text-gray-600 text-sm">{loc.email}</TableCell>
                  <TableCell className="border-r text-gray-500 font-mono text-xs">{loc.gps}</TableCell>
                  <TableCell className="text-center">
                     <Button variant="ghost" size="icon" className="h-8 w-8">
                       <MoreHorizontal className="h-4 w-4 text-gray-500" />
                     </Button>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </div>
      </div>

      <CreateLocationDialog open={isCreateDialogOpen} onOpenChange={setIsCreateDialogOpen} />
    </div>
  );
}

// --- Sub-components ---

function CreateLocationDialog({ open, onOpenChange }: { open: boolean; onOpenChange: (open: boolean) => void }) {
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[600px]">
        <DialogHeader>
          <DialogTitle>Add New Location</DialogTitle>
          <DialogDescription>
            Enter the details for the new store location.
          </DialogDescription>
        </DialogHeader>
        
        <div className="grid gap-4 py-4">
          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label>Partner</Label>
              <Select defaultValue="partner-a">
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="partner-a">Partner A</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label>Group</Label>
              <Select defaultValue="group-b">
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="group-b">Group B</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>

          <div className="grid grid-cols-3 gap-4">
             <div className="space-y-2 col-span-1">
              <Label>Location ID</Label>
              <Input placeholder="e.g. 12345" />
            </div>
            <div className="space-y-2 col-span-2">
              <Label>Location Name</Label>
              <Input placeholder="e.g. Downtown Store" />
            </div>
          </div>

          <div className="space-y-2">
            <Label>Address</Label>
            <Input placeholder="Full street address" />
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label>Phone Number</Label>
              <Input placeholder="+1 (555) 000-0000" />
            </div>
            <div className="space-y-2">
              <Label>Email</Label>
              <Input placeholder="store@example.com" />
            </div>
          </div>

          <div className="space-y-2">
            <Label className="flex items-center gap-2">
              <MapPin className="w-4 h-4" /> GPS Coordinates
            </Label>
            <div className="grid grid-cols-2 gap-4">
              <Input placeholder="Latitude (e.g. 40.7128)" />
              <Input placeholder="Longitude (e.g. -74.0060)" />
            </div>
          </div>

           <div className="flex items-center gap-2 pt-2">
            <Switch id="loc-status" defaultChecked />
            <Label htmlFor="loc-status">Active Location</Label>
          </div>

        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>Cancel</Button>
          <Button onClick={() => onOpenChange(false)} className="bg-blue-600 text-white hover:bg-blue-700">Create Location</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}