-
-
+
+
+
+ β©{cost}
+
+ / month
+
+
+
@@ -78,12 +156,12 @@ const ArchitectureImageExample = () => (
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
-
+
);
diff --git a/apps/hub/src/app/favicon.ico b/apps/hub/src/app/favicon.ico
new file mode 100644
index 00000000..356af84c
Binary files /dev/null and b/apps/hub/src/app/favicon.ico differ
diff --git a/apps/hub/src/app/fonts.ts b/apps/hub/src/app/fonts.ts
new file mode 100644
index 00000000..7a1a3c29
--- /dev/null
+++ b/apps/hub/src/app/fonts.ts
@@ -0,0 +1,6 @@
+import localFont from 'next/font/local';
+
+export const gamjaFlower = localFont({
+ src: '../fonts/GamjaFlower-Regular.ttf',
+ variable: '--font-gamja-flower',
+});
diff --git a/apps/hub/src/app/layout.tsx b/apps/hub/src/app/layout.tsx
index 4dc592ff..a508ad63 100644
--- a/apps/hub/src/app/layout.tsx
+++ b/apps/hub/src/app/layout.tsx
@@ -1,10 +1,11 @@
import type { Metadata } from 'next';
import './globals.css';
import { GlobalHeader } from '@/components/GlobalHeader';
+import { gamjaFlower } from './fonts';
export const metadata: Metadata = {
- title: 'Create Next App',
- description: 'Generated by create next app',
+ title: 'Cloud Canvas',
+ description: 'Draw your cloud architecture with ease',
};
export default function RootLayout({
@@ -12,7 +13,7 @@ export default function RootLayout({
}: Readonly<{ children: React.ReactNode }>) {
return (
-
+
{children}
diff --git a/apps/hub/src/app/my/architectures/page.tsx b/apps/hub/src/app/my/architectures/page.tsx
index c1cf92a1..f2530565 100644
--- a/apps/hub/src/app/my/architectures/page.tsx
+++ b/apps/hub/src/app/my/architectures/page.tsx
@@ -1,5 +1,14 @@
-import { Architectures } from '@/components/Architectures';
+'use client';
+import { PrivateArchitectureBoard } from '@/components/PrivateArchitectureBoard';
+
+import { Suspense } from 'react';
export default function MyArchitecturesPage() {
- return
;
+ return (
+
+
+
+ );
}
diff --git a/apps/hub/src/app/my/shared/page.tsx b/apps/hub/src/app/my/shared/page.tsx
index 81e94ad2..a9f63aee 100644
--- a/apps/hub/src/app/my/shared/page.tsx
+++ b/apps/hub/src/app/my/shared/page.tsx
@@ -1,5 +1,13 @@
-import { Architectures } from '@/components/Architectures';
+'use client';
+import { ArchitectureBoard } from '@/components/ArchitectureBoard';
+import { Suspense } from 'react';
export default function MySharedPage() {
- return
;
+ return (
+
+
+
+ );
}
diff --git a/apps/hub/src/app/my/starred/page.tsx b/apps/hub/src/app/my/starred/page.tsx
index 9d432eec..9f98c2a1 100644
--- a/apps/hub/src/app/my/starred/page.tsx
+++ b/apps/hub/src/app/my/starred/page.tsx
@@ -1,5 +1,13 @@
-import { Architectures } from '@/components/Architectures';
+'use client';
+import { ArchitectureBoard } from '@/components/ArchitectureBoard';
+import { Suspense } from 'react';
export default function MyStarredPage() {
- return
;
+ return (
+
+
+
+ );
}
diff --git a/apps/hub/src/app/page.tsx b/apps/hub/src/app/page.tsx
index 6777118c..60ecebd7 100644
--- a/apps/hub/src/app/page.tsx
+++ b/apps/hub/src/app/page.tsx
@@ -1,6 +1,13 @@
'use client';
import { ArchitectureBoard } from '@/components/ArchitectureBoard';
+import { Suspense } from 'react';
export default function Home() {
- return
;
+ return (
+
+
+
+ );
}
diff --git a/apps/hub/src/components/ArchitectureBoard/ArchitectureItem.tsx b/apps/hub/src/components/ArchitectureBoard/ArchitectureItem.tsx
index 7700ed47..8eab1b50 100644
--- a/apps/hub/src/components/ArchitectureBoard/ArchitectureItem.tsx
+++ b/apps/hub/src/components/ArchitectureBoard/ArchitectureItem.tsx
@@ -7,40 +7,40 @@ export const ArchitectureItem = ({
author,
cost,
createdAt,
- stars,
- imports,
tags,
+ _count,
}: {
id: number;
title: string;
- author: string;
+ author: { id: number; name: string };
cost: number;
createdAt: string;
- stars: number;
- imports: number;
- tags: string[];
+ tags: { tag: { name: string } }[];
+ _count: {
+ imports: number;
+ stars: number;
+ };
}) => {
+ const { imports, stars } = _count;
return (
-
+
{title}
-
-
{createdAt}
-
{author}
+
+
{new Date(createdAt).toLocaleString()}
+
{author.name}
-
- {tags.map((tag) => (
-
+
+ {tags?.map(({ tag: { name } }) => (
+
))}
-
-
{cost}
-
{imports}
-
{stars}
-
+
β© {cost}
+
{stars}
+
{imports}
);
};
diff --git a/apps/hub/src/components/ArchitectureBoard/ArchitectureList.tsx b/apps/hub/src/components/ArchitectureBoard/ArchitectureList.tsx
index cc37f07d..c8bd053e 100644
--- a/apps/hub/src/components/ArchitectureBoard/ArchitectureList.tsx
+++ b/apps/hub/src/components/ArchitectureBoard/ArchitectureList.tsx
@@ -1,6 +1,6 @@
import { ArchitectureItem } from './ArchitectureItem';
-export const ArchitectureList = ({ data }) => {
+export const ArchitectureList = ({ data }: { data: Array
}) => {
if (!data?.length) {
return (
@@ -13,13 +13,9 @@ export const ArchitectureList = ({ data }) => {
return (
- {/*
*/}
- {/*
*/}
{data.map((item) => (
))}
- {/*
*/}
- {/*
*/}
);
};
diff --git a/apps/hub/src/components/ArchitectureBoard/BoardHeader.tsx b/apps/hub/src/components/ArchitectureBoard/BoardHeader.tsx
index a7ebcb9f..9cf3d7a4 100644
--- a/apps/hub/src/components/ArchitectureBoard/BoardHeader.tsx
+++ b/apps/hub/src/components/ArchitectureBoard/BoardHeader.tsx
@@ -13,9 +13,9 @@ export const BoardHeader = ({
}) => {
const columns = [
{ key: 'name', title: 'Architecture', width: 'w-full' },
- { key: 'cost', title: 'Costs', width: 'w-40' },
- { key: 'imports', title: 'Imports', width: 'w-40' },
+ { key: 'cost', title: 'Costs', width: 'w-52' },
{ key: 'stars', title: 'Stars', width: 'w-40' },
+ { key: 'imports', title: 'Imports', width: 'w-40' },
];
const getSortIcon = (columnKey: string) => {
@@ -27,7 +27,7 @@ export const BoardHeader = ({
};
return (
-
+
{columns.map((column) => (
{
if (error) return
;
+ // return
{JSON.stringify(data)}
;
+
return (
diff --git a/apps/hub/src/components/GlobalHeader.tsx b/apps/hub/src/components/GlobalHeader/index.tsx
similarity index 63%
rename from apps/hub/src/components/GlobalHeader.tsx
rename to apps/hub/src/components/GlobalHeader/index.tsx
index ca779588..2c5d8afb 100644
--- a/apps/hub/src/components/GlobalHeader.tsx
+++ b/apps/hub/src/components/GlobalHeader/index.tsx
@@ -2,27 +2,52 @@
import Link from 'next/link';
import { useRouter } from 'next/navigation';
-import { useState } from 'react';
-import { LinkButton } from '../ui/LinkButton';
+import { useEffect, useState } from 'react';
+import { LinkButton } from '@/ui/LinkButton';
+import { CloudCanvasIcon } from '@/ui/CloudCanvasIcon';
export const GlobalHeader = () => {
const router = useRouter();
const [isLoggedIn, setIsLoggedIn] = useState(false);
- const handleLogin = () => {
- setIsLoggedIn(true);
+ useEffect(() => {
+ if (localStorage.getItem('isLoggedIn') === 'true') {
+ setIsLoggedIn(true);
+ }
+ }, []);
+
+ const handleLogin = async () => {
+ const res = await fetch(`${process.env.BACK_URL}/auth/login`, {
+ method: 'POST',
+ credentials: 'include',
+ });
+ if (res.ok) {
+ setIsLoggedIn(true);
+ localStorage.setItem('isLoggedIn', 'true');
+ router.refresh();
+ router.push('/');
+ }
};
const handleLogout = () => {
+ fetch(`${process.env.BACK_URL}/auth/logout`, {
+ method: 'POST',
+ credentials: 'include',
+ });
setIsLoggedIn(false);
+ localStorage.removeItem('isLoggedIn');
+ router.refresh();
router.push('/');
};
return (
-