Skip to content

Commit 470fefe

Browse files
author
dynamicdev-official
committed
feat: initialize project scaffolding with Shadcn UI components and Tailwind CSS configuration
1 parent 0a286c8 commit 470fefe

84 files changed

Lines changed: 17653 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# ---------------------------------------------------------------
2+
# WatchDocs - environment template
3+
# Copy this file to .env and adjust values before running compose.
4+
# ---------------------------------------------------------------
5+
6+
# Node runtime
7+
NODE_ENV=production
8+
PORT=3355
9+
HOSTNAME=0.0.0.0
10+
11+
# Public base URL (used for share links, metadata, absolute redirects)
12+
NEXT_PUBLIC_APP_URL=https://watchdocs.dynamicdev.asia
13+
14+
# Postgres connection.
15+
# When the DB container runs on the same dynamicdev-net network,
16+
# reference it by container name, e.g. postgres:5432.
17+
# Format: postgres://USER:PASSWORD@HOST:PORT/DATABASE
18+
DATABASE_URL=postgres://watchdocs:change-me@postgres:5432/watchdocs
19+
20+
# Timezone used by the container runtime
21+
TZ=Asia/Bangkok
22+
23+
# Optional - Vercel Web Analytics token, leave blank when self-hosting
24+
NEXT_PUBLIC_VERCEL_ANALYTICS_ID=

.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# v0 sandbox internal files
2+
__v0_runtime_loader.js
3+
__v0_devtools.tsx
4+
__v0_jsx-dev-runtime.ts
5+
.snowflake/
6+
.v0-trash/
7+
.vercel/
8+
next.user-config.*
9+
.agents
10+
.antigravity
11+
12+
# Environment variables
13+
.env*.local
14+
.env
15+
16+
# Common ignores
17+
node_modules
18+
.next/
19+
.DS_Store

app/globals.css

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
@import 'tailwindcss';
2+
@import 'tw-animate-css';
3+
4+
@custom-variant dark (&:is(.dark *));
5+
6+
:root {
7+
/* Light theme - muted crimson accent, editorial feel */
8+
--background: oklch(0.985 0.002 260);
9+
--foreground: oklch(0.2 0.008 260);
10+
--card: oklch(1 0 0);
11+
--card-foreground: oklch(0.2 0.008 260);
12+
--popover: oklch(1 0 0);
13+
--popover-foreground: oklch(0.2 0.008 260);
14+
--primary: oklch(0.52 0.13 22);
15+
--primary-foreground: oklch(0.99 0.002 60);
16+
--secondary: oklch(0.955 0.004 260);
17+
--secondary-foreground: oklch(0.25 0.008 260);
18+
--muted: oklch(0.955 0.004 260);
19+
--muted-foreground: oklch(0.52 0.008 260);
20+
--accent: oklch(0.955 0.008 22);
21+
--accent-foreground: oklch(0.45 0.1 22);
22+
--destructive: oklch(0.56 0.14 25);
23+
--destructive-foreground: oklch(0.99 0.002 60);
24+
--border: oklch(0.905 0.004 260);
25+
--input: oklch(0.905 0.004 260);
26+
--ring: oklch(0.52 0.13 22);
27+
--chart-1: oklch(0.58 0.12 22);
28+
--chart-2: oklch(0.6 0.08 184);
29+
--chart-3: oklch(0.45 0.06 227);
30+
--chart-4: oklch(0.75 0.1 84);
31+
--chart-5: oklch(0.7 0.1 70);
32+
--radius: 0.5rem;
33+
--sidebar: oklch(0.97 0.003 260);
34+
--sidebar-foreground: oklch(0.2 0.008 260);
35+
--sidebar-primary: oklch(0.52 0.13 22);
36+
--sidebar-primary-foreground: oklch(0.99 0.002 60);
37+
--sidebar-accent: oklch(0.94 0.004 260);
38+
--sidebar-accent-foreground: oklch(0.25 0.008 260);
39+
--sidebar-border: oklch(0.905 0.004 260);
40+
--sidebar-ring: oklch(0.52 0.13 22);
41+
42+
/* Custom grid color for canvas */
43+
--grid-color: oklch(0.9 0.004 260);
44+
}
45+
46+
.dark {
47+
/* Dark theme - editorial, muted, slight warm crimson accent */
48+
--background: oklch(0.155 0.006 260);
49+
--foreground: oklch(0.93 0.004 260);
50+
--card: oklch(0.19 0.006 260);
51+
--card-foreground: oklch(0.93 0.004 260);
52+
--popover: oklch(0.18 0.006 260);
53+
--popover-foreground: oklch(0.93 0.004 260);
54+
--primary: oklch(0.58 0.13 22);
55+
--primary-foreground: oklch(0.99 0.002 60);
56+
--secondary: oklch(0.23 0.006 260);
57+
--secondary-foreground: oklch(0.93 0.004 260);
58+
--muted: oklch(0.23 0.006 260);
59+
--muted-foreground: oklch(0.64 0.006 260);
60+
--accent: oklch(0.28 0.05 22);
61+
--accent-foreground: oklch(0.82 0.08 22);
62+
--destructive: oklch(0.56 0.13 25);
63+
--destructive-foreground: oklch(0.99 0.002 60);
64+
--border: oklch(0.26 0.006 260);
65+
--input: oklch(0.23 0.006 260);
66+
--ring: oklch(0.58 0.13 22);
67+
--chart-1: oklch(0.6 0.12 22);
68+
--chart-2: oklch(0.68 0.09 162);
69+
--chart-3: oklch(0.72 0.1 70);
70+
--chart-4: oklch(0.6 0.08 240);
71+
--chart-5: oklch(0.64 0.12 16);
72+
--sidebar: oklch(0.17 0.006 260);
73+
--sidebar-foreground: oklch(0.93 0.004 260);
74+
--sidebar-primary: oklch(0.58 0.13 22);
75+
--sidebar-primary-foreground: oklch(0.99 0.002 60);
76+
--sidebar-accent: oklch(0.23 0.006 260);
77+
--sidebar-accent-foreground: oklch(0.93 0.004 260);
78+
--sidebar-border: oklch(0.26 0.006 260);
79+
--sidebar-ring: oklch(0.58 0.13 22);
80+
81+
--grid-color: oklch(0.23 0.006 260);
82+
}
83+
84+
@theme inline {
85+
--font-sans: var(--font-sans);
86+
--font-mono: var(--font-mono);
87+
--color-background: var(--background);
88+
--color-foreground: var(--foreground);
89+
--color-card: var(--card);
90+
--color-card-foreground: var(--card-foreground);
91+
--color-popover: var(--popover);
92+
--color-popover-foreground: var(--popover-foreground);
93+
--color-primary: var(--primary);
94+
--color-primary-foreground: var(--primary-foreground);
95+
--color-secondary: var(--secondary);
96+
--color-secondary-foreground: var(--secondary-foreground);
97+
--color-muted: var(--muted);
98+
--color-muted-foreground: var(--muted-foreground);
99+
--color-accent: var(--accent);
100+
--color-accent-foreground: var(--accent-foreground);
101+
--color-destructive: var(--destructive);
102+
--color-destructive-foreground: var(--destructive-foreground);
103+
--color-border: var(--border);
104+
--color-input: var(--input);
105+
--color-ring: var(--ring);
106+
--color-chart-1: var(--chart-1);
107+
--color-chart-2: var(--chart-2);
108+
--color-chart-3: var(--chart-3);
109+
--color-chart-4: var(--chart-4);
110+
--color-chart-5: var(--chart-5);
111+
--radius-sm: calc(var(--radius) - 4px);
112+
--radius-md: calc(var(--radius) - 2px);
113+
--radius-lg: var(--radius);
114+
--radius-xl: calc(var(--radius) + 4px);
115+
--color-sidebar: var(--sidebar);
116+
--color-sidebar-foreground: var(--sidebar-foreground);
117+
--color-sidebar-primary: var(--sidebar-primary);
118+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
119+
--color-sidebar-accent: var(--sidebar-accent);
120+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
121+
--color-sidebar-border: var(--sidebar-border);
122+
--color-sidebar-ring: var(--sidebar-ring);
123+
}
124+
125+
@layer base {
126+
* {
127+
@apply border-border outline-ring/50;
128+
}
129+
body {
130+
@apply bg-background text-foreground;
131+
}
132+
}
133+
134+
/* Canvas grid background */
135+
.canvas-grid {
136+
background-image:
137+
linear-gradient(to right, var(--grid-color) 1px, transparent 1px),
138+
linear-gradient(to bottom, var(--grid-color) 1px, transparent 1px);
139+
background-size: 24px 24px;
140+
}
141+
142+
.canvas-grid-lg {
143+
background-image:
144+
linear-gradient(to right, var(--grid-color) 1px, transparent 1px),
145+
linear-gradient(to bottom, var(--grid-color) 1px, transparent 1px);
146+
background-size: 40px 40px;
147+
}
148+
149+
/* Scrollbar styling */
150+
.thin-scrollbar::-webkit-scrollbar {
151+
width: 6px;
152+
height: 6px;
153+
}
154+
.thin-scrollbar::-webkit-scrollbar-track {
155+
background: transparent;
156+
}
157+
.thin-scrollbar::-webkit-scrollbar-thumb {
158+
background: var(--border);
159+
border-radius: 3px;
160+
}
161+
.thin-scrollbar::-webkit-scrollbar-thumb:hover {
162+
background: var(--muted-foreground);
163+
}

app/layout.tsx

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import type { Metadata } from "next"
2+
import { Inter, JetBrains_Mono, Sarabun, Prompt } from "next/font/google"
3+
import { Analytics } from "@vercel/analytics/next"
4+
import { ThemeProvider } from "@/components/theme-provider"
5+
import { Toaster } from "@/components/ui/sonner"
6+
import "./globals.css"
7+
8+
const inter = Inter({
9+
subsets: ["latin"],
10+
variable: "--font-sans",
11+
display: "swap",
12+
})
13+
const jetbrainsMono = JetBrains_Mono({
14+
subsets: ["latin"],
15+
variable: "--font-mono",
16+
display: "swap",
17+
})
18+
const sarabun = Sarabun({
19+
weight: ["300", "400", "500", "600", "700"],
20+
subsets: ["thai", "latin"],
21+
variable: "--font-sarabun",
22+
display: "swap",
23+
})
24+
const prompt = Prompt({
25+
weight: ["300", "400", "500", "600", "700"],
26+
subsets: ["thai", "latin"],
27+
variable: "--font-prompt",
28+
display: "swap",
29+
})
30+
31+
export const metadata: Metadata = {
32+
title: "WatchDocs — Productivity & Network Workspace",
33+
description:
34+
"WatchDocs is a high-tech workspace for automation, document preview, fast notes, and network site survey diagrams.",
35+
generator: "v0.app",
36+
icons: {
37+
icon: [
38+
{ url: '/favicon.ico' },
39+
{ url: '/favicon.png', type: 'image/png' },
40+
],
41+
apple: '/favicon.png',
42+
},
43+
manifest: "/manifest.json",
44+
appleWebApp: {
45+
capable: true,
46+
statusBarStyle: "black-translucent",
47+
title: "WatchDocs",
48+
},
49+
}
50+
51+
export const viewport = {
52+
themeColor: [
53+
{ media: "(prefers-color-scheme: light)", color: "#fafafa" },
54+
{ media: "(prefers-color-scheme: dark)", color: "#0a0a0c" },
55+
],
56+
}
57+
58+
export default function RootLayout({
59+
children,
60+
}: Readonly<{
61+
children: React.ReactNode
62+
}>) {
63+
return (
64+
<html lang="en" suppressHydrationWarning className="bg-background">
65+
<body className={`${inter.variable} ${jetbrainsMono.variable} ${sarabun.variable} ${prompt.variable} font-sans antialiased bg-background text-foreground`}>
66+
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem disableTransitionOnChange>
67+
{children}
68+
<Toaster />
69+
</ThemeProvider>
70+
{process.env.NODE_ENV === "production" && <Analytics />}
71+
</body>
72+
</html>
73+
)
74+
}

app/page.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"use client"
2+
3+
import { useState } from "react"
4+
import { Navbar, type ViewKey } from "@/components/watchdocs/navbar"
5+
import { StatusBar } from "@/components/watchdocs/status-bar"
6+
import { AutomationPlayground } from "@/components/watchdocs/automation-playground"
7+
import { PreviewView } from "@/components/watchdocs/preview-view"
8+
import { FastNote } from "@/components/watchdocs/fast-note"
9+
import { PlaygroundDiagram } from "@/components/watchdocs/playground-diagram"
10+
11+
export default function Page() {
12+
const [view, setView] = useState<ViewKey>("automation")
13+
const [previewMode, setPreviewMode] = useState<"markdown" | "html">("markdown")
14+
15+
return (
16+
<div className="flex h-dvh w-full flex-col overflow-hidden bg-background text-foreground">
17+
<Navbar
18+
view={view}
19+
previewMode={previewMode}
20+
onViewChange={(v, mode) => {
21+
setView(v)
22+
if (mode) setPreviewMode(mode)
23+
}}
24+
/>
25+
<main className="relative flex-1 overflow-hidden">
26+
{view === "automation" && <AutomationPlayground />}
27+
{view === "preview" && <PreviewView mode={previewMode} onModeChange={setPreviewMode} />}
28+
{view === "fastnote" && <FastNote />}
29+
{view === "diagram" && <PlaygroundDiagram />}
30+
</main>
31+
<StatusBar view={view} previewMode={previewMode} />
32+
</div>
33+
)
34+
}

components.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "new-york",
4+
"rsc": true,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "",
8+
"css": "app/globals.css",
9+
"baseColor": "neutral",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"aliases": {
14+
"components": "@/components",
15+
"utils": "@/lib/utils",
16+
"ui": "@/components/ui",
17+
"lib": "@/lib",
18+
"hooks": "@/hooks"
19+
},
20+
"iconLibrary": "lucide"
21+
}

components/theme-provider.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use client'
2+
3+
import * as React from 'react'
4+
import {
5+
ThemeProvider as NextThemesProvider,
6+
type ThemeProviderProps,
7+
} from 'next-themes'
8+
9+
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
10+
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
11+
}

0 commit comments

Comments
 (0)