Изображения в услугах, поиске, возможность открыть карточку услуги
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { getMyOffers, Offer } from "@/shared/api/catalog";
|
||||
import { getMyOffers, Offer, toggleOffer, deleteOffer } from "@/shared/api/catalog";
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { toast } from "sonner";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { PlusCircle, Loader2, Pencil, Trash2, PauseCircle, PlayCircle } from "lucide-react";
|
||||
import { PlusCircle, Loader2, Pencil, Trash2, PauseCircle, PlayCircle, Image as ImageIcon } from "lucide-react";
|
||||
import { useSessionStore } from "@/entities/session/store";
|
||||
|
||||
export default function MyOffersPage() {
|
||||
@@ -42,6 +42,27 @@ export default function MyOffersPage() {
|
||||
fetchOffers();
|
||||
}, [isAuth, user, router]);
|
||||
|
||||
const handleToggle = async (id: string) => {
|
||||
try {
|
||||
const newStatus = await toggleOffer(id);
|
||||
setOffers(offers.map(o => o.id === id ? { ...o, isActive: newStatus } : o));
|
||||
toast.success(newStatus ? "Услуга активирована" : "Услуга приостановлена");
|
||||
} catch {
|
||||
toast.error("Не удалось изменить статус услуги");
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
if (!confirm("Вы уверены, что хотите удалить эту услугу?")) return;
|
||||
try {
|
||||
await deleteOffer(id);
|
||||
setOffers(offers.filter(o => o.id !== id));
|
||||
toast.success("Услуга удалена");
|
||||
} catch {
|
||||
toast.error("Не удалось удалить услугу");
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex justify-center items-center h-48">
|
||||
@@ -104,6 +125,11 @@ export default function MyOffersPage() {
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className={`flex-1 ${!offer.isActive && "opacity-70 grayscale"}`}>
|
||||
{offer.images && offer.images.length > 0 && (
|
||||
<div className="w-full h-32 mb-4 rounded-md bg-muted overflow-hidden relative">
|
||||
<img src={offer.images[0]} className="w-full h-full object-cover" alt="Primary image" />
|
||||
</div>
|
||||
)}
|
||||
<p className="text-sm text-foreground/80 line-clamp-3 mb-4 leading-relaxed">
|
||||
{offer.description}
|
||||
</p>
|
||||
@@ -115,19 +141,21 @@ export default function MyOffersPage() {
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter className="flex gap-2 justify-end bg-muted/20 pt-4 mt-auto border-t">
|
||||
<Button variant="outline" size="sm" className="group flex items-center gap-0 overflow-hidden px-2 hover:px-3 hover:bg-primary/10 border-transparent hover:border-primary/20 text-muted-foreground hover:text-primary transition-all duration-300 ease-out">
|
||||
<Pencil className="h-4 w-4 shrink-0" />
|
||||
<span className="max-w-0 overflow-hidden whitespace-nowrap opacity-0 group-hover:max-w-[120px] group-hover:opacity-100 group-hover:ml-2 transition-all duration-300 ease-out">
|
||||
Редактировать
|
||||
</span>
|
||||
</Button>
|
||||
<Button variant="outline" size="sm" className="group flex items-center gap-0 overflow-hidden px-2 hover:px-3 hover:bg-orange-500/10 border-transparent hover:border-orange-500/20 text-muted-foreground hover:text-orange-500 transition-all duration-300 ease-out" onClick={() => toast.info("Функция паузы в разработке")}>
|
||||
<Link href={`/dashboard/offers/${offer.id}/edit`}>
|
||||
<Button variant="outline" size="sm" className="group flex items-center gap-0 overflow-hidden px-2 hover:px-3 hover:bg-primary/10 border-transparent hover:border-primary/20 text-muted-foreground hover:text-primary transition-all duration-300 ease-out">
|
||||
<Pencil className="h-4 w-4 shrink-0" />
|
||||
<span className="max-w-0 overflow-hidden whitespace-nowrap opacity-0 group-hover:max-w-[120px] group-hover:opacity-100 group-hover:ml-2 transition-all duration-300 ease-out">
|
||||
Редактировать
|
||||
</span>
|
||||
</Button>
|
||||
</Link>
|
||||
<Button variant="outline" size="sm" className="group flex items-center gap-0 overflow-hidden px-2 hover:px-3 hover:bg-orange-500/10 border-transparent hover:border-orange-500/20 text-muted-foreground hover:text-orange-500 transition-all duration-300 ease-out" onClick={() => handleToggle(offer.id)}>
|
||||
{offer.isActive ? <PauseCircle className="h-4 w-4 shrink-0" /> : <PlayCircle className="h-4 w-4 shrink-0" />}
|
||||
<span className="max-w-0 overflow-hidden whitespace-nowrap opacity-0 group-hover:max-w-[120px] group-hover:opacity-100 group-hover:ml-2 transition-all duration-300 ease-out">
|
||||
{offer.isActive ? "Приостановить" : "Активировать"}
|
||||
</span>
|
||||
</Button>
|
||||
<Button variant="outline" size="sm" className="group flex items-center gap-0 overflow-hidden px-2 hover:px-3 hover:bg-destructive/10 border-transparent hover:border-destructive/20 text-muted-foreground hover:text-destructive transition-all duration-300 ease-out" onClick={() => toast.info("Функция удаления в разработке")}>
|
||||
<Button variant="outline" size="sm" className="group flex items-center gap-0 overflow-hidden px-2 hover:px-3 hover:bg-destructive/10 border-transparent hover:border-destructive/20 text-muted-foreground hover:text-destructive transition-all duration-300 ease-out" onClick={() => handleDelete(offer.id)}>
|
||||
<Trash2 className="h-4 w-4 shrink-0" />
|
||||
<span className="max-w-0 overflow-hidden whitespace-nowrap opacity-0 group-hover:max-w-[100px] group-hover:opacity-100 group-hover:ml-2 transition-all duration-300 ease-out">
|
||||
Удалить
|
||||
|
||||
Reference in New Issue
Block a user