mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-02-22 23:42:00 +00:00
109 lines
3.5 KiB
TypeScript
109 lines
3.5 KiB
TypeScript
|
"use client"
|
||
|
|
||
|
import * as React from "react"
|
||
|
|
||
|
import { Button } from "@/components/ui/button"
|
||
|
import {
|
||
|
Drawer,
|
||
|
DrawerClose,
|
||
|
DrawerContent,
|
||
|
DrawerDescription,
|
||
|
DrawerFooter,
|
||
|
DrawerHeader,
|
||
|
DrawerTitle,
|
||
|
DrawerTrigger,
|
||
|
} from "@/components/ui/drawer"
|
||
|
import { cartDrawerOpenAtom, deviceCartAtom } from "@/lib/atoms"
|
||
|
import type { Device } from "@prisma/client"
|
||
|
import { useAtom, useAtomValue, useSetAtom } from "jotai"
|
||
|
import { CircleDollarSign, ShoppingCart, Trash2 } from "lucide-react"
|
||
|
import Link from "next/link"
|
||
|
import { usePathname } from "next/navigation"
|
||
|
|
||
|
|
||
|
export function DeviceCartDrawer() {
|
||
|
const pathname = usePathname()
|
||
|
const devices = useAtomValue(deviceCartAtom)
|
||
|
const setDeviceCart = useSetAtom(deviceCartAtom)
|
||
|
const [isOpen, setIsOpen] = useAtom(cartDrawerOpenAtom)
|
||
|
if (pathname === "/payment") {
|
||
|
return null
|
||
|
}
|
||
|
return (
|
||
|
<Drawer open={isOpen} onOpenChange={setIsOpen}>
|
||
|
<DrawerTrigger asChild>
|
||
|
<Button
|
||
|
onClick={() => setIsOpen(!isOpen)}
|
||
|
variant="outline">
|
||
|
<ShoppingCart />
|
||
|
Cart {devices.length > 0 && `(${devices.length})`}
|
||
|
</Button>
|
||
|
</DrawerTrigger>
|
||
|
<DrawerContent>
|
||
|
<div className="mx-auto w-full max-w-sm">
|
||
|
<DrawerHeader>
|
||
|
<DrawerTitle>Cart Devices</DrawerTitle>
|
||
|
<DrawerDescription>Devices in your cart to pay.</DrawerDescription>
|
||
|
</DrawerHeader>
|
||
|
<div className="flex max-h-[calc(100svh-200px)] flex-col overflow-auto px-4 pb-4 gap-4">
|
||
|
{devices.map((device) => (
|
||
|
<DeviceCard key={device.id} device={device} />
|
||
|
))}
|
||
|
</div>
|
||
|
<DrawerFooter>
|
||
|
<Link aria-disabled={devices.length === 0} href={devices.length === 0 ? "#" : "/payment"}>
|
||
|
<Button
|
||
|
onClick={() => {
|
||
|
setIsOpen(!isOpen)
|
||
|
}}
|
||
|
className="w-full" disabled={devices.length === 0}>
|
||
|
Go to payment
|
||
|
<CircleDollarSign />
|
||
|
</Button>
|
||
|
</Link>
|
||
|
<DrawerClose asChild>
|
||
|
<Button variant="outline">Cancel</Button>
|
||
|
|
||
|
|
||
|
</DrawerClose>
|
||
|
<Button
|
||
|
onClick={() => {
|
||
|
setDeviceCart([])
|
||
|
}}
|
||
|
variant="outline">Reset Cart</Button>
|
||
|
</DrawerFooter>
|
||
|
</div>
|
||
|
</DrawerContent>
|
||
|
</Drawer>
|
||
|
)
|
||
|
}
|
||
|
|
||
|
|
||
|
function DeviceCard({ device }: { device: Device }) {
|
||
|
const setDeviceCart = useSetAtom(deviceCartAtom)
|
||
|
return (
|
||
|
<div className="relative flex h-full w-full items-center pr-4 justify-between rounded-lg border border-input bg-background shadow-sm shadow-black/5 transition-shadow focus-within:border-ring focus-within:outline-none focus-within:ring-[3px] focus-within:ring-ring/20 has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50 [&:has(input:is(:disabled))_*]:pointer-events-none">
|
||
|
<div>
|
||
|
|
||
|
<label htmlFor="input-33" className="block px-3 pt-2 text-xs font-medium text-foreground">
|
||
|
{device.name}
|
||
|
</label>
|
||
|
<input
|
||
|
className="flex h-10 w-full bg-transparent px-3 pb-2 text-sm text-foreground placeholder:text-muted-foreground/70 focus-visible:outline-none"
|
||
|
value={device.mac}
|
||
|
readOnly
|
||
|
placeholder={"MAC Address"}
|
||
|
/>
|
||
|
</div>
|
||
|
|
||
|
<Button
|
||
|
onClick={() => {
|
||
|
setDeviceCart((prev) => prev.filter((d) => d.id !== device.id))
|
||
|
}}
|
||
|
variant={"destructive"}>
|
||
|
Remove
|
||
|
<Trash2 />
|
||
|
</Button>
|
||
|
</div>
|
||
|
)
|
||
|
}
|