Skip to content

Commit caa2775

Browse files
committed
Improved UI/UX + Lazy Loading
1 parent 6c3b431 commit caa2775

25 files changed

Lines changed: 1344 additions & 867 deletions

package-lock.json

Lines changed: 876 additions & 502 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "StackRender",
33
"private": true,
4-
"version": "1.0.2",
4+
"version": "1.3.2",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",
@@ -86,7 +86,7 @@
8686
"@types/react-dom": "18.3.0",
8787
"@typescript-eslint/eslint-plugin": "8.11.0",
8888
"@typescript-eslint/parser": "8.11.0",
89-
"@vitejs/plugin-react": "^6.0.2",
89+
"@vitejs/plugin-react": "^4.2.1",
9090
"autoprefixer": "10.4.19",
9191
"esbuild": "^0.28.0",
9292
"eslint": "^8.57.0",
@@ -102,8 +102,8 @@
102102
"rollup": "^4.61.1",
103103
"tw-animate-css": "^1.3.6",
104104
"typescript": "5.6.3",
105-
"vite": "^8.0.3",
105+
"vite": "^5.2.0",
106106
"vite-plugin-top-level-await": "^1.5.0",
107107
"vite-tsconfig-paths": "^4.3.2"
108108
}
109-
}
109+
}

src/components/clipboard.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,13 @@ const Clipboard: React.FC<ClipboardProps> = ({ text }) => {
4141
}, [text])
4242

4343
return (
44-
<Tooltip>
44+
<Tooltip>
4545
<TooltipTrigger asChild>
4646
<span>
4747
<Button
4848
size="icon"
49-
5049
variant="outline"
51-
className="size-8"
50+
className="w-7 h-7 text-muted-foreground bg-card/50 backdrop-blur-xs dark:backdrop-blur-md shadow-lg"
5251
onClick={copyToClipboard}
5352
>
5453
{

src/components/code-editor.tsx

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import React, { useEffect, useState } from "react";
2+
import { useTheme } from "@/providers/theme-provider/theme-provider";
3+
import { cn } from "@/lib/utils";
4+
import { Spinner } from "./ui/shadcn-io/spinner";
5+
6+
interface CodeEditorProps {
7+
defaultValue?: string;
8+
value?: string;
9+
className?: string | undefined,
10+
readOnly?: boolean,
11+
onChange?: (sql: string) => void
12+
}
13+
14+
const CodeEditor: React.FC<CodeEditorProps> = ({
15+
defaultValue,
16+
value,
17+
className,
18+
readOnly = false,
19+
onChange
20+
}) => {
21+
22+
23+
const [editor, setEditor] = useState<any>(null);
24+
25+
useEffect(() => {
26+
27+
let mounted = true;
28+
29+
Promise.all([
30+
import("@uiw/react-codemirror"),
31+
import("@codemirror/lang-sql"),
32+
import("@codemirror/view"),
33+
]).then(([cm, sqlLang, view]) => {
34+
35+
if (!mounted) return;
36+
37+
const overrideDarkTheme = view.EditorView.theme({
38+
39+
'.cm-content': {
40+
backgroundColor: "#1c2025",
41+
},
42+
".cm-gutter": {
43+
backgroundColor: "#1c2025",
44+
},
45+
46+
".cm-gutterElement": {
47+
color: "#4b515a"
48+
},
49+
50+
".ͼp": {
51+
color: "#A994FF"
52+
},
53+
54+
".cm-line .ͼq": {
55+
color: "#ff6363"
56+
},
57+
".ͼu": {
58+
color: "#B6E672"
59+
},
60+
".ͼv": {
61+
color: "#6cdcc4"
62+
}
63+
}, { dark: true });
64+
65+
const overrideLightTheme = view.EditorView.theme({
66+
67+
".ͼb": {
68+
color: "#2A1D66"
69+
},
70+
".cm-gutterElement": {
71+
color: "#62748e"
72+
},
73+
".cm-gutter": {
74+
backgroundColor: "white",
75+
76+
},
77+
".cm-gutters": {
78+
borderColor: "#f2f4f6"
79+
},
80+
".cm-line": {
81+
color: "#0f172b"
82+
},
83+
84+
})
85+
setEditor({
86+
CodeMirror: cm.default,
87+
oneDark: cm.oneDark,
88+
sql: sqlLang.sql,
89+
overrideDarkTheme,
90+
overrideLightTheme,
91+
});
92+
});
93+
94+
return () => {
95+
mounted = false;
96+
};
97+
}, []);
98+
99+
100+
const { theme } = useTheme();
101+
102+
if (!editor) {
103+
return (
104+
<div
105+
className={cn(
106+
"flex flex-1 w-full min-h-9 rounded-sm border border-border bg-card items-center justify-center",
107+
className
108+
)}
109+
>
110+
<Spinner className="text-primary" />
111+
</div>
112+
);
113+
}
114+
115+
const { CodeMirror, oneDark, sql, overrideDarkTheme, overrideLightTheme } = editor;
116+
return (
117+
<CodeMirror
118+
defaultValue={defaultValue}
119+
value={value}
120+
className={cn("flex flex-1 w-full min-h-9 rounded-sm h-full bg-card border-1 border-border !min-w-0 overflow-hidden", className)}
121+
extensions={[sql()]}
122+
readOnly={readOnly}
123+
theme={theme != "dark" ? overrideLightTheme : [oneDark, overrideDarkTheme]}
124+
onChange={onChange}
125+
/>
126+
)
127+
}
128+
129+
130+
export default React.memo(CodeEditor);

src/components/layout/app-sidebar/app-sidebar.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
1616
const sidebarData = useSidebarData();
1717
const { openController } = useDiagramOps();
1818
return (
19-
<Sidebar collapsible='icon' variant='floating' {...props} className='bg-card border-r' >
19+
<Sidebar collapsible='icon' {...props} >
2020
<SidebarHeader>
21-
<div className='flex items-center'>
21+
<div className='flex items-center gap-2'>
2222
<img
23-
className='w-8 h-8 p-[6px] rounded-md '
23+
className='w-8 p-[4px] rounded-md '
2424
src='/stackrender.png'
2525
/>
2626
<h3 className='data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground truncate font-semibold text-sm '>

src/features/dashboard/index.tsx

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
1+
22
import { Outlet } from "react-router-dom";
3-
import { SidebarProvider } from "@/components/ui/sidebar";
4-
import { cn } from "@/lib/utils";
3+
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
54
import { AppSidebar } from "@/components/layout/app-sidebar/app-sidebar";
65
import { Header } from "@/components/header";
76

@@ -14,24 +13,20 @@ interface Props {
1413
const Dashboard: React.FC<Props> = ({ children }) => {
1514
return (
1615
<SidebarProvider defaultOpen={false}>
17-
<AppSidebar />
18-
<div
19-
id='content'
20-
className={cn(
21-
'ml-auto w-full max-w-full',
22-
'peer-data-[state=collapsed]:w-[calc(100%-var(--sidebar-width-icon)-1rem)]',
23-
'peer-data-[state=expanded]:w-[calc(100%-var(--sidebar-width))]',
24-
'sm:transition-[width] sm:duration-200 sm:ease-linear',
25-
'flex h-svh flex-col',
26-
'group-data-[scroll-locked=1]/body:h-full',
27-
'has-[main.fixed-main]:group-data-[scroll-locked=1]/body:h-svh'
28-
)}
29-
>
30-
<Header className="bg-card border-b pl-3"/>
31-
{
32-
children ? children : <Outlet />
33-
}
34-
</div>
16+
<AppSidebar variant="inset" />
17+
{/* dark:p-0 dark:border-l-1 */}
18+
<SidebarInset className=" overflow-hidden max-h-screen flex flex-col flex-1 !m-0 !rounded-none bg-sidebar p-1 ">
19+
{/*dark:border-none dark:rounded-none */}
20+
<div className="border-4 border-sidebar-border ring-1 ring-border/30 dark:!border-background dark:ring-sidebar-border flex flex-col min-h-0 !overflow-hidden rounded-2xl h-screen">
21+
<div className="overflow-hidden h-full flex flex-col flex-1 bg-white dark:bg-background dark:!border-1 dark:border-sidebar-border dark:rounded-[14px] !overflow-hidden" >
22+
<Header className="bg-card border-b pl-3" />
23+
{
24+
children ? children : <Outlet />
25+
}
26+
</div>
27+
</div>
28+
29+
</SidebarInset>
3530

3631
</SidebarProvider>
3732
)

src/features/database/components/cardinality-marker.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ const CardinalityMarker: React.FC<CardinalityMarkerProps> = ({ selected = false,
4848
>
4949
<svg
5050
fill="transparent"
51-
className={selected ? "stroke-ring dark:!stroke-primary-foreground" : "stroke-ring/60 dark:!stroke-muted-foreground/60"}
52-
strokeWidth="4"
51+
className={selected ? ' !stroke-[oklch(0.60_0.028_263.3984)] dark:!stroke-primary-foreground' : 'stroke-[oklch(0.72_0.022_263.3984)] dark:!stroke-muted-foreground'}
52+
strokeWidth="6"
5353
width="24"
5454
height="24"
5555
viewBox="0 0 100 100">
@@ -74,24 +74,24 @@ const CardinalityMarker: React.FC<CardinalityMarkerProps> = ({ selected = false,
7474
<circle
7575
cx="12"
7676
cy="12"
77-
r="8"
77+
r="6"
7878
strokeWidth="1"
7979
className={
80-
cn(" fill-background",
81-
selected ? " stroke-ring fill-background dark:!stroke-primary-foreground" :
82-
" stroke-ring/60 dark:!stroke-muted-foreground "
80+
cn(" fill-background ",
81+
selected ? " stroke-[oklch(0.60_0.028_263.3984)] fill-background dark:!stroke-primary-foreground" :
82+
" stroke-[oklch(0.72_0.022_263.3984)] dark:!stroke-muted-foreground "
8383
)
8484
}
8585
/>
8686
<text
8787
x="12"
88-
y="13"
88+
y="12.5"
8989
textAnchor="middle"
9090
dominantBaseline="middle"
91-
fontSize="8"
91+
fontSize="6"
9292
className={
93-
cn("fill-ring/60 font-semibold dark:!fill-muted-foreground" ,
94-
selected ? "fill-ring dark:!fill-primary-foreground" : "" ,
93+
cn("fill-[oklch(0.72_0.022_263.3984)] font-semibold dark:!fill-muted-foreground" ,
94+
selected ? "fill-[oklch(0.60_0.028_263.3984)] dark:!fill-primary-foreground" : "" ,
9595
)
9696
}
9797
>

src/features/database/components/database-control-buttons.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { useDatabaseHistory } from "@/providers/database-history/database-histor
99
import { useOnViewportChange, useReactFlow } from "@xyflow/react";
1010

1111
import { LayoutGrid, Redo, Scan, Undo, ZoomIn, ZoomOut } from "lucide-react";
12-
import { useCallback, useState } from "react";
12+
import { useCallback, useState } from "react";
1313
import { useTranslation } from "react-i18next";
1414

1515
interface DbControlButtons {
@@ -58,8 +58,8 @@ const DatabaseControlButtons: React.FC<DbControlButtons> = ({ adjustPositions })
5858
}, []);
5959

6060
return (
61-
<div className="flex !rounded-md p-2 border-1 !overflow-hidden !bg-background/20 dark:!bg-card/20 text-muted-foreground shadow-md backdrop-blur-sm"
62-
>
61+
<div className="flex !rounded-md p-2 border-1 !overflow-hidden !bg-input/50 dark:!bg-card/50 text-muted-foreground shadow-md backdrop-blur-xs dark:backdrop-blur-md">
62+
6363
<Tooltip>
6464
<TooltipTrigger asChild>
6565
<span>

src/features/database/components/database-diagram.tsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import { Modals } from "@/providers/modal-provider/modal-contxet";
5252
import { useModal } from "@/providers/modal-provider/modal-provider";
5353
import { useIsMobile } from "@/hooks/use-mobile";
5454
import { cn } from "@/lib/utils";
55+
import useToast from "@/hooks/use-toast";
5556

5657

5758

@@ -72,7 +73,7 @@ const DatabaseDiagram: React.FC = () => {
7273

7374
// Diagram-related state (e.g. connection in progress)
7475
const { setIsConnectionInProgress, cardinalityStyle, showController, openController } = useDiagramOps();
75-
76+
const raise = useToast() ;
7677
// Destructure tables and relationships from database
7778
const { tables, relationships } = database || { tables: [], relationships: [] };
7879

@@ -145,13 +146,11 @@ const DatabaseDiagram: React.FC = () => {
145146
} else {
146147

147148

148-
toast(t("db_controller.invalid_relationship.title"), {
149-
description: t("db_controller.invalid_relationship.description"),
150-
classNames: {
151-
description: "!text-destructive",
152-
title: "!text-destructive"
153-
},
154-
})
149+
raise(
150+
t("db_controller.invalid_relationship.title"),
151+
t("db_controller.invalid_relationship.description"),
152+
"ERROR"
153+
)
155154
}
156155

157156
setIsConnectionInProgress(false);
@@ -266,17 +265,18 @@ const DatabaseDiagram: React.FC = () => {
266265
</Controls >
267266
<MiniMap
268267
nodeStrokeWidth={4}
269-
className="!bg-background border-1 rounded-lg overflow-hidden "
270-
maskStrokeColor={resolvedTheme == "dark" ? "#FFFFFF1A" : "#e2e8f0"}
271-
maskColor={resolvedTheme == "dark" ? "#21262d77" : "#62748e05"}
268+
className="!bg-input/50 ring-1 ring-border shadow-sm rounded-md overflow-hidden shadow-md backdrop-blur-xs dark:!bg-background/50 "
269+
maskStrokeColor={resolvedTheme == "dark" ? "#FFFFFF1A" : "#cad5e2"}
270+
maskColor={resolvedTheme == "dark" ? "#21262d88" : "#f1f5f9cc"}
272271
maskStrokeWidth={1}
273-
nodeClassName={"!fill-muted-foreground/20 "}
272+
273+
nodeClassName={"!fill-foreground/20 "}
274274
style={{
275-
width: 164,
275+
width: 148,
276276
height: 128
277277
}}
278278
/>
279-
<Background color="#62748e" className="dark:!bg-background " />
279+
<Background color="#62748e" className="!bg-background dark:!bg-background" />
280280

281281
</ReactFlow>
282282
<div

src/features/database/components/db-controller/circular-dependecy-alert.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const CircularDependencyAlert: React.FC<CircularDependencyAlertProps> = ({ error
5252
deleteRelationship(id)
5353
}, [])
5454
return (
55-
<div className="flex flex-col gap-2 w-full h-full items-center pt-12 ">
55+
<div className="flex flex-col gap-2 w-full h-full items-center pt-12 ">
5656
<AlertTriangle
5757
className="size-12 text-destructive"
5858
/>
@@ -63,14 +63,14 @@ const CircularDependencyAlert: React.FC<CircularDependencyAlertProps> = ({ error
6363
{t("db_controller.circular_dependency.description")} , <span className="font-medium text-foreground"> {t("db_controller.circular_dependency.suggestion")} </span>
6464
</p>
6565

66-
<ul aria-label="Relationships" className="w-[80%] max-w-[360px]"
66+
<ul aria-label="Relationships" className="w-[80%] max-w-[360px] mt-4"
6767
>
6868
{
6969
circularRelationships.map((relationship: RelationshipType) => (
7070
<li
7171
onClick={() => focus(relationship.id)}
7272
key={relationship.id}>
73-
<div className="hover:bg-secondary flex items-center justify-between h-10 mb-2 px-3 rounded-md cursor-pointer">
73+
<div className="hover:bg-secondary flex items-center justify-between h-10 mb-2 px-3 rounded-md cursor-pointer bg-card border-1">
7474
<span className="text-sm">
7575
{relationship.sourceTable.name} -&gt; {relationship.targetTable.name}
7676
</span>

0 commit comments

Comments
 (0)