diff --git a/components/gallery/thumbnail.tsx b/components/gallery/thumbnail.tsx index 046a0cb..7c09565 100644 --- a/components/gallery/thumbnail.tsx +++ b/components/gallery/thumbnail.tsx @@ -18,7 +18,7 @@ import SmoothImage from "@/components/ui/smooth-image" * @param props.art Art piece to render in the gallery thumbnail * */ -export default function Thumbnail(props: { art: Art, onClick: () => void}) { +export default function Thumbnail(props: { art: Art, onClick: () => void }) { const [isClient, setIsClient] = useState(false); useEffect(() => { setIsClient(true); @@ -31,7 +31,7 @@ export default function Thumbnail(props: { art: Art, onClick: () => void}) { (orientation === Orientation.Horizontal ? colSpan : 1) * colWidth; const imgHeight = imgWidth / aspect(width, height); return ( -
+
{isClient ? ( void }) { - const { image, title } = props.art; + const { image, title, listPrice, status } = props.art; + const isAvailable = status === Status.Available; const { width, height } = useWindowSize(); + let statusText = "Unavailable"; + switch (status) { + case Status.Sold: + statusText = "Sold"; + break; + case Status.Private: + statusText = "Private Collection"; + break; + case Status.Available: + statusText = "Available"; + break; + case Status.Exhibiting: + statusText = "Exhibiting"; + } + + // render sales info for when painting is available + const salesInfo = (<> + S$${listPrice} + + ); + // render painting status if otherwise not available + const statusInfo = ( + {statusText} + ); + return ( - - + + - +
+ +
+ {isAvailable ? salesInfo : statusInfo} +
); diff --git a/components/ui/art-metadata.tsx b/components/ui/art-metadata.tsx index 144b1fd..9f41754 100644 --- a/components/ui/art-metadata.tsx +++ b/components/ui/art-metadata.tsx @@ -9,6 +9,7 @@ import { Art } from "@/lib/models"; /** * Render the metadata for the given art piece * @param props.art Art piece to render metadata for. + * @param props.status Optional. If set to true will show status of the piece. * */ export default function Metadata(props: { art: Art }) { @@ -16,7 +17,7 @@ export default function Metadata(props: { art: Art }) { const { title, height, width, medium, madeOn } = props.art; return (
-

{title}

+

{title}

{height}mm x {width} mm diff --git a/components/ui/button.tsx b/components/ui/button.tsx index 0ba4277..1925e3d 100644 --- a/components/ui/button.tsx +++ b/components/ui/button.tsx @@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority" import { cn } from "@/lib/utils" const buttonVariants = cva( - "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + "inline-flex items-center justify-center whitespace-nowrap text-sm font-bold transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50", { variants: { variant: { @@ -21,8 +21,8 @@ const buttonVariants = cva( }, size: { default: "h-10 px-4 py-2", - sm: "h-9 rounded-md px-3", - lg: "h-11 rounded-md px-8", + sm: "h-9 px-3", + lg: "h-11 px-8", icon: "h-10 w-10", }, }, diff --git a/lib/models.ts b/lib/models.ts index d303468..48a4397 100644 --- a/lib/models.ts +++ b/lib/models.ts @@ -3,7 +3,6 @@ * Models */ - /** Orientation of the Art piece upright. */ export enum Orientation { Vertical = "Vertical", @@ -17,6 +16,15 @@ export enum Channel { Website = "Website", } +/** Defines status states of the Art piece */ +export enum Status { + Available = "Available", + Exhibiting = "Exhbiting", + Sold = "Sold", + Private = "Private", // private collection + Missing = "Missing", +} + /** Art Sales information. */ export type Sale = { channel: Channel; @@ -39,6 +47,7 @@ export type Art = { cost: string; listPrice: string; featured: boolean; + status: Status; framingCost: string | null; sale: Sale | null; exhibited: string | null; diff --git a/lib/parsing.test.ts b/lib/parsing.test.ts index 11076b3..75af31e 100644 --- a/lib/parsing.test.ts +++ b/lib/parsing.test.ts @@ -6,15 +6,17 @@ import { describe, expect, test } from "@jest/globals"; import { parseArt } from "./parsing"; +import { Orientation, Status } from "./models"; describe("parseArt()", () => { test("Parses art.csv", async () => { const records = await parseArt(); - expect(records).toHaveLength(10); + expect(records).toHaveLength(13); expect(records[0]).toStrictEqual({ cost: "5", exhibited: null, featured: false, + status: Status.Available, framingCost: null, height: 410, id: "1", @@ -23,7 +25,7 @@ describe("parseArt()", () => { location: "Luggage", madeOn: new Date("2024-07-16T00:00:00.000Z"), medium: "Watercolor on paper", - orientation: "Vertical", + orientation: Orientation.Vertical, sale: null, title: "KL Dusk", width: 310, diff --git a/lib/parsing.ts b/lib/parsing.ts index 24bfd44..84da775 100644 --- a/lib/parsing.ts +++ b/lib/parsing.ts @@ -27,9 +27,10 @@ export async function parseArt( title: raw["Title"], medium: raw["Medium"], location: raw["Location"], - cost: raw["Cost"], + cost: raw["Painting Cost"], listPrice: raw["List Price"], featured: raw["Featured"].toLowerCase() === "true" ? true : false, + status: raw["Status"], framingCost: raw["Framing Cost"].length > 0 ? raw["Framing Cost"] : null, sale: raw["Sold On"].length > 0 diff --git a/public/art.csv b/public/art.csv index bc31a68..ee4afb2 100644 --- a/public/art.csv +++ b/public/art.csv @@ -1,11 +1,14 @@ -ID,Image,Orientation,Height (mm),Width (mm),Made On,Title,Medium,Location,Cost,Framing Cost,List Price,Featured,Exhibited,Sales Channel,Sold On,Sold Price,Bought By -1,/art/1.jpg,Vertical,410,310,2024-07-16,KL Dusk,Watercolor on paper,Luggage,5,,150,FALSE,,,,, -2,/art/2.jpg,Horizontal,180,260,2024-07-16,National Mosque,Watercolor on paper,Luggage,2.5,,50,FALSE,,,,, -3,/art/3.jpg,Horizontal,310,410,2024-07-16,St. John's Intitution,Watercolor on paper,Luggage,5,,250,TRUE,,,,, -4,/art/4.jpg,Vertical,410,310,2024-07-15,Merdeka!,Watercolor on paper,Luggage,5,,175,FALSE,,,,, -5,/art/5.jpg,Horizontal,310,410,2024-07-15,Sri Maha Mariamman Temple,Watercolor on paper,Luggage,5,,250,TRUE,,,,, -6,/art/6.jpg,Horizontal,310,410,2024-07-14,Thean Hou Temple,Watercolor on paper,Luggage,5,,200,FALSE,,,,, -7,/art/7.jpg,Horizontal,270,380,2024-06-29,The Calm Before the Storm,Watercolor on paper,Home,4,,150,FALSE,,,,, -8,/art/8.jpg,Vertical,380,270,2024-07-04,Holttum Hall,Watercolor on paper,Green Pavilion @ Singapore Botanical Gardens,4,,200,TRUE,Living Story: An Interactive Exhibition,,,, -9,/art/9.jpg,Horizontal,180,260,2024-07-02,Late Afternoon Tea,Watercolor on paper,Home,2.5,,50,FALSE,,,,, -10,/art/10.jpg,Vertical,380,270,2024-07-07,River Sparkle,Watercolor on paper,Home,4,,200,TRUE,,,,, +ID,Image,Orientation,Height (mm),Width (mm),Made On,Title,Medium,Location,Painting Cost,Framing Cost,List Price,Featured,Status,Exhibited,Sales Channel,Sold On,Sold Price,Bought By +1,/art/1.jpg,Vertical,410,310,2024-07-16,KL Dusk,Watercolor on paper,Luggage,5,,150,FALSE,Available,,,,, +2,/art/2.jpg,Horizontal,180,260,2024-07-16,National Mosque,Watercolor on paper,Luggage,2.5,,50,FALSE,Available,,,,, +3,/art/3.jpg,Horizontal,310,410,2024-07-16,St. John's Institution,Watercolor on paper,Luggage,5,,250,TRUE,Available,,,,, +4,/art/4.jpg,Vertical,410,310,2024-07-15,Merdeka!,Watercolor on paper,Luggage,5,,175,FALSE,Available,,,,, +5,/art/5.jpg,Horizontal,310,410,2024-07-15,Sri Maha Mariamman Temple,Watercolor on paper,Luggage,5,,250,TRUE,Available,,,,, +6,/art/6.jpg,Horizontal,310,410,2024-07-14,Thean Hou Temple,Watercolor on paper,Luggage,5,,200,FALSE,Available,,,,, +7,/art/7.jpg,Horizontal,270,380,2024-06-29,The Calm Before the Storm,Watercolor on paper,Home,4,,150,FALSE,Available,,,,, +8,/art/8.jpg,Vertical,380,270,2024-07-04,Holttum Hall,Watercolor on paper,Green Pavilion @ Singapore Botanical Gardens,4,,200,TRUE,Exhbiting,Living Story: An Interactive Exhibition,,,, +9,/art/9.jpg,Horizontal,180,260,2024-07-02,Late Afternoon Tea,Watercolor on paper,Home,2.5,,50,FALSE,Available,,,,, +10,/art/10.jpg,Vertical,380,270,2024-07-07,River Sparkle,Watercolor on paper,Home,4,,200,TRUE,Available,,,,, +11,/art/11.jpg,Horizontal,310,410,2024-07-22,Jog by the Pier,Watercolor on paper,Luggage,4,,150,FALSE,Available,,,,, +12,/art/12.jpg,Horizontal,310,410,2024-07-23,Jing'an Temple,Watercolor on paper,Luggage,4,,200,FALSE,Available,,,,, +13,/art/13.jpg,Horizontal,310,410,2024-07-23,Hogwarts,Watercolor on paper,Luggage,4,,200,FALSE,Available,,,,, diff --git a/public/images/art/11.jpg b/public/images/art/11.jpg new file mode 100755 index 0000000..bccecc7 Binary files /dev/null and b/public/images/art/11.jpg differ diff --git a/public/images/art/12.jpg b/public/images/art/12.jpg new file mode 100755 index 0000000..a415f28 Binary files /dev/null and b/public/images/art/12.jpg differ diff --git a/public/images/art/13.jpg b/public/images/art/13.jpg new file mode 100755 index 0000000..139116d Binary files /dev/null and b/public/images/art/13.jpg differ diff --git a/tailwind.config.ts b/tailwind.config.ts index 8061394..28d8e20 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -29,6 +29,7 @@ const config = { ring: "hsl(var(--ring))", background: "hsl(var(--background))", foreground: "hsl(var(--foreground))", + green: "#32AC5C", primary: { DEFAULT: "hsl(var(--primary))", foreground: "hsl(var(--primary-foreground))",