1
2// File: apps/koyo/lib/icecreamOrder/IcecreamOrder.Zone.tsx
3"use client";
4import { Model } from "@akanjs/ui";
5
6// ... existing code ...
7
8interface CardProps {
9 className?: string;
10 init: ClientInit<"icecreamOrder", cnst.LightIcecreamOrder>;
11}
12export const Card = ({ className, init }: CardProps) => {
13 return (
14 <>
15 <Load.Units
16 className={className}
17 init={init}
18 renderItem={(icecreamOrder: cnst.LightIcecreamOrder) => (
19 <IcecreamOrder.Unit.Card
20 key={icecreamOrder.id}
21 href={`/icecreamOrder/${icecreamOrder.id}`}
22 icecreamOrder={icecreamOrder}
23 />
24 )}
25 />
26 <Model.ViewEditModal
27 sliceName="icecreamOrderInPublic"
28 renderTitle={(icecreamOrder: DefaultOf<cnst.IcecreamOrder>) =>
29 `IcecreamOrder - ${icecreamOrder.id ? icecreamOrder.id : "New"}`
30 }
31 renderView={(icecreamOrder: cnst.IcecreamOrder) => (
32 <IcecreamOrder.View.General className="w-full" icecreamOrder={icecreamOrder} />
33 )}
34 renderTemplate={() => <IcecreamOrder.Template.General />}
35 />
36 </>
37 );
38};
1
2// File: apps/koyo/lib/icecreamOrder/IcecreamOrder.Unit.tsx
3import { clsx, ModelProps } from "@akanjs/client";
4import { Model } from "@akanjs/ui";
5import { cnst, usePage } from "@koyo/client";
6
7export const Card = ({ icecreamOrder }: ModelProps<"icecreamOrder", cnst.LightIcecreamOrder>) => {
8 const { l } = usePage();
9 return (
10 <div className="group flex h-36 w-full overflow-hidden rounded-xl bg-gradient-to-br from-pink-100 via-yellow-50 to-pink-200 px-8 py-6 shadow-md transition-all duration-300 hover:shadow-xl">
11 <div className="flex w-full flex-col justify-center">
12 <div className="flex items-center gap-2 text-lg font-semibold text-pink-700">
13 <span className="inline-block rounded bg-pink-200 px-2 py-1 text-xs font-bold tracking-wider uppercase">
14 {l.field("icecreamOrder", "id")}
15 </span>
16 <span className="ml-2 font-mono text-pink-900">{icecreamOrder.id}</span>
17 </div>
18 <div className="mt-4 flex items-center gap-2">
19 <span className="inline-block rounded bg-yellow-200 px-2 py-1 text-xs font-bold tracking-wider text-yellow-800 uppercase">
20 {l.field("icecreamOrder", "status")}
21 </span>
22 <span
23 className={clsx("ml-2 rounded-full px-3 py-1 text-sm font-semibold", {
24 "bg-green-100 text-green-700": icecreamOrder.status === "active",
25 "bg-blue-100 text-blue-700": icecreamOrder.status === "processing",
26 "bg-red-100 text-red-700": icecreamOrder.status === "served",
27 "bg-gray-100 text-gray-700": icecreamOrder.status === "canceled",
28 })}
29 >
30 {l.enum("icecreamOrder", "status", icecreamOrder.status)}
31 </span>
32 </div>
33 </div>
34 <div className="bg-base-100/50 flex items-center justify-center gap-2 rounded-xl p-4">
35 <Model.ViewWrapper sliceName="icecreamOrder" modelId={icecreamOrder.id}>
36 <button className="btn btn-primary">
37 <span>{l.trans({ en: "View", ko: "보기" })}</span>
38 </button>
39 </Model.ViewWrapper>
40 </div>
41 </div>
42 );
43};
1// File: apps/koyo/lib/icecreamOrder/IcecreamOrder.View.tsx
2import { clsx } from "@akanjs/client";
3import { cnst, usePage } from "@koyo/client";
4
5interface IcecreamOrderViewProps {
6 className?: string;
7 icecreamOrder: cnst.IcecreamOrder;
8}
9
10export const General = ({ className, icecreamOrder }: IcecreamOrderViewProps) => {
11 const { l } = usePage();
12 return (
13 <div className={clsx(className, "mx-auto w-full space-y-6 rounded-xl p-8 shadow-lg")}>
14 {/* Header with icon and title */}
15 <div className="flex items-center gap-3 border-b pb-4">
16 <span className="text-3xl font-extrabold text-pink-600">🍦</span>
17 <span className="text-2xl font-bold">{l("icecreamOrder.modelName")}</span>
18 <span className="ml-auto text-xs text-base-content/50">#{icecreamOrder.id}</span>
19 </div>
20
21 {/* Order details in a grid layout */}
22 <div className="grid grid-cols-2 gap-x-6 gap-y-4">
23 {/* Size information */}
24 <div className="font-semibold text-base-content/50">{l.field("icecreamOrder", "size")}</div>
25 <div>{l.enum("icecreamOrder", "size", icecreamOrder.size.toString())}</div>
26
27 {/* Toppings information */}
28 <div className="font-semibold text-base-content/50">{l.field("icecreamOrder", "toppings")}</div>
29 <div className="flex flex-wrap gap-2">
30 {icecreamOrder.toppings.length === 0 ? (
31 <span className="italic text-gray-400">
32 {l.trans({ en: "No toppings", ko: "토핑 없음" })}
33 </span>
34 ) : (
35 icecreamOrder.toppings.map((topping) => (
36 <span
37 key={topping}
38 className="inline-block rounded-full bg-pink-100 px-2 py-1 text-xs font-medium text-pink-700"
39 >
40 {l.enum("icecreamOrder", "toppings", topping)}
41 </span>
42 ))
43 )}
44 </div>
45
46 {/* Status information */}
47 <div className="font-semibold text-base-content/50">{l.field("icecreamOrder", "status")}</div>
48 <div>
49 <span
50 className={clsx("inline-block rounded-full px-2 py-1 text-xs font-semibold", {
51 "bg-green-100 text-green-700": icecreamOrder.status === "active",
52 "bg-yellow-100 text-yellow-700": icecreamOrder.status === "processing",
53 "bg-red-100 text-red-700": icecreamOrder.status === "served",
54 "bg-gray-100 text-gray-700": icecreamOrder.status === "canceled",
55 })}
56 >
57 {l.enum("icecreamOrder", "status", icecreamOrder.status)}
58 </span>
59 </div>
60
61 {/* Timestamps */}
62 <div className="font-semibold text-base-content/50">{l.field("icecreamOrder", "createdAt")}</div>
63 <div className="text-gray-500">{icecreamOrder.createdAt.format("YYYY-MM-DD HH:mm:ss")}</div>
64
65 <div className="font-semibold text-base-content/50">{l.field("icecreamOrder", "updatedAt")}</div>
66 <div className="text-gray-500">{icecreamOrder.updatedAt.format("YYYY-MM-DD HH:mm:ss")}</div>
67 </div>
68 </div>
69 );
70};