├── .env
├── .eslintrc.json
├── .gitignore
├── .vscode
└── settings.json
├── README.md
├── app
├── globals.css
├── layout.tsx
└── page.tsx
├── components
└── ui
│ ├── alert.tsx
│ ├── avatar.tsx
│ ├── badge.tsx
│ ├── button.tsx
│ ├── card.tsx
│ ├── checkbox.tsx
│ ├── colorPicker.tsx
│ ├── editable-text-field.tsx
│ ├── input.tsx
│ ├── label.tsx
│ ├── progress.tsx
│ ├── select.tsx
│ ├── slider.tsx
│ ├── switch.tsx
│ └── tabs.tsx
├── lib
├── colors.ts
├── useClickOutside.ts
└── utils.ts
├── next.config.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
├── next.svg
└── vercel.svg
├── tailwind.config.js
└── tsconfig.json
/.env:
--------------------------------------------------------------------------------
1 | NEXT_PUBLIC_APP_URL=http://localhost:3000
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env*.local
29 |
30 | # vercel
31 | .vercel
32 |
33 | # typescript
34 | *.tsbuildinfo
35 | next-env.d.ts
36 |
37 | .vercel
38 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "..\\node_modules\\.pnpm\\typescript@5.0.4\\node_modules\\typescript\\lib",
3 | "typescript.enablePromptUseWorkspaceTsdk": true
4 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | work in progress
--------------------------------------------------------------------------------
/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | @layer base {
6 |
7 | :root {
8 | --background: 0 0% 100%;
9 | --foreground: 222.2 47.4% 11.2%;
10 |
11 | --muted: 210 40% 96.1%;
12 | --muted-foreground: 215.4 16.3% 46.9%;
13 |
14 | --popover: 0 0% 100%;
15 | --popover-foreground: 222.2 47.4% 11.2%;
16 |
17 | --card: 0 0% 100%;
18 | --card-foreground: 222.2 47.4% 11.2%;
19 |
20 | --border: 214.3 31.8% 91.4%;
21 | --input: 214.3 31.8% 91.4%;
22 |
23 | --primary: 222.2 47.4% 11.2%;
24 | --primary-foreground: 210 40% 98%;
25 |
26 | --secondary: 210 40% 96.1%;
27 | --secondary-foreground: 222.2 47.4% 11.2%;
28 |
29 | --accent: 210 40% 96.1%;
30 | --accent-foreground: 222.2 47.4% 11.2%;
31 |
32 | --destructive: 0 100% 50%;
33 | --destructive-foreground: 210 40% 98%;
34 |
35 | --ring: 215 20.2% 65.1%;
36 |
37 | --radius: 0.5rem;
38 | }
39 |
40 | .dark {
41 | --background: 224 71% 4%;
42 | --foreground: 213 31% 91%;
43 |
44 | --muted: 223 47% 11%;
45 | --muted-foreground: 215.4 16.3% 56.9%;
46 |
47 | --popover: 224 71% 4%;
48 | --popover-foreground: 215 20.2% 65.1%;
49 |
50 | --card: 0 0% 100%;
51 | --card-foreground: 222.2 47.4% 11.2%;
52 |
53 | --border: 216 34% 17%;
54 | --input: 216 34% 17%;
55 |
56 | --primary: 210 40% 98%;
57 | --primary-foreground: 222.2 47.4% 1.2%;
58 |
59 | --secondary: 222.2 47.4% 11.2%;
60 | --secondary-foreground: 210 40% 98%;
61 |
62 | --accent: 216 34% 17%;
63 | --accent-foreground: 210 40% 98%;
64 |
65 | --destructive: 0 63% 31%;
66 | --destructive-foreground: 210 40% 98%;
67 |
68 | --ring: 216 34% 17%;
69 |
70 | --radius: 0.5rem;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import './globals.css'
2 | import { Inter } from 'next/font/google'
3 |
4 | const inter = Inter({ subsets: ['latin'] })
5 |
6 | export const metadata = {
7 | title: 'Create Next App',
8 | description: 'Generated by create next app',
9 | }
10 |
11 | export default function RootLayout({
12 | children,
13 | }: {
14 | children: React.ReactNode
15 | }) {
16 | return (
17 |
18 |
{children}
19 |
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/app/page.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import { Button } from '@/components/ui/button'
4 | import { Input } from '@/components/ui/input'
5 | import { useState } from 'react'
6 | import { generatePalette, hexToHSL } from '@/lib/colors'
7 | import { CopyBlock, dracula } from "react-code-blocks";
8 | import { Progress } from '@/components/ui/progress'
9 | import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@/components/ui/card'
10 | import { Switch } from '@/components/ui/switch'
11 | import { Badge } from '@/components/ui/badge'
12 | import { Slider } from '@/components/ui/slider'
13 | import { ColorPicker } from '@/components/ui/colorPicker'
14 | import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
15 | import { Label } from "@/components/ui/label"
16 | import { Alert, AlertTitle, AlertDescription } from '@/components/ui/alert'
17 | import { AlertCircle } from 'lucide-react'
18 | import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from '@/components/ui/select'
19 | import { Configuration, OpenAIApi } from "openai"
20 | import toast, { Toaster } from 'react-hot-toast'
21 |
22 | let baseCSS = `
23 | :root {
24 | --background: 0 0% 100%;
25 | --foreground: 222.2 47.4% 11.2%;
26 |
27 | --muted: 210 40% 96.1%;
28 | --muted-foreground: 215.4 16.3% 46.9%;
29 |
30 | --popover: 0 0% 100%;
31 | --popover-foreground: 222.2 47.4% 11.2%;
32 |
33 | --card: 0 0% 100%;
34 | --card-foreground: 222.2 47.4% 11.2%;
35 |
36 | --border: 214.3 31.8% 91.4%;
37 | --input: 214.3 31.8% 91.4%;
38 |
39 | --primary: 222.2 47.4% 11.2%;
40 | --primary-foreground: 210 40% 98%;
41 |
42 | --secondary: 210 40% 96.1%;
43 | --secondary-foreground: 222.2 47.4% 11.2%;
44 |
45 | --accent: 210 40% 96.1%;
46 | --accent-foreground: 222.2 47.4% 11.2%;
47 |
48 | --destructive: 0 100% 50%;
49 | --destructive-foreground: 210 40% 98%;
50 |
51 | --ring: 215 20.2% 65.1%;
52 |
53 | --radius: 0.5rem;
54 | }
55 |
56 | `
57 |
58 | export default function Home() {
59 | const [currentPrimaryColor, setCurrentPrimaryColor] = useState('#0f172a')
60 | const [currentSecondaryColor, setCurrentSecondaryColor] = useState('#f1f5f9')
61 | const [currentForegroundColor, setCurrentForegroundColor] = useState('#0f172a')
62 | const [currentBackgroundColor, setCurrentBackgroundColor] = useState('#ffffff')
63 | const [currentDestructiveColor, setCurrentDestructiveColor] = useState('#ff0000')
64 | const [currentAccentColor, setCurrentAccentColor] = useState('#532355')
65 | const [currentMutedColor, setCurrentMutedColor] = useState('#f1f5f9')
66 | const [currentOpenApiKey, setCurrentOpenApiKey] = useState('')
67 | const [currentOpenApiModel, setCurrentOpenApiModel] = useState('gpt-3.5-turbo')
68 | const [currentTheme, setCurrentTheme] = useState('light')
69 | const [currentCSS, setCurrentCSS] = useState(baseCSS)
70 |
71 | return (
72 | <>
73 |
76 | Generate your theme
77 |
78 |
79 |
80 |
81 | Manually
82 | ChatGPT
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
130 |
131 |
132 |
133 |
144 |
145 |
146 | setCurrentOpenApiKey(e.target.value)} />
147 |
148 |
149 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
254 |
255 | Change your password here.
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
Preview
264 |
265 |
266 |
267 |
268 |
269 | Notifications
270 | You have 3 unread messages.
271 |
272 |
273 |
274 |
275 |
276 |
277 | Push Notifications
278 |
279 |
280 | Send notifications to device.
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
292 |
295 |
298 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 | Account
312 | Password
313 |
314 |
315 |
316 |
317 | Account
318 |
319 | Make changes to your account here. Click save when you are done.
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 | Password
341 |
342 | Change your password here. After saving, you will be logged out.
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
Badge
364 |
365 |
366 |
367 | Error
368 |
369 | Your session has expired. Please log in again.
370 |
371 |
372 |
373 |
374 | Error
375 |
376 | Your session has expired. Please log in again.
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
Generated CSS
388 |
389 |
396 |
397 |
398 |
399 |
400 | >
401 | )
402 | }
403 |
--------------------------------------------------------------------------------
/components/ui/alert.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { VariantProps, cva } from "class-variance-authority"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const alertVariants = cva(
7 | "relative w-full rounded-lg border p-4 [&>svg]:absolute [&>svg]:text-foreground [&>svg]:left-4 [&>svg]:top-4 [&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11",
8 | {
9 | variants: {
10 | variant: {
11 | default: "bg-background text-foreground",
12 | destructive:
13 | "text-destructive border-destructive/50 dark:border-destructive [&>svg]:text-destructive text-destructive",
14 | },
15 | },
16 | defaultVariants: {
17 | variant: "default",
18 | },
19 | }
20 | )
21 |
22 | const Alert = React.forwardRef<
23 | HTMLDivElement,
24 | React.HTMLAttributes