From 0028fcffc73454e1f8ec0e695dfb75703a682a02 Mon Sep 17 00:00:00 2001 From: Zakher Masri Date: Tue, 11 Mar 2025 16:38:13 +0300 Subject: [PATCH] chore(ui): improve template dialog --- app/index.html | 2 +- app/package.json | 20 +-- app/pnpm-lock.yaml | 57 ++++++++ app/src/components/TemplateGrid.tsx | 217 ++++++++++++++++------------ app/src/components/ui/dialog.tsx | 4 +- app/src/components/ui/label.tsx | 22 +++ app/src/components/ui/tabs.tsx | 64 ++++++++ app/src/store/index.ts | 4 +- 8 files changed, 282 insertions(+), 108 deletions(-) create mode 100644 app/src/components/ui/label.tsx create mode 100644 app/src/components/ui/tabs.tsx diff --git a/app/index.html b/app/index.html index 4600ddf..84e5e3a 100644 --- a/app/index.html +++ b/app/index.html @@ -2,7 +2,7 @@ - + Dokploy Blueprints diff --git a/app/package.json b/app/package.json index bc134e9..5079b01 100644 --- a/app/package.json +++ b/app/package.json @@ -10,10 +10,20 @@ "preview": "vite preview" }, "dependencies": { + "@codemirror/autocomplete": "^6.18.6", + "@codemirror/lang-json": "^6.0.1", + "@codemirror/lang-yaml": "^6.1.1", + "@codemirror/language": "^6.10.1", + "@codemirror/legacy-modes": "6.4.0", + "@codemirror/view": "6.29.0", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-dropdown-menu": "^2.1.6", + "@radix-ui/react-label": "^2.1.2", "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-tabs": "^1.1.3", "@tailwindcss/vite": "^4.0.12", + "@uiw/codemirror-theme-github": "^4.22.1", + "@uiw/react-codemirror": "^4.22.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "copy-to-clipboard": "^3.3.3", @@ -25,15 +35,7 @@ "tailwind-merge": "^3.0.2", "tailwindcss": "^4.0.12", "tailwindcss-animate": "^1.0.7", - "vite-plugin-static-copy": "2.3.0", - "@codemirror/autocomplete": "^6.18.6", - "@codemirror/lang-json": "^6.0.1", - "@codemirror/lang-yaml": "^6.1.1", - "@codemirror/language": "^6.10.1", - "@codemirror/legacy-modes": "6.4.0", - "@codemirror/view": "6.29.0", - "@uiw/codemirror-theme-github": "^4.22.1", - "@uiw/react-codemirror": "^4.22.1" + "vite-plugin-static-copy": "2.3.0" }, "devDependencies": { "@types/node": "^20.8.2", diff --git a/app/pnpm-lock.yaml b/app/pnpm-lock.yaml index a7869dd..3358923 100644 --- a/app/pnpm-lock.yaml +++ b/app/pnpm-lock.yaml @@ -32,9 +32,15 @@ importers: '@radix-ui/react-dropdown-menu': specifier: ^2.1.6 version: 2.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@radix-ui/react-slot': specifier: ^1.1.2 version: 1.1.2(@types/react@19.0.10)(react@19.0.0) + '@radix-ui/react-tabs': + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@tailwindcss/vite': specifier: ^4.0.12 version: 4.0.12(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)) @@ -567,6 +573,19 @@ packages: '@types/react': optional: true + '@radix-ui/react-label@2.1.2': + resolution: {integrity: sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-menu@2.1.6': resolution: {integrity: sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==} peerDependencies: @@ -654,6 +673,19 @@ packages: '@types/react': optional: true + '@radix-ui/react-tabs@1.1.3': + resolution: {integrity: sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-use-callback-ref@1.1.0': resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} peerDependencies: @@ -1883,6 +1915,15 @@ snapshots: optionalDependencies: '@types/react': 19.0.10 + '@radix-ui/react-label@2.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + optionalDependencies: + '@types/react': 19.0.10 + '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@radix-ui/react-menu@2.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: '@radix-ui/primitive': 1.1.1 @@ -1980,6 +2021,22 @@ snapshots: optionalDependencies: '@types/react': 19.0.10 + '@radix-ui/react-tabs@1.1.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) + '@radix-ui/react-direction': 1.1.0(@types/react@19.0.10)(react@19.0.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + optionalDependencies: + '@types/react': 19.0.10 + '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@radix-ui/react-use-callback-ref@1.1.0(@types/react@19.0.10)(react@19.0.0)': dependencies: react: 19.0.0 diff --git a/app/src/components/TemplateGrid.tsx b/app/src/components/TemplateGrid.tsx index d44cf0a..c163d67 100644 --- a/app/src/components/TemplateGrid.tsx +++ b/app/src/components/TemplateGrid.tsx @@ -17,9 +17,11 @@ import { import { Button } from "./ui/button"; import { toast } from "sonner"; import copy from "copy-to-clipboard"; -import { ModeToggle } from "../mode-toggle"; import { CodeEditor } from "./ui/code-editor"; import { useStore } from "../store"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs"; +import { Label } from "./ui/label"; +import { Clipboard } from "lucide-react"; interface Template { id: string; @@ -234,8 +236,8 @@ const TemplateGrid: React.FC = () => { open={!!selectedTemplate} onOpenChange={() => setSelectedTemplate(null)} > - - + +
{selectedTemplate?.logo && ( {
+
+ +
{selectedTemplate?.description} @@ -299,99 +304,123 @@ const TemplateGrid: React.FC = () => { ))}
-
- {modalLoading ? ( -
-
-

Loading template files...

-
- ) : ( -
- {templateFiles?.dockerCompose && ( -
-

- Docker Compose - - docker-compose.yml - -

- - -
- )} - {templateFiles?.config && ( -
-

- Configuration - - template.yml - -

- - - -
- )} - {(templateFiles?.dockerCompose || templateFiles?.config) && ( -
-

- Base64 Configuration - - Encoded template files - -

-
- - + {modalLoading ? ( +
+
+

Loading template files...

+
+ ) : ( +
+ {(templateFiles?.dockerCompose || templateFiles?.config) && ( +
+ +
+ + +
-
- )} - {!templateFiles?.dockerCompose && !templateFiles?.config && ( -
-

- No configuration files available for this template. -

-
- )} -
- )} + )} + + + + Docker Compose + + Configuration + + + {templateFiles?.dockerCompose && ( +
+ + + + +
+ )} +
+ + + {templateFiles?.config && ( +
+ + + + + +
+ )} +
+
+ + {!templateFiles?.dockerCompose && !templateFiles?.config && ( +
+

+ No configuration files available for this template. +

+
+ )} +
+ )} +
diff --git a/app/src/components/ui/dialog.tsx b/app/src/components/ui/dialog.tsx index 1b608b2..d02c292 100644 --- a/app/src/components/ui/dialog.tsx +++ b/app/src/components/ui/dialog.tsx @@ -61,8 +61,8 @@ function DialogContent({ {...props} > {children} - - + + Close diff --git a/app/src/components/ui/label.tsx b/app/src/components/ui/label.tsx new file mode 100644 index 0000000..ef7133a --- /dev/null +++ b/app/src/components/ui/label.tsx @@ -0,0 +1,22 @@ +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" + +import { cn } from "@/lib/utils" + +function Label({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { Label } diff --git a/app/src/components/ui/tabs.tsx b/app/src/components/ui/tabs.tsx new file mode 100644 index 0000000..83abc89 --- /dev/null +++ b/app/src/components/ui/tabs.tsx @@ -0,0 +1,64 @@ +import * as React from "react"; +import * as TabsPrimitive from "@radix-ui/react-tabs"; + +import { cn } from "@/lib/utils"; + +function Tabs({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function TabsList({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function TabsTrigger({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function TabsContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +export { Tabs, TabsList, TabsTrigger, TabsContent }; diff --git a/app/src/store/index.ts b/app/src/store/index.ts index f80640d..fb7c819 100644 --- a/app/src/store/index.ts +++ b/app/src/store/index.ts @@ -1,4 +1,4 @@ -import { create } from 'zustand' +import { create } from "zustand"; interface Template { id: string; @@ -26,4 +26,4 @@ export const useStore = create((set) => ({ setTemplates: (templates) => set({ templates }), githubStars: 0, setGithubStars: (count) => set({ githubStars: count }), -})) \ No newline at end of file +}));