From 9fdd78e73704feb0431b4b42e580321dca1285a8 Mon Sep 17 00:00:00 2001 From: Bintang Murtifandy <21844@student.stembayo.sch.id> Date: Tue, 26 May 2026 12:11:14 +0700 Subject: [PATCH] Initial commit --- .env | 2 + .env.example | 2 + .gitignore | 15 + components/theme-provider.tsx | 11 + components/ui/accordion.tsx | 66 ++ components/ui/alert-dialog.tsx | 157 +++ components/ui/alert.tsx | 66 ++ components/ui/aspect-ratio.tsx | 11 + components/ui/avatar.tsx | 53 + components/ui/badge.tsx | 46 + components/ui/breadcrumb.tsx | 109 ++ components/ui/button-group.tsx | 83 ++ components/ui/button.tsx | 60 ++ components/ui/calendar.tsx | 213 ++++ components/ui/card.tsx | 92 ++ components/ui/carousel.tsx | 241 +++++ components/ui/chart.tsx | 351 +++++++ components/ui/checkbox.tsx | 32 + components/ui/collapsible.tsx | 33 + components/ui/command.tsx | 184 ++++ components/ui/context-menu.tsx | 252 +++++ components/ui/dialog.tsx | 143 +++ components/ui/drawer.tsx | 135 +++ components/ui/dropdown-menu.tsx | 257 +++++ components/ui/empty.tsx | 104 ++ components/ui/field.tsx | 244 +++++ components/ui/form.tsx | 167 +++ components/ui/hover-card.tsx | 44 + components/ui/input-group.tsx | 169 +++ components/ui/input-otp.tsx | 77 ++ components/ui/input.tsx | 21 + components/ui/item.tsx | 193 ++++ components/ui/kbd.tsx | 28 + components/ui/label.tsx | 24 + components/ui/menubar.tsx | 276 +++++ components/ui/navigation-menu.tsx | 166 +++ components/ui/pagination.tsx | 127 +++ components/ui/popover.tsx | 48 + components/ui/progress.tsx | 31 + components/ui/radio-group.tsx | 45 + components/ui/resizable.tsx | 56 + components/ui/scroll-area.tsx | 58 + components/ui/select.tsx | 185 ++++ components/ui/separator.tsx | 28 + components/ui/sheet.tsx | 139 +++ components/ui/sidebar.tsx | 726 +++++++++++++ components/ui/skeleton.tsx | 13 + components/ui/slider.tsx | 59 ++ components/ui/sonner.tsx | 25 + components/ui/spinner.tsx | 16 + components/ui/switch.tsx | 29 + components/ui/table.tsx | 116 ++ components/ui/tabs.tsx | 66 ++ components/ui/textarea.tsx | 18 + components/ui/toast.tsx | 129 +++ components/ui/toaster.tsx | 35 + components/ui/toggle-group.tsx | 73 ++ components/ui/toggle.tsx | 47 + components/ui/tooltip.tsx | 61 ++ components/ui/use-mobile.tsx | 19 + components/ui/use-toast.ts | 191 ++++ dist/apple-icon.png | Bin 0 -> 2626 bytes dist/assets/index-BO7gh51n.js | 9 + dist/assets/index-mUm8ch4i.css | 1 + dist/icon-dark-32x32.png | Bin 0 -> 585 bytes dist/icon-light-32x32.png | Bin 0 -> 566 bytes dist/icon.svg | 26 + dist/index.html | 15 + dist/placeholder-logo.png | Bin 0 -> 568 bytes dist/placeholder-logo.svg | 1 + dist/placeholder-user.jpg | Bin 0 -> 1635 bytes dist/placeholder.jpg | Bin 0 -> 1064 bytes dist/placeholder.svg | 1 + hooks/use-mobile.ts | 19 + hooks/use-toast.ts | 191 ++++ index.html | 14 + lib/utils.ts | 6 + next-env.d.ts | 6 + package.json | 25 + pnpm-lock.yaml | 1634 +++++++++++++++++++++++++++++ postcss.config.js | 6 + public/apple-icon.png | Bin 0 -> 2626 bytes public/icon-dark-32x32.png | Bin 0 -> 585 bytes public/icon-light-32x32.png | Bin 0 -> 566 bytes public/icon.svg | 26 + public/placeholder-logo.png | Bin 0 -> 568 bytes public/placeholder-logo.svg | 1 + public/placeholder-user.jpg | Bin 0 -> 1635 bytes public/placeholder.jpg | Bin 0 -> 1064 bytes public/placeholder.svg | 1 + src/App.vue | 70 ++ src/components/AppHeader.vue | 109 ++ src/components/MusicPlayer.vue | 80 ++ src/components/PlayerBar.vue | 147 +++ src/components/SettingsItem.vue | 62 ++ src/components/Sidebar.vue | 94 ++ src/composables/useAuthGate.js | 30 + src/composables/usePlayer.js | 39 + src/lib/api.js | 30 + src/lib/audioEngine.js | 56 + src/main.js | 10 + src/router/index.js | 46 + src/stores/authStore.js | 75 ++ src/stores/playerStore.js | 103 ++ src/stores/queueStore.js | 86 ++ src/stores/uiStore.js | 21 + src/style.css | 40 + src/views/AdminPage.vue | 132 +++ src/views/LandingPage.vue | 89 ++ src/views/LibraryPage.vue | 134 +++ src/views/LoginPage.vue | 130 +++ src/views/PlaylistPage.vue | 147 +++ src/views/ProfilePage.vue | 158 +++ src/views/RegisterPage.vue | 83 ++ styles/globals.css | 125 +++ tailwind.config.js | 23 + vite.config.js | 11 + 117 files changed, 10579 insertions(+) create mode 100644 .env create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 components/theme-provider.tsx create mode 100644 components/ui/accordion.tsx create mode 100644 components/ui/alert-dialog.tsx create mode 100644 components/ui/alert.tsx create mode 100644 components/ui/aspect-ratio.tsx create mode 100644 components/ui/avatar.tsx create mode 100644 components/ui/badge.tsx create mode 100644 components/ui/breadcrumb.tsx create mode 100644 components/ui/button-group.tsx 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/carousel.tsx create mode 100644 components/ui/chart.tsx create mode 100644 components/ui/checkbox.tsx create mode 100644 components/ui/collapsible.tsx create mode 100644 components/ui/command.tsx create mode 100644 components/ui/context-menu.tsx create mode 100644 components/ui/dialog.tsx create mode 100644 components/ui/drawer.tsx create mode 100644 components/ui/dropdown-menu.tsx create mode 100644 components/ui/empty.tsx create mode 100644 components/ui/field.tsx create mode 100644 components/ui/form.tsx create mode 100644 components/ui/hover-card.tsx create mode 100644 components/ui/input-group.tsx create mode 100644 components/ui/input-otp.tsx create mode 100644 components/ui/input.tsx create mode 100644 components/ui/item.tsx create mode 100644 components/ui/kbd.tsx create mode 100644 components/ui/label.tsx create mode 100644 components/ui/menubar.tsx create mode 100644 components/ui/navigation-menu.tsx create mode 100644 components/ui/pagination.tsx create mode 100644 components/ui/popover.tsx create mode 100644 components/ui/progress.tsx create mode 100644 components/ui/radio-group.tsx create mode 100644 components/ui/resizable.tsx create mode 100644 components/ui/scroll-area.tsx create mode 100644 components/ui/select.tsx create mode 100644 components/ui/separator.tsx create mode 100644 components/ui/sheet.tsx create mode 100644 components/ui/sidebar.tsx create mode 100644 components/ui/skeleton.tsx create mode 100644 components/ui/slider.tsx create mode 100644 components/ui/sonner.tsx create mode 100644 components/ui/spinner.tsx create mode 100644 components/ui/switch.tsx create mode 100644 components/ui/table.tsx create mode 100644 components/ui/tabs.tsx create mode 100644 components/ui/textarea.tsx create mode 100644 components/ui/toast.tsx create mode 100644 components/ui/toaster.tsx create mode 100644 components/ui/toggle-group.tsx create mode 100644 components/ui/toggle.tsx create mode 100644 components/ui/tooltip.tsx create mode 100644 components/ui/use-mobile.tsx create mode 100644 components/ui/use-toast.ts create mode 100644 dist/apple-icon.png create mode 100644 dist/assets/index-BO7gh51n.js create mode 100644 dist/assets/index-mUm8ch4i.css create mode 100644 dist/icon-dark-32x32.png create mode 100644 dist/icon-light-32x32.png create mode 100644 dist/icon.svg create mode 100644 dist/index.html create mode 100644 dist/placeholder-logo.png create mode 100644 dist/placeholder-logo.svg create mode 100644 dist/placeholder-user.jpg create mode 100644 dist/placeholder.jpg create mode 100644 dist/placeholder.svg create mode 100644 hooks/use-mobile.ts create mode 100644 hooks/use-toast.ts create mode 100644 index.html create mode 100644 lib/utils.ts create mode 100644 next-env.d.ts create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 postcss.config.js create mode 100644 public/apple-icon.png create mode 100644 public/icon-dark-32x32.png create mode 100644 public/icon-light-32x32.png create mode 100644 public/icon.svg create mode 100644 public/placeholder-logo.png create mode 100644 public/placeholder-logo.svg create mode 100644 public/placeholder-user.jpg create mode 100644 public/placeholder.jpg create mode 100644 public/placeholder.svg create mode 100644 src/App.vue create mode 100644 src/components/AppHeader.vue create mode 100644 src/components/MusicPlayer.vue create mode 100644 src/components/PlayerBar.vue create mode 100644 src/components/SettingsItem.vue create mode 100644 src/components/Sidebar.vue create mode 100644 src/composables/useAuthGate.js create mode 100644 src/composables/usePlayer.js create mode 100644 src/lib/api.js create mode 100644 src/lib/audioEngine.js create mode 100644 src/main.js create mode 100644 src/router/index.js create mode 100644 src/stores/authStore.js create mode 100644 src/stores/playerStore.js create mode 100644 src/stores/queueStore.js create mode 100644 src/stores/uiStore.js create mode 100644 src/style.css create mode 100644 src/views/AdminPage.vue create mode 100644 src/views/LandingPage.vue create mode 100644 src/views/LibraryPage.vue create mode 100644 src/views/LoginPage.vue create mode 100644 src/views/PlaylistPage.vue create mode 100644 src/views/ProfilePage.vue create mode 100644 src/views/RegisterPage.vue create mode 100644 styles/globals.css create mode 100644 tailwind.config.js create mode 100644 vite.config.js diff --git a/.env b/.env new file mode 100644 index 0000000..e67e847 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +VITE_API_BASE_URL=http://localhost:3002/api +VITE_APP_NAME=NOCTUNE diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..0344b5a --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +VITE_API_BASE_URL=http://localhost:3001/api +VITE_APP_NAME=NOCTUNE diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..97eb8c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# v0 sandbox internal files +__v0_runtime_loader.js +__v0_devtools.tsx +__v0_jsx-dev-runtime.ts +.snowflake/ +.v0-trash/ +.vercel/ + +# Environment variables +.env*.local + +# Common ignores +node_modules +.next/ +.DS_Store \ No newline at end of file diff --git a/components/theme-provider.tsx b/components/theme-provider.tsx new file mode 100644 index 0000000..55c2f6e --- /dev/null +++ b/components/theme-provider.tsx @@ -0,0 +1,11 @@ +'use client' + +import * as React from 'react' +import { + ThemeProvider as NextThemesProvider, + type ThemeProviderProps, +} from 'next-themes' + +export function ThemeProvider({ children, ...props }: ThemeProviderProps) { + return {children} +} diff --git a/components/ui/accordion.tsx b/components/ui/accordion.tsx new file mode 100644 index 0000000..e538a33 --- /dev/null +++ b/components/ui/accordion.tsx @@ -0,0 +1,66 @@ +'use client' + +import * as React from 'react' +import * as AccordionPrimitive from '@radix-ui/react-accordion' +import { ChevronDownIcon } from 'lucide-react' + +import { cn } from '@/lib/utils' + +function Accordion({ + ...props +}: React.ComponentProps) { + return +} + +function AccordionItem({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AccordionTrigger({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + svg]:rotate-180', + className, + )} + {...props} + > + {children} + + + + ) +} + +function AccordionContent({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + +
{children}
+
+ ) +} + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/components/ui/alert-dialog.tsx b/components/ui/alert-dialog.tsx new file mode 100644 index 0000000..9704452 --- /dev/null +++ b/components/ui/alert-dialog.tsx @@ -0,0 +1,157 @@ +'use client' + +import * as React from 'react' +import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog' + +import { cn } from '@/lib/utils' +import { buttonVariants } from '@/components/ui/button' + +function AlertDialog({ + ...props +}: React.ComponentProps) { + return +} + +function AlertDialogTrigger({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogPortal({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + + ) +} + +function AlertDialogHeader({ + className, + ...props +}: React.ComponentProps<'div'>) { + return ( +
+ ) +} + +function AlertDialogFooter({ + className, + ...props +}: React.ComponentProps<'div'>) { + return ( +
+ ) +} + +function AlertDialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogAction({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogCancel({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { + AlertDialog, + AlertDialogPortal, + AlertDialogOverlay, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel, +} diff --git a/components/ui/alert.tsx b/components/ui/alert.tsx new file mode 100644 index 0000000..e6751ab --- /dev/null +++ b/components/ui/alert.tsx @@ -0,0 +1,66 @@ +import * as React from 'react' +import { cva, type VariantProps } from 'class-variance-authority' + +import { cn } from '@/lib/utils' + +const alertVariants = cva( + 'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current', + { + variants: { + variant: { + default: 'bg-card text-card-foreground', + destructive: + 'text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90', + }, + }, + defaultVariants: { + variant: 'default', + }, + }, +) + +function Alert({ + className, + variant, + ...props +}: React.ComponentProps<'div'> & VariantProps) { + return ( +
+ ) +} + +function AlertTitle({ className, ...props }: React.ComponentProps<'div'>) { + return ( +
+ ) +} + +function AlertDescription({ + className, + ...props +}: React.ComponentProps<'div'>) { + return ( +
+ ) +} + +export { Alert, AlertTitle, AlertDescription } diff --git a/components/ui/aspect-ratio.tsx b/components/ui/aspect-ratio.tsx new file mode 100644 index 0000000..40bb120 --- /dev/null +++ b/components/ui/aspect-ratio.tsx @@ -0,0 +1,11 @@ +'use client' + +import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio' + +function AspectRatio({ + ...props +}: React.ComponentProps) { + return +} + +export { AspectRatio } diff --git a/components/ui/avatar.tsx b/components/ui/avatar.tsx new file mode 100644 index 0000000..aa98465 --- /dev/null +++ b/components/ui/avatar.tsx @@ -0,0 +1,53 @@ +'use client' + +import * as React from 'react' +import * as AvatarPrimitive from '@radix-ui/react-avatar' + +import { cn } from '@/lib/utils' + +function Avatar({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AvatarImage({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AvatarFallback({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { Avatar, AvatarImage, AvatarFallback } diff --git a/components/ui/badge.tsx b/components/ui/badge.tsx new file mode 100644 index 0000000..fc4126b --- /dev/null +++ b/components/ui/badge.tsx @@ -0,0 +1,46 @@ +import * as React from 'react' +import { Slot } from '@radix-ui/react-slot' +import { cva, type VariantProps } from 'class-variance-authority' + +import { cn } from '@/lib/utils' + +const badgeVariants = cva( + 'inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden', + { + variants: { + variant: { + default: + 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90', + secondary: + 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90', + destructive: + 'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60', + outline: + 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground', + }, + }, + defaultVariants: { + variant: 'default', + }, + }, +) + +function Badge({ + className, + variant, + asChild = false, + ...props +}: React.ComponentProps<'span'> & + VariantProps & { asChild?: boolean }) { + const Comp = asChild ? Slot : 'span' + + return ( + + ) +} + +export { Badge, badgeVariants } diff --git a/components/ui/breadcrumb.tsx b/components/ui/breadcrumb.tsx new file mode 100644 index 0000000..1750ff2 --- /dev/null +++ b/components/ui/breadcrumb.tsx @@ -0,0 +1,109 @@ +import * as React from 'react' +import { Slot } from '@radix-ui/react-slot' +import { ChevronRight, MoreHorizontal } from 'lucide-react' + +import { cn } from '@/lib/utils' + +function Breadcrumb({ ...props }: React.ComponentProps<'nav'>) { + return