initial template
Seto Elkahfi committed
Jul 31, 2024 at 00:17 UTC
1967bad27b599c1592737e2c36ca04cdb26b5848
15 files changed
+183
-200
frontend/splitfire-desktop/README.md
+5
-1
@@ -4,11 +4,15 @@ SplitFire AI is an artificial intelligence app for music enthusiasts. This repo
4
5
## Bazel
6
7
-Run under bazel for more faster iteration:
7
+Run Tauri project under bazel for more faster iteration:
8
```bash
9
bazel run //frontend/splitfire-desktop:dev
10
```
11
12
+Run frontend from the local node:
13
+```bash
14
+npm run next-dev
15
+```
16
## Local development
17
18
Run only the web target:
frontend/splitfire-desktop/app/_lib/menus.ts
+4
-4
@@ -8,12 +8,12 @@ export const menus: { items: Item[] }[] = [
8
{
9
items: [
10
{
11
- name: 'Play',
12
- slug: 'play',
11
+ name: 'Home',
12
+ slug: '',
13
},
14
{
15
- name: 'Chat 🤖',
16
- slug: 'chat',
15
+ name: 'Play',
16
+ slug: 'play',
17
},
18
],
19
},
frontend/splitfire-desktop/app/_ui/address-bar.tsx
+3
-28
@@ -45,34 +45,9 @@ export function AddressBar() {
45
<HomeIcon width={16} />
46
</div>
47
<div className="flex gap-x-1 text-sm font-medium">
48
- {pathname ? (
49
- <>
50
- <span className="text-gray-600">/</span>
51
- {pathname
52
- .split('/')
53
- .slice(1)
54
- .map((segment) => {
55
- return (
56
- <React.Fragment key={segment}>
57
- <span>
58
- <span
59
- key={segment}
60
- className="animate-[highlight_1s_ease-in-out_1] rounded-full px-1.5 py-0.5 text-gray-100"
61
- >
62
- {segment}
63
- </span>
64
- </span>
65
-
66
- <span className="text-gray-600">/</span>
67
- </React.Fragment>
68
- );
69
- })}
70
- </>
71
- ) : null}
72
-
73
- <Suspense>
74
- <Params />
75
- </Suspense>
48
+ <span className="animate-[highlight_1s_ease-in-out_1] text-gray-100">
49
+ {pathname.replaceAll("/", "").toUpperCase()}
50
+ </span>
51
</div>
52
</div>
53
);
frontend/splitfire-desktop/app/_ui/global-nav.tsx
+10
-2
@@ -21,11 +21,11 @@ export function GlobalNav() {
21
onClick={close}
22
>
23
<div className="h-7 w-7 rounded-sm border border-white/30 group-hover:border-white/50">
24
- <Image src="/logo192.png" alt="Tauri on Bazel" width={40} height={40} />
24
+ <Image src="/logo192.png" alt="SplitFire" width={40} height={40} />
25
</div>
26
27
<h3 className="font-semibold tracking-wide text-gray-400 group-hover:text-gray-50">
28
- Tauri on Bazel
28
+ SplitFire
29
</h3>
30
</Link>
31
</div>
@@ -60,9 +60,17 @@ export function GlobalNav() {
60
<GlobalNavItem key={item.slug} item={item} close={close} />
61
))}
62
</div>
63
+
64
</div>
65
);
66
})}
67
+ <div className="mb-2 px-3 text-xs font-semibold uppercase tracking-wider text-gray-400/80">
68
+ <div>{"Account"}</div>
69
+ </div>
70
+
71
+ <div className="space-y-1">
72
+ <GlobalNavItem key={"login"} item={{name: "Login", slug: "login"}} close={close} />
73
+ </div>
74
</nav>
75
</div>
76
</div>
frontend/splitfire-desktop/app/layout.tsx
+8
-2
@@ -1,8 +1,14 @@
1
-'use client'
2
-
1
+import { Metadata } from 'next';
2
import { AddressBar } from './_ui/address-bar';
3
import { GlobalNav } from './_ui/global-nav';
4
import './globals.css';
5
+import { cn } from '@/lib/utils';
6
+
7
+
8
+export const metadata: Metadata = {
9
+ title: "SplitFire",
10
+ description: "an intelligent exression engine.",
11
+};
12
13
export default function RootLayout({
14
children,
frontend/splitfire-desktop/app/login/page.tsx
new
+21
@@ -0,0 +1,21 @@
1
+import Link from "next/link";
2
+
3
+export default function Page() {
4
+ return (
5
+ <div className="space-y-8">
6
+ <h1 className="text-xl font-medium text-gray-300">Login</h1>
7
+ <div className="h-screen w-screen flex justify-center items-center bg-slate-100">
8
+ <div className="sm:shadow-xl px-8 pb-8 pt-12 sm:bg-white rounded-xl space-y-12">
9
+ <h1 className="font-semibold text-2xl">Login</h1>
10
+
11
+ <p className="text-center">
12
+ Need to create an account?{' '}
13
+ <Link className="text-indigo-500 hover:underline" href="/register">
14
+ Create Account
15
+ </Link>{' '}
16
+ </p>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ );
21
+}
frontend/splitfire-desktop/app/play/(checkout)/checkout/page.tsx
deleted
-15
@@ -1,15 +0,0 @@
1
-export async function generateStaticParams() {
2
- const posts = [
3
- { slug: "post-1" },
4
- { slug: "post-2" },
5
- { slug: "post-3" },
6
- ];
7
-
8
- return posts.map((post) => ({
9
- slug: post.slug,
10
- }))
11
-}
12
-
13
-export default function Page() {
14
- return <h1 className="text-xl font-medium text-gray-400/80">Checkout</h1>;
15
-}
frontend/splitfire-desktop/app/play/(checkout)/layout.tsx
deleted
-23
@@ -1,23 +0,0 @@
1
-import { Boundary } from '@/app/_ui/boundary';
2
-import { TabNavItem } from '@/app/_ui/tab-nav-item';
3
-import React from 'react';
4
-
5
-export default function Layout({ children }: { children: React.ReactNode }) {
6
- return (
7
- <Boundary
8
- labels={['checkout layout']}
9
- color="blue"
10
- animateRerendering={false}
11
- >
12
- <div className="space-y-9">
13
- <div className="flex items-center justify-between">
14
- <div className="flex items-center gap-x-4">
15
- <TabNavItem href="/play">Back</TabNavItem>
16
- </div>
17
- </div>
18
-
19
- <div>{children}</div>
20
- </div>
21
- </Boundary>
22
- );
23
-}
frontend/splitfire-desktop/app/play/(checkout)/template.tsx
deleted
-6
@@ -1,6 +0,0 @@
1
-import { Boundary } from '@/app/_ui/boundary';
2
-import React from 'react';
3
-
4
-export default function Template({ children }: { children: React.ReactNode }) {
5
- return <Boundary>{children}</Boundary>;
6
-}
frontend/splitfire-desktop/app/play/layout.tsx
+5
-9
@@ -1,16 +1,12 @@
1
+import { Metadata } from 'next';
2
import React from 'react';
3
3
-const title = 'Nested Layouts';
4
-
5
-export const metadata = {
6
- metadataBase: new URL('https://splitfire.ai'),
7
- title,
8
- openGraph: {
9
- title,
10
- images: [`/api/og?title=${title}`],
11
- },
4
+export const metadata: Metadata = {
5
+ title: "Play",
6
+ description: "an intelligent exression engine.",
7
};
8
9
+
10
export default async function Layout({
11
children,
12
}: {
frontend/splitfire-desktop/package-lock.json
+20
-2
@@ -10,6 +10,7 @@
10
"license": "MIT",
11
"dependencies": {
12
"@heroicons/react": "1.0.6",
13
+ "@radix-ui/react-icons": "^1.3.0",
14
"@radix-ui/react-slot": "^1.0.2",
15
"@radix-ui/react-tooltip": "^1.0.7",
16
"@sentry/react": "^7.12.1",
@@ -24,7 +25,7 @@
25
"axios": "^0.25.0",
26
"bootstrap": "5.1.3",
27
"class-variance-authority": "^0.7.0",
27
- "clsx": "1.2.1",
28
+ "clsx": "^1.2.1",
29
"dexie": "^3.2.0",
30
"dexie-observable": "^3.0.0-beta.11",
31
"eslint": "8.32.0",
@@ -44,7 +45,8 @@
45
"react-textarea-autosize": "^8.5.3",
46
"react-transition-group": "4.x",
47
"react-youtube": "^7.14.0",
47
- "tailwind-merge": "^2.2.1",
48
+ "tailwind-merge": "^2.4.0",
49
+ "tailwindcss-animate": "^1.0.7",
50
"tone": "^14.7.77",
51
"tslog": "^4.9.2",
52
"typescript": "4.9.4",
@@ -3455,6 +3457,14 @@
3457
}
3458
}
3459
},
3460
+ "node_modules/@radix-ui/react-icons": {
3461
+ "version": "1.3.0",
3462
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz",
3463
+ "integrity": "sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==",
3464
+ "peerDependencies": {
3465
+ "react": "^16.x || ^17.x || ^18.x"
3466
+ }
3467
+ },
3468
"node_modules/@radix-ui/react-id": {
3469
"version": "1.1.0",
3470
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
@@ -16493,6 +16503,14 @@
16503
"node": ">=14.0.0"
16504
}
16505
},
16506
+ "node_modules/tailwindcss-animate": {
16507
+ "version": "1.0.7",
16508
+ "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz",
16509
+ "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==",
16510
+ "peerDependencies": {
16511
+ "tailwindcss": ">=3.0.0 || insiders"
16512
+ }
16513
+ },
16514
"node_modules/tailwindcss/node_modules/postcss-selector-parser": {
16515
"version": "6.1.1",
16516
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz",
frontend/splitfire-desktop/package.json
+22
-20
@@ -4,46 +4,48 @@
4
"version": "0.3.4",
5
"private": true,
6
"dependencies": {
7
+ "@heroicons/react": "1.0.6",
8
+ "@radix-ui/react-icons": "^1.3.0",
9
+ "@radix-ui/react-slot": "^1.0.2",
10
+ "@radix-ui/react-tooltip": "^1.0.7",
11
"@sentry/react": "^7.12.1",
12
"@sentry/tracing": "^7.12.1",
13
+ "@tauri-apps/api": "^1.5.3",
14
"@types/actioncable": "^5.2.7",
15
"@types/jest": "^27.4.0",
16
+ "@types/node": "18.17.0",
17
+ "@types/react": "18.2.78",
18
+ "@types/react-dom": "18.2.25",
19
"actioncable": "^5.2.6",
20
"axios": "^0.25.0",
21
"bootstrap": "5.1.3",
22
+ "class-variance-authority": "^0.7.0",
23
+ "clsx": "^1.2.1",
24
"dexie": "^3.2.0",
25
"dexie-observable": "^3.0.0-beta.11",
26
+ "eslint": "8.32.0",
27
+ "eslint-config-next": "14.1.0",
28
"lodash.debounce": "^4.0.8",
29
+ "next": "14.2.5",
30
+ "react": "18.2.0",
31
"react-bootstrap": "^2.1.1",
32
"react-dnd": "^16.0.1",
33
"react-dnd-html5-backend": "^16.0.1",
34
+ "react-dom": "18.2.0",
35
+ "react-hot-toast": "^2.4.1",
36
"react-icons": "^4.3.1",
37
"react-intl": "^5.24.4",
38
"react-router-dom": "6",
39
"react-scripts": "5.0.0",
40
+ "react-textarea-autosize": "^8.5.3",
41
"react-transition-group": "4.x",
42
"react-youtube": "^7.14.0",
43
+ "tailwind-merge": "^2.4.0",
44
+ "tailwindcss-animate": "^1.0.7",
45
"tone": "^14.7.77",
46
"tslog": "^4.9.2",
28
- "web-vitals": "^2.1.3",
29
- "@heroicons/react": "1.0.6",
30
- "@radix-ui/react-slot": "^1.0.2",
31
- "@radix-ui/react-tooltip": "^1.0.7",
32
- "@tauri-apps/api": "^1.5.3",
33
- "@types/node": "18.17.0",
34
- "@types/react": "18.2.78",
35
- "@types/react-dom": "18.2.25",
36
- "class-variance-authority": "^0.7.0",
37
- "clsx": "1.2.1",
38
- "eslint": "8.32.0",
39
- "eslint-config-next": "14.1.0",
40
- "next": "14.2.5",
41
- "react": "18.2.0",
42
- "react-hot-toast": "^2.4.1",
43
- "react-textarea-autosize": "^8.5.3",
44
- "react-dom": "18.2.0",
47
"typescript": "4.9.4",
46
- "tailwind-merge": "^2.2.1"
48
+ "web-vitals": "^2.1.3"
49
},
50
"scripts": {
51
"next-dev": "next dev",
@@ -73,10 +75,10 @@
75
"mini-css-extract-plugin": "2.4.5"
76
},
77
"devDependencies": {
76
- "@tauri-apps/cli": "^1.5.14",
77
- "@types/lodash.debounce": "^4.0.7",
78
"@tailwindcss/forms": "0.5.3",
79
"@tailwindcss/typography": "0.5.9",
80
+ "@tauri-apps/cli": "^1.5.14",
81
+ "@types/lodash.debounce": "^4.0.7",
82
"autoprefixer": "^10.4.19",
83
"postcss": "^8.4.38",
84
"tailwindcss": "^3.4.3"
frontend/splitfire-desktop/public/grid.svg
new
+5
@@ -0,0 +1,5 @@
1
+
2
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
3
+ <path d="M96,95h4v1H96v4H95V96H86v4H85V96H76v4H75V96H66v4H65V96H56v4H55V96H46v4H45V96H36v4H35V96H26v4H25V96H16v4H15V96H0V95H15V86H0V85H15V76H0V75H15V66H0V65H15V56H0V55H15V46H0V45H15V36H0V35H15V26H0V25H15V16H0V15H15V0h1V15h9V0h1V15h9V0h1V15h9V0h1V15h9V0h1V15h9V0h1V15h9V0h1V15h9V0h1V15h9V0h1V15h4v1H96v9h4v1H96v9h4v1H96v9h4v1H96v9h4v1H96v9h4v1H96v9h4v1H96v9h4v1H96Zm-1,0V86H86v9ZM85,95V86H76v9ZM75,95V86H66v9ZM65,95V86H56v9ZM55,95V86H46v9ZM45,95V86H36v9ZM35,95V86H26v9ZM25,95V86H16v9ZM16,85h9V76H16Zm10,0h9V76H26Zm10,0h9V76H36Zm10,0h9V76H46Zm10,0h9V76H56Zm10,0h9V76H66Zm10,0h9V76H76Zm10,0h9V76H86Zm9-10V66H86v9ZM85,75V66H76v9ZM75,75V66H66v9ZM65,75V66H56v9ZM55,75V66H46v9ZM45,75V66H36v9ZM35,75V66H26v9ZM25,75V66H16v9ZM16,65h9V56H16Zm10,0h9V56H26Zm10,0h9V56H36Zm10,0h9V56H46Zm10,0h9V56H56Zm10,0h9V56H66Zm10,0h9V56H76Zm10,0h9V56H86Zm9-10V46H86v9ZM85,55V46H76v9ZM75,55V46H66v9ZM65,55V46H56v9ZM55,55V46H46v9ZM45,55V46H36v9ZM35,55V46H26v9ZM25,55V46H16v9ZM16,45h9V36H16Zm10,0h9V36H26Zm10,0h9V36H36Zm10,0h9V36H46Zm10,0h9V36H56Zm10,0h9V36H66Zm10,0h9V36H76Zm10,0h9V36H86Zm9-10V26H86v9ZM85,35V26H76v9ZM75,35V26H66v9ZM65,35V26H56v9ZM55,35V26H46v9ZM45,35V26H36v9ZM35,35V26H26v9ZM25,35V26H16v9ZM16,25h9V16H16Zm10,0h9V16H26Zm10,0h9V16H36Zm10,0h9V16H46Zm10,0h9V16H56Zm10,0h9V16H66Zm10,0h9V16H76Zm10,0h9V16H86Z" fill="rgba(255,255,255,0.2)" fill-rule="evenodd" opacity="0.2"/>
4
+ <path d="M6,5V0H5V5H0V6H5v94H6V6h94V5Z" fill="rgba(255,255,255,0.075)" fill-rule="evenodd"/>
5
+</svg>
frontend/splitfire-desktop/tailwind.config.js
deleted
-88
@@ -1,88 +0,0 @@
1
-import colors from 'tailwindcss/colors';
2
-import { Config } from 'tailwindcss';
3
-
4
-export default {
5
- content: [
6
- './app/**/*.{js,ts,jsx,tsx,mdx}',
7
- ],
8
- future: {
9
- hoverOnlyWhenSupported: true,
10
- },
11
- darkMode: 'class',
12
- theme: {
13
- extend: {
14
- // https://vercel.com/design/color
15
- colors: {
16
- gray: colors.zinc,
17
- 'gray-1000': 'rgb(17,17,19)',
18
- 'gray-1100': 'rgb(10,10,11)',
19
- vercel: {
20
- pink: '#FF0080',
21
- blue: '#0070F3',
22
- cyan: '#50E3C2',
23
- orange: '#F5A623',
24
- violet: '#7928CA',
25
- },
26
- },
27
- backgroundImage: ({ theme }) => ({
28
- 'vc-border-gradient': `radial-gradient(at left top, ${theme(
29
- 'colors.gray.500',
30
- )}, 50px, ${theme('colors.gray.800')} 50%)`,
31
- }),
32
- keyframes: ({ theme }) => ({
33
- rerender: {
34
- '0%': {
35
- ['border-color']: theme('colors.vercel.pink'),
36
- },
37
- '40%': {
38
- ['border-color']: theme('colors.vercel.pink'),
39
- },
40
- },
41
- highlight: {
42
- '0%': {
43
- background: theme('colors.vercel.pink'),
44
- color: theme('colors.white'),
45
- },
46
- '40%': {
47
- background: theme('colors.vercel.pink'),
48
- color: theme('colors.white'),
49
- },
50
- },
51
- loading: {
52
- '0%': {
53
- opacity: '.2',
54
- },
55
- '20%': {
56
- opacity: '1',
57
- transform: 'translateX(1px)',
58
- },
59
- to: {
60
- opacity: '.2',
61
- },
62
- },
63
- shimmer: {
64
- '100%': {
65
- transform: 'translateX(100%)',
66
- },
67
- },
68
- translateXReset: {
69
- '100%': {
70
- transform: 'translateX(0)',
71
- },
72
- },
73
- fadeToTransparent: {
74
- '0%': {
75
- opacity: '1',
76
- },
77
- '40%': {
78
- opacity: '1',
79
- },
80
- '100%': {
81
- opacity: '0',
82
- },
83
- },
84
- }),
85
- },
86
- },
87
- plugins: [require('@tailwindcss/typography'), require('@tailwindcss/forms')],
88
-} satisfies Config;
frontend/splitfire-desktop/tailwind.config.ts
new
+80
@@ -0,0 +1,80 @@
1
+import type { Config } from "tailwindcss"
2
+
3
+const config = {
4
+ darkMode: ["class"],
5
+ content: [
6
+ './pages/**/*.{ts,tsx}',
7
+ './components/**/*.{ts,tsx}',
8
+ './app/**/*.{ts,tsx}',
9
+ './src/**/*.{ts,tsx}',
10
+ ],
11
+ prefix: "",
12
+ theme: {
13
+ container: {
14
+ center: true,
15
+ padding: "2rem",
16
+ screens: {
17
+ "2xl": "1400px",
18
+ },
19
+ },
20
+ extend: {
21
+ colors: {
22
+ border: "hsl(var(--border))",
23
+ input: "hsl(var(--input))",
24
+ ring: "hsl(var(--ring))",
25
+ background: "hsl(var(--background))",
26
+ foreground: "hsl(var(--foreground))",
27
+ primary: {
28
+ DEFAULT: "hsl(var(--primary))",
29
+ foreground: "hsl(var(--primary-foreground))",
30
+ },
31
+ secondary: {
32
+ DEFAULT: "hsl(var(--secondary))",
33
+ foreground: "hsl(var(--secondary-foreground))",
34
+ },
35
+ destructive: {
36
+ DEFAULT: "hsl(var(--destructive))",
37
+ foreground: "hsl(var(--destructive-foreground))",
38
+ },
39
+ muted: {
40
+ DEFAULT: "hsl(var(--muted))",
41
+ foreground: "hsl(var(--muted-foreground))",
42
+ },
43
+ accent: {
44
+ DEFAULT: "hsl(var(--accent))",
45
+ foreground: "hsl(var(--accent-foreground))",
46
+ },
47
+ popover: {
48
+ DEFAULT: "hsl(var(--popover))",
49
+ foreground: "hsl(var(--popover-foreground))",
50
+ },
51
+ card: {
52
+ DEFAULT: "hsl(var(--card))",
53
+ foreground: "hsl(var(--card-foreground))",
54
+ },
55
+ },
56
+ borderRadius: {
57
+ lg: "var(--radius)",
58
+ md: "calc(var(--radius) - 2px)",
59
+ sm: "calc(var(--radius) - 4px)",
60
+ },
61
+ keyframes: {
62
+ "accordion-down": {
63
+ from: { height: "0" },
64
+ to: { height: "var(--radix-accordion-content-height)" },
65
+ },
66
+ "accordion-up": {
67
+ from: { height: "var(--radix-accordion-content-height)" },
68
+ to: { height: "0" },
69
+ },
70
+ },
71
+ animation: {
72
+ "accordion-down": "accordion-down 0.2s ease-out",
73
+ "accordion-up": "accordion-up 0.2s ease-out",
74
+ },
75
+ },
76
+ },
77
+ plugins: [require("tailwindcss-animate")],
78
+} satisfies Config
79
+
80
+export default config
\ No newline at end of file