From ff755f6dce2efcbedd3019b3f8d3139bb6a59007 Mon Sep 17 00:00:00 2001 From: Nguyen Phuc Vinh Date: Sat, 26 Oct 2024 21:34:53 +0700 Subject: [PATCH] feat: add shadcn UI --- app/datasets/[dataset]/page.tsx | 36 ++++++++++++++++- app/datasets/page.tsx | 12 +++--- app/globals.css | 63 ++++++++++++++++++++++++++++++ bun.lockb | Bin 110525 -> 176686 bytes components.json | 20 ++++++++++ components/ui/button.tsx | 47 ++++++++++++++++++++++ components/ui/calendar.tsx | 63 ++++++++++++++++++++++++++++++ components/ui/card.tsx | 49 +++++++++++++++++++++++ components/ui/dateRangePicker.tsx | 54 +++++++++++++++++++++++++ components/ui/input.tsx | 22 +++++++++++ components/ui/popover.tsx | 33 ++++++++++++++++ components/ui/slider.tsx | 25 ++++++++++++ lib/api/dataset.ts | 2 +- lib/utils.ts | 6 +++ next.config.js | 2 - package.json | 13 +++++- tailwind.config.ts | 57 ++++++++++++++++++++++++--- 17 files changed, 487 insertions(+), 17 deletions(-) create mode 100644 components.json create mode 100644 components/ui/button.tsx create mode 100644 components/ui/calendar.tsx create mode 100644 components/ui/card.tsx create mode 100644 components/ui/dateRangePicker.tsx create mode 100644 components/ui/input.tsx create mode 100644 components/ui/popover.tsx create mode 100644 components/ui/slider.tsx create mode 100644 lib/utils.ts diff --git a/app/datasets/[dataset]/page.tsx b/app/datasets/[dataset]/page.tsx index d015fbc..11d8d39 100644 --- a/app/datasets/[dataset]/page.tsx +++ b/app/datasets/[dataset]/page.tsx @@ -1,8 +1,42 @@ 'use client'; +import { DateRangePicker } from '@/components/ui/dateRangePicker'; +import { Input } from '@/components/ui/input'; +import { Slider } from '@/components/ui/slider'; +import { DatasetAPI, type DatasetSchema } from '@/lib/api/dataset'; +import { useQuery } from '@tanstack/react-query'; import { useParams } from 'next/navigation'; +import { useMemo } from 'react'; + +// keyword -> Text input +// text -> Text input +// long | double -> Range input +// date -> Date range input export default function DatasetPage() { const { dataset } = useParams<{ dataset: string }>(); - return
{dataset}
; + + const { data: schema } = useQuery({ + queryKey: ['schema', dataset], + queryFn: () => DatasetAPI.getSchema(dataset) + }); + + const inputDefs = useMemo(() => Object.entries(schema || {}), [schema]); + + return ( +
+ {inputDefs.map(([inputName, inputSchema]) => { + if (inputSchema.type === 'keyword' || inputSchema.type === 'text') { + return ; + } + if (inputSchema.type === 'long' || inputSchema.type === 'double') { + return ; + } + if (inputSchema.type === 'date') { + return ; + } + return null; + })} +
+ ); } diff --git a/app/datasets/page.tsx b/app/datasets/page.tsx index 63fbdae..4a969f4 100644 --- a/app/datasets/page.tsx +++ b/app/datasets/page.tsx @@ -12,13 +12,11 @@ export default function DatasetPage() { return (
- + {datasets.map((dataset) => ( + + {dataset.name} + + ))}
); } diff --git a/app/globals.css b/app/globals.css index b5c61c9..6baea5d 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,3 +1,66 @@ @tailwind base; @tailwind components; @tailwind utilities; +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 222.2 84% 4.9%; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + --radius: 0.5rem; + } + .dark { + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + --primary: 210 40% 98%; + --primary-foreground: 222.2 47.4% 11.2%; + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + --accent: 217.2 32.6% 17.5%; + --accent-foreground: 210 40% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 40% 98%; + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + --ring: 212.7 26.8% 83.9%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } +} +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/bun.lockb b/bun.lockb index 18bf32ea0010c9374b8ea12dc18dc77afd2393a9..61828cf98e5dca795f253724569fcdf9229e4d6d 100755 GIT binary patch delta 63055 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 delta 21439 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 diff --git a/components.json b/components.json new file mode 100644 index 0000000..aa6b0dc --- /dev/null +++ b/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.ts", + "css": "app/globals.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + } +} diff --git a/components/ui/button.tsx b/components/ui/button.tsx new file mode 100644 index 0000000..5c8de11 --- /dev/null +++ b/components/ui/button.tsx @@ -0,0 +1,47 @@ +import { Slot } from '@radix-ui/react-slot'; +import { type VariantProps, cva } from 'class-variance-authority'; +import * as React from 'react'; + +import { cn } from '@/lib/utils'; + +const buttonVariants = cva( + 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', + { + variants: { + variant: { + default: 'bg-primary text-primary-foreground shadow hover:bg-primary/90', + destructive: 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90', + outline: 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground', + secondary: 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80', + ghost: 'hover:bg-accent hover:text-accent-foreground', + link: 'text-primary underline-offset-4 hover:underline' + }, + size: { + default: 'h-9 px-4 py-2', + sm: 'h-8 rounded-md px-3 text-xs', + lg: 'h-10 rounded-md px-8', + icon: 'h-9 w-9' + } + }, + defaultVariants: { + variant: 'default', + size: 'default' + } + } +); + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : 'button'; + return ; + } +); +Button.displayName = 'Button'; + +export { Button, buttonVariants }; diff --git a/components/ui/calendar.tsx b/components/ui/calendar.tsx new file mode 100644 index 0000000..d33c43b --- /dev/null +++ b/components/ui/calendar.tsx @@ -0,0 +1,63 @@ +'use client'; + +import { ChevronLeftIcon, ChevronRightIcon } from '@radix-ui/react-icons'; +import type React from 'react'; +import { DayPicker } from 'react-day-picker'; + +import { buttonVariants } from '@/components/ui/button'; +import { cn } from '@/lib/utils'; + +export type CalendarProps = React.ComponentProps; + +function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) { + return ( + .day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md' + : '[&:has([aria-selected])]:rounded-md' + ), + day: cn(buttonVariants({ variant: 'ghost' }), 'h-8 w-8 p-0 font-normal aria-selected:opacity-100'), + day_range_start: 'day-range-start', + day_range_end: 'day-range-end', + day_selected: + 'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground', + day_today: 'bg-accent text-accent-foreground', + day_outside: + 'day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30', + day_disabled: 'text-muted-foreground opacity-50', + day_range_middle: 'aria-selected:bg-accent aria-selected:text-accent-foreground', + day_hidden: 'invisible', + ...classNames + }} + components={{ + // @ts-ignore + IconLeft: ({ ...props }) => , + IconRight: ({ ...props }) => + }} + {...props} + /> + ); +} +Calendar.displayName = 'Calendar'; + +export { Calendar }; diff --git a/components/ui/card.tsx b/components/ui/card.tsx new file mode 100644 index 0000000..315f2a6 --- /dev/null +++ b/components/ui/card.tsx @@ -0,0 +1,49 @@ +import * as React from 'react'; + +import { cn } from '@/lib/utils'; + +const Card = React.forwardRef>( + ({ className, ...props }, ref) => ( +
+ ) +); +Card.displayName = 'Card'; + +const CardHeader = React.forwardRef>( + ({ className, ...props }, ref) => ( +
+ ) +); +CardHeader.displayName = 'CardHeader'; + +const CardTitle = React.forwardRef>( + ({ className, ...props }, ref) => ( +

+ ) +); +CardTitle.displayName = 'CardTitle'; + +const CardDescription = React.forwardRef>( + ({ className, ...props }, ref) => ( +

+ ) +); +CardDescription.displayName = 'CardDescription'; + +const CardContent = React.forwardRef>( + ({ className, ...props }, ref) =>

+); +CardContent.displayName = 'CardContent'; + +const CardFooter = React.forwardRef>( + ({ className, ...props }, ref) => ( +
+ ) +); +CardFooter.displayName = 'CardFooter'; + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }; diff --git a/components/ui/dateRangePicker.tsx b/components/ui/dateRangePicker.tsx new file mode 100644 index 0000000..490db99 --- /dev/null +++ b/components/ui/dateRangePicker.tsx @@ -0,0 +1,54 @@ +'use client'; + +import { addDays, format } from 'date-fns'; +import { Calendar as CalendarIcon } from 'lucide-react'; +import * as React from 'react'; +import type { DateRange } from 'react-day-picker'; + +import { Button } from '@/components/ui/button'; +import { Calendar } from '@/components/ui/calendar'; +import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; +import { cn } from '@/lib/utils'; + +export function DateRangePicker({ className }: React.HTMLAttributes) { + const [date, setDate] = React.useState({ + from: new Date(2022, 0, 20), + to: addDays(new Date(2022, 0, 20), 20) + }); + + return ( +
+ + + + + + + + +
+ ); +} diff --git a/components/ui/input.tsx b/components/ui/input.tsx new file mode 100644 index 0000000..ec82d3a --- /dev/null +++ b/components/ui/input.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; + +import { cn } from '@/lib/utils'; + +export interface InputProps extends React.InputHTMLAttributes {} + +const Input = React.forwardRef(({ className, type, ...props }, ref) => { + return ( + + ); +}); +Input.displayName = 'Input'; + +export { Input }; diff --git a/components/ui/popover.tsx b/components/ui/popover.tsx new file mode 100644 index 0000000..026866a --- /dev/null +++ b/components/ui/popover.tsx @@ -0,0 +1,33 @@ +'use client'; + +import * as PopoverPrimitive from '@radix-ui/react-popover'; +import * as React from 'react'; + +import { cn } from '@/lib/utils'; + +const Popover = PopoverPrimitive.Root; + +const PopoverTrigger = PopoverPrimitive.Trigger; + +const PopoverAnchor = PopoverPrimitive.Anchor; + +const PopoverContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, align = 'center', sideOffset = 4, ...props }, ref) => ( + + + +)); +PopoverContent.displayName = PopoverPrimitive.Content.displayName; + +export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }; diff --git a/components/ui/slider.tsx b/components/ui/slider.tsx new file mode 100644 index 0000000..1ebf362 --- /dev/null +++ b/components/ui/slider.tsx @@ -0,0 +1,25 @@ +'use client'; + +import * as SliderPrimitive from '@radix-ui/react-slider'; +import * as React from 'react'; + +import { cn } from '@/lib/utils'; + +const Slider = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + + + +)); +Slider.displayName = SliderPrimitive.Root.displayName; + +export { Slider }; diff --git a/lib/api/dataset.ts b/lib/api/dataset.ts index d3aa611..1eb3146 100644 --- a/lib/api/dataset.ts +++ b/lib/api/dataset.ts @@ -6,7 +6,7 @@ export type Dataset = { }; export type DatasetFieldSchema = { - type: string; + type: 'keyword' | 'text' | 'long' | 'double' | 'date' | string; format?: string; }; export type DatasetSchema = Record; diff --git a/lib/utils.ts b/lib/utils.ts new file mode 100644 index 0000000..9ad0df4 --- /dev/null +++ b/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from 'clsx'; +import { twMerge } from 'tailwind-merge'; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/next.config.js b/next.config.js index b6c3485..7f37d26 100644 --- a/next.config.js +++ b/next.config.js @@ -4,8 +4,6 @@ */ await import('./lib/env.js'); -const isProd = process.env.NODE_ENV === 'production'; - /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, diff --git a/package.json b/package.json index 26e708a..81e5440 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,24 @@ "prepare": "lefthook install" }, "dependencies": { + "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-popover": "^1.1.2", + "@radix-ui/react-slider": "^1.2.1", + "@radix-ui/react-slot": "^1.1.0", "@t3-oss/env-nextjs": "^0.11.1", "@tanstack/react-query": "^5.59.15", "@tanstack/react-table": "^8.20.5", "axios": "^1.7.7", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "date-fns": "^4.1.0", + "lucide-react": "^0.453.0", "next": "^14.2.15", "react": "^18.3.1", + "react-day-picker": "^9.2.0", "react-dom": "^18.3.1", + "tailwind-merge": "^2.5.4", + "tailwindcss-animate": "^1.0.7", "zod": "^3.23.8" }, "devDependencies": { @@ -28,9 +39,9 @@ "@types/node": "^22.7.6", "@types/react": "^18.3.5", "@types/react-dom": "^18.3.0", - "daisyui": "^4.12.13", "lefthook": "^1.7.22", "postcss": "8.4.41", + "shadcn": "^2.1.2", "tailwindcss": "3.4.10", "typescript": "5.5.4" }, diff --git a/tailwind.config.ts b/tailwind.config.ts index f3f333e..01d393f 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,16 +1,63 @@ -import daisyui from 'daisyui'; import type { Config } from 'tailwindcss'; -import { fontFamily } from 'tailwindcss/defaultTheme'; const config = { + darkMode: ['class'], content: [ './app/**/*.{js,ts,jsx,tsx,mdx}', './pages/**/*.{js,ts,jsx,tsx,mdx}', './components/**/*.{js,ts,jsx,tsx,mdx}' ], - plugins: [daisyui], - daisyui: { - themes: ['light'] + plugins: [require('tailwindcss-animate')], + theme: { + extend: { + borderRadius: { + lg: 'var(--radius)', + md: 'calc(var(--radius) - 2px)', + sm: 'calc(var(--radius) - 4px)' + }, + colors: { + background: 'hsl(var(--background))', + foreground: 'hsl(var(--foreground))', + card: { + DEFAULT: 'hsl(var(--card))', + foreground: 'hsl(var(--card-foreground))' + }, + popover: { + DEFAULT: 'hsl(var(--popover))', + foreground: 'hsl(var(--popover-foreground))' + }, + primary: { + DEFAULT: 'hsl(var(--primary))', + foreground: 'hsl(var(--primary-foreground))' + }, + secondary: { + DEFAULT: 'hsl(var(--secondary))', + foreground: 'hsl(var(--secondary-foreground))' + }, + muted: { + DEFAULT: 'hsl(var(--muted))', + foreground: 'hsl(var(--muted-foreground))' + }, + accent: { + DEFAULT: 'hsl(var(--accent))', + foreground: 'hsl(var(--accent-foreground))' + }, + destructive: { + DEFAULT: 'hsl(var(--destructive))', + foreground: 'hsl(var(--destructive-foreground))' + }, + border: 'hsl(var(--border))', + input: 'hsl(var(--input))', + ring: 'hsl(var(--ring))', + chart: { + '1': 'hsl(var(--chart-1))', + '2': 'hsl(var(--chart-2))', + '3': 'hsl(var(--chart-3))', + '4': 'hsl(var(--chart-4))', + '5': 'hsl(var(--chart-5))' + } + } + } } } satisfies Config;