98 lines
3.7 KiB
TypeScript
98 lines
3.7 KiB
TypeScript
"use client"
|
||
|
||
import { useState } from "react"
|
||
import { Checkbox } from "./ui/checkbox"
|
||
import { Button } from "./ui/button"
|
||
import { Minus, Plus, Heart, Trash } from "lucide-react"
|
||
import Image from "next/image"
|
||
import { useCart } from "@/contexts/cart-context"
|
||
import { useFavorites } from "@/contexts/favorites-context"
|
||
import Link from "next/link"
|
||
|
||
export function CartItems() {
|
||
const { items, removeFromCart, addToCart, removeAllFromCart, updateQuantity, getTotalQuantity } = useCart()
|
||
const { addToFavorites, removeFromFavorites, isFavorite } = useFavorites()
|
||
const [selectedItems, setSelectedItems] = useState<number[]>([])
|
||
|
||
const toggleItem = (id: number) => {
|
||
setSelectedItems((prev) => (prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]))
|
||
}
|
||
|
||
const handleToggleFavorite = (item: (typeof items)[0]) => {
|
||
if (isFavorite(item.id)) {
|
||
removeFromFavorites(item.id)
|
||
} else {
|
||
addToFavorites(item)
|
||
}
|
||
}
|
||
|
||
const handleUpdateQuantity = (id: number, newQuantity: number) => {
|
||
updateQuantity(id, newQuantity)
|
||
}
|
||
|
||
return (
|
||
<div className="space-y-4">
|
||
<div className="mb-4">
|
||
<span className="font-semibold">Всего товаров: {getTotalQuantity()}</span>
|
||
</div>
|
||
<div className="flex items-center gap-2 mb-4">
|
||
<Checkbox
|
||
checked={selectedItems.length === items.length}
|
||
onCheckedChange={(checked) => {
|
||
setSelectedItems(checked ? items.map((item) => item.id) : [])
|
||
}}
|
||
/>
|
||
<span>Выбрать все</span>
|
||
{selectedItems.length > 0 && <button className="text-red-500 ml-4 hover:underline">Удалить выбранные</button>}
|
||
</div>
|
||
{items.map((item) => (
|
||
<div key={item.id} className="flex gap-4 p-4 bg-white rounded-lg">
|
||
<Checkbox checked={selectedItems.includes(item.id)} onCheckedChange={() => toggleItem(item.id)} />
|
||
<Link href={`/product/${item.id}`} className="flex-grow flex gap-4">
|
||
<Image
|
||
src={item.image || "/placeholder.svg"}
|
||
alt={item.title}
|
||
width={100}
|
||
height={100}
|
||
className="object-cover"
|
||
/>
|
||
<div className="flex-1">
|
||
<h3 className="font-medium">{item.title}</h3>
|
||
<div className="flex gap-4 mt-4">
|
||
<div className="flex items-center gap-2">
|
||
<Button
|
||
variant="outline"
|
||
size="icon"
|
||
onClick={() => handleUpdateQuantity(item.id, item.quantity - 1)}
|
||
>
|
||
<Minus className="h-4 w-4" />
|
||
</Button>
|
||
<span className="w-8 text-center">{item.quantity}</span>
|
||
<Button
|
||
variant="outline"
|
||
size="icon"
|
||
onClick={() => handleUpdateQuantity(item.id, item.quantity + 1)}
|
||
>
|
||
<Plus className="h-4 w-4" />
|
||
</Button>
|
||
</div>
|
||
<Button variant="ghost" size="icon" onClick={() => handleToggleFavorite(item)}>
|
||
<Heart className={`h-4 w-4 ${isFavorite(item.id) ? "fill-red-500 text-red-500" : ""}`} />
|
||
</Button>
|
||
<Button variant="ghost" size="icon" onClick={() => removeAllFromCart(item.id)}>
|
||
<Trash className="h-4 w-4" />
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</Link>
|
||
<div className="text-right">
|
||
<div className="text-lg font-bold">{item.price * item.quantity} ₽</div>
|
||
<div className="text-sm text-muted-foreground">{item.price} ₽ за шт.</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
)
|
||
}
|
||
|