feat(guide): proper order sorting & hidden
This commit is contained in:
@@ -23,6 +23,7 @@ import { guides } from "@/lib/db/schema";
|
||||
export default async function GuideEditPage({
|
||||
params,
|
||||
}: PageProps<"/admin/guide/[id]">) {
|
||||
if (!(await adminCheck())) redirect("/login");
|
||||
const { id } = await params;
|
||||
const [guide] = await db.select().from(guides).where(eq(guides.id, id));
|
||||
if (!guide) notFound();
|
||||
|
||||
@@ -21,6 +21,7 @@ import { db } from "@/lib/db";
|
||||
import { guides } from "@/lib/db/schema";
|
||||
|
||||
export default async function GuideCreatePage() {
|
||||
if (!(await adminCheck())) redirect("/login");
|
||||
const [{ maxOrder }] = await db
|
||||
.select({
|
||||
maxOrder: sql<number>`
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
"use server";
|
||||
|
||||
import { eq, not } from "drizzle-orm";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { redirect } from "next/navigation";
|
||||
import { adminCheck } from "@/lib/auth";
|
||||
import { db } from "@/lib/db";
|
||||
import { guides } from "@/lib/db/schema";
|
||||
|
||||
export async function hideGuide(id: string) {
|
||||
if (!(await adminCheck())) redirect("/login");
|
||||
await db
|
||||
.update(guides)
|
||||
.set({
|
||||
hidden: not(guides.hidden),
|
||||
})
|
||||
.where(eq(guides.id, id));
|
||||
revalidatePath("/admin/guide");
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
import { Pencil, PlusIcon } from "lucide-react";
|
||||
import { EyeIcon, EyeOffIcon, Pencil, PlusIcon } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import Image from "@/components/image";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { searchGuide } from "../../guide/api";
|
||||
import { hideGuide } from "./api";
|
||||
|
||||
export default async function AdminGuidePage() {
|
||||
const list = await searchGuide();
|
||||
const list = await searchGuide("", true);
|
||||
|
||||
return (
|
||||
<div className="grow-0 flex flex-col pt-5 gap-2 mx-4">
|
||||
@@ -20,18 +22,25 @@ export default async function AdminGuidePage() {
|
||||
{list.map((card) => (
|
||||
<Card
|
||||
key={card.id}
|
||||
className="bg-card/50 hover:bg-border backdrop-blur-sm transition-colors py-3 sm:py-6 rounded-sm sm:rounded-xl group relative"
|
||||
className={cn(
|
||||
"bg-card/50 hover:bg-border backdrop-blur-sm transition-colors py-3 sm:py-6 rounded-sm sm:rounded-xl group relative",
|
||||
card.hidden && "opacity-70",
|
||||
)}
|
||||
>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="outline"
|
||||
className="absolute opacity-0 group-hover:opacity-100 transition-opacity top-0 right-0 m-2"
|
||||
asChild
|
||||
>
|
||||
<Link href={`/admin/guide/${card.id}`}>
|
||||
<Pencil />
|
||||
</Link>
|
||||
</Button>
|
||||
<div className="flex gap-1 absolute opacity-0 group-hover:opacity-100 transition-opacity top-0 right-0 m-2">
|
||||
<Button
|
||||
size="icon"
|
||||
variant="outline"
|
||||
onClick={hideGuide.bind(null, card.id)}
|
||||
>
|
||||
{card.hidden ? <EyeOffIcon /> : <EyeIcon />}
|
||||
</Button>
|
||||
<Button size="icon" variant="outline" asChild>
|
||||
<Link href={`/admin/guide/${card.id}`}>
|
||||
<Pencil />
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
<CardHeader className="px-3 sm:px-6">
|
||||
<CardTitle>{card.name}</CardTitle>
|
||||
<div className="relative w-full aspect-square mt-2 rounded-sm sm:rounded-lg border overflow-hidden">
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
"use server";
|
||||
|
||||
import { ilike } from "drizzle-orm";
|
||||
import { and, desc, ilike, not } from "drizzle-orm";
|
||||
import { db } from "@/lib/db";
|
||||
import { guides } from "@/lib/db/schema";
|
||||
|
||||
export async function searchGuide(search: string = "") {
|
||||
export async function searchGuide(search: string = "", admin = false) {
|
||||
return await db
|
||||
.select()
|
||||
.from(guides)
|
||||
.where(ilike(guides.name, `%${search}%`))
|
||||
.orderBy(guides.id);
|
||||
.where(
|
||||
and(
|
||||
ilike(guides.name, `%${search}%`),
|
||||
admin ? undefined : not(guides.hidden),
|
||||
),
|
||||
)
|
||||
.orderBy(desc(guides.order));
|
||||
}
|
||||
|
||||
@@ -2,6 +2,6 @@ import { searchGuide } from "./api";
|
||||
import { GuideList } from "./client";
|
||||
|
||||
export default async function GuidePage() {
|
||||
const initialData = await searchGuide();
|
||||
const initialData = await searchGuide("");
|
||||
return <GuideList initialList={initialData} />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user