diff --git a/apps/web/package.json b/apps/web/package.json
index 7b0bb20..16095b5 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -18,6 +18,7 @@
"dependencies": {
"@manifold/auth": "*",
"@manifold/engine": "*",
+ "@manifold/lib": "*",
"@manifold/router": "*",
"@manifold/tailwind-config": "*",
"@manifold/ui": "*",
diff --git a/apps/web/src/features/routing/routes/dashboard/components/dashboard-header/aphorism.tsx b/apps/web/src/features/routing/routes/dashboard/components/dashboard-header/aphorism.tsx
new file mode 100644
index 0000000..348aea0
--- /dev/null
+++ b/apps/web/src/features/routing/routes/dashboard/components/dashboard-header/aphorism.tsx
@@ -0,0 +1,19 @@
+import { getRandomElement } from "@manifold/lib/utils/array";
+
+const SOURCES = {
+ dashboard: [
+ "Do you feel lucky?",
+ "You're in the right place.",
+ "What chance will fate decide today?",
+ ] as const satisfies string[],
+} as const;
+
+export function Aphorism({
+ source,
+ className,
+}: {
+ source: keyof typeof SOURCES;
+ className?: string;
+}) {
+ return {getRandomElement(SOURCES[source])};
+}
diff --git a/apps/web/src/features/routing/routes/dashboard/components/dashboard-header/index.tsx b/apps/web/src/features/routing/routes/dashboard/components/dashboard-header/index.tsx
new file mode 100644
index 0000000..5c20f85
--- /dev/null
+++ b/apps/web/src/features/routing/routes/dashboard/components/dashboard-header/index.tsx
@@ -0,0 +1,47 @@
+import { useSession } from "@manifold/auth/client";
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from "@manifold/ui/components/ui/card";
+import { cn } from "@manifold/ui/lib/utils";
+
+import { QuickLauncher } from "../quick-launcher";
+import { Aphorism } from "./aphorism";
+
+function getGreeting(isAuthenticated: boolean, name?: string) {
+ if (isAuthenticated && name) {
+ return `Hello, ${name.split(" ")[0]} ✌️`;
+ }
+
+ return "Hello, stranger! 👋";
+}
+
+export function DashboardHeader({ className }: { className?: string }) {
+ const auth = useSession();
+
+ return (
+
+
+
+ {getGreeting(auth.status === "authenticated", auth.data?.user?.name)}
+
+
+
+
+
+
+
+
+
+
+
+ );
+
+ //
{greeting}
;
+}
diff --git a/apps/web/src/features/routing/routes/dashboard/components/quick-launcher/index.tsx b/apps/web/src/features/routing/routes/dashboard/components/quick-launcher/index.tsx
new file mode 100644
index 0000000..44bbc82
--- /dev/null
+++ b/apps/web/src/features/routing/routes/dashboard/components/quick-launcher/index.tsx
@@ -0,0 +1,42 @@
+import { Button } from "@manifold/ui/components/ui/button";
+import { Card, CardContent } from "@manifold/ui/components/ui/card";
+
+const ITEMS = [
+ {
+ title: "Cryptids",
+ },
+ {
+ title: "UFOs",
+ },
+ {
+ title: "Ghosts",
+ },
+ {
+ title: "Deities",
+ },
+ {
+ title: "Potions",
+ },
+];
+
+export function QuickLauncher() {
+ return (
+
+ {ITEMS.map((item) => {
+ return ;
+ })}
+
+ );
+}
+
+function QuickLaunchTile({ item }: { item: { title: string } }) {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/apps/web/src/features/routing/routes/dashboard/components/table-list/index.tsx b/apps/web/src/features/routing/routes/dashboard/components/table-list/index.tsx
new file mode 100644
index 0000000..6d5d2a2
--- /dev/null
+++ b/apps/web/src/features/routing/routes/dashboard/components/table-list/index.tsx
@@ -0,0 +1,63 @@
+import { Button } from "@manifold/ui/components/ui/button";
+import {
+ Card,
+ CardContent,
+ CardHeader,
+ CardTitle,
+} from "@manifold/ui/components/ui/card";
+
+const TABLES = [
+ {
+ id: 1,
+ title: "Cryptids",
+ },
+ {
+ id: 2,
+ title: "UFOs",
+ },
+ {
+ id: 3,
+ title: "Ghosts",
+ },
+ {
+ id: 4,
+ title: "Deities",
+ },
+ {
+ id: 5,
+ title: "Potions",
+ },
+];
+
+export function TableList() {
+ return (
+
+
+ {/* @TODO: Maybe this is a dropdown - recent/created at/used */}
+ Recently Edited:
+
+
+
+ {TABLES.map((table) => {
+ return (
+
+
+
+
+
+ );
+ })}
+
+
+ );
+}
diff --git a/apps/web/src/features/routing/routes/dashboard/page.tsx b/apps/web/src/features/routing/routes/dashboard/page.tsx
index 7d5b9c4..188501f 100644
--- a/apps/web/src/features/routing/routes/dashboard/page.tsx
+++ b/apps/web/src/features/routing/routes/dashboard/page.tsx
@@ -1,19 +1,11 @@
-import { useSession } from "@manifold/auth/client";
-
-import { Editor } from "#features/editor/editor.tsx";
+import { DashboardHeader } from "./components/dashboard-header";
+import { TableList } from "./components/table-list";
export function Component() {
- const auth = useSession();
-
- let greeting = "Hello";
- if (auth.status === "authenticated") {
- greeting = `Hello, ${auth.data?.user?.name.split(" ")[0]} ✌️`;
- }
-
return (
-
-
{greeting}
-
+
);
}
diff --git a/package-lock.json b/package-lock.json
index 2d8c610..3baaf2b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -40,6 +40,7 @@
"dependencies": {
"@manifold/auth": "*",
"@manifold/engine": "*",
+ "@manifold/lib": "*",
"@manifold/router": "*",
"@manifold/tailwind-config": "*",
"@manifold/ui": "*",
@@ -1635,6 +1636,10 @@
"resolved": "packages/config-eslint",
"link": true
},
+ "node_modules/@manifold/lib": {
+ "resolved": "packages/lib",
+ "link": true
+ },
"node_modules/@manifold/router": {
"resolved": "packages/router",
"link": true
@@ -11486,6 +11491,14 @@
"packages/engine": {
"name": "@manifold/engine"
},
+ "packages/lib": {
+ "name": "@manifold/lib",
+ "version": "0.0.0",
+ "devDependencies": {
+ "@manifold/eslint-config": "*",
+ "@manifold/typescript-config": "*"
+ }
+ },
"packages/router": {
"name": "@manifold/router",
"version": "0.0.0",
diff --git a/packages/lib/.eslintrc.cjs b/packages/lib/.eslintrc.cjs
new file mode 100644
index 0000000..e43651e
--- /dev/null
+++ b/packages/lib/.eslintrc.cjs
@@ -0,0 +1,5 @@
+/** @type {import("eslint").Linter.Config} */
+module.exports = {
+ root: true,
+ extends: ["@manifold/eslint-config/index.js"],
+};
diff --git a/packages/lib/README.md b/packages/lib/README.md
new file mode 100644
index 0000000..01091f8
--- /dev/null
+++ b/packages/lib/README.md
@@ -0,0 +1 @@
+# `@manifold/lib`
diff --git a/packages/lib/package.json b/packages/lib/package.json
new file mode 100644
index 0000000..6fed6de
--- /dev/null
+++ b/packages/lib/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "@manifold/lib",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "imports": {
+ "#*": "./src/*"
+ },
+ "exports": {
+ ".": "./src/index.ts",
+ "./*": "./src/*.ts"
+ },
+ "scripts": {
+ "dev": "echo 'Add dev script here'",
+ "build": "echo 'Add build script here'",
+ "test": "echo 'Add test script here'",
+ "lint": "echo 'Add lint script here'"
+ },
+ "devDependencies": {
+ "@manifold/eslint-config": "*",
+ "@manifold/typescript-config": "*"
+ }
+}
diff --git a/packages/lib/src/utils/array.ts b/packages/lib/src/utils/array.ts
new file mode 100644
index 0000000..f13c1a8
--- /dev/null
+++ b/packages/lib/src/utils/array.ts
@@ -0,0 +1,3 @@
+export function getRandomElement
(arr: T[]): T {
+ return arr[Math.floor(Math.random() * arr.length)];
+}
diff --git a/packages/lib/tsconfig.json b/packages/lib/tsconfig.json
new file mode 100644
index 0000000..7bf0418
--- /dev/null
+++ b/packages/lib/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "@manifold/typescript-config/base.json",
+ "include": ["src"],
+ "exclude": ["node_modules"]
+}
diff --git a/packages/ui/src/components/ui/badge.tsx b/packages/ui/src/components/ui/badge.tsx
index 6dbc94d..4c70b2f 100644
--- a/packages/ui/src/components/ui/badge.tsx
+++ b/packages/ui/src/components/ui/badge.tsx
@@ -1,7 +1,8 @@
-import { cn } from "@manifold/ui/lib/utils";
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
+import { cn } from "#lib/utils.ts";
+
const badgeVariants = cva(
"inline-flex items-center rounded-md border px-10 py-2 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
{
diff --git a/packages/ui/src/components/ui/button.tsx b/packages/ui/src/components/ui/button.tsx
index 8b85f2e..7506f56 100644
--- a/packages/ui/src/components/ui/button.tsx
+++ b/packages/ui/src/components/ui/button.tsx
@@ -1,8 +1,9 @@
-import { cn } from "@manifold/ui/lib/utils";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
+import { cn } from "#lib/utils.ts";
+
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-sm text-sm ring-offset-0 ring-0 focus-visible:ring-offset-2 transition-all ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
{
@@ -17,7 +18,7 @@ const buttonVariants = cva(
secondary:
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
- link: "text-primary underline-offset-4 hover:underline",
+ link: "text-primary hover:underline decoration-from-font underline-offset-2 decoration-current",
},
size: {
default: "h-36 px-16 py-8",
diff --git a/packages/ui/src/components/ui/card.tsx b/packages/ui/src/components/ui/card.tsx
index a665bc7..e37cede 100644
--- a/packages/ui/src/components/ui/card.tsx
+++ b/packages/ui/src/components/ui/card.tsx
@@ -1,6 +1,7 @@
-import { cn } from "@manifold/ui/lib/utils";
import * as React from "react";
+import { cn } from "#lib/utils.ts";
+
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes
@@ -22,7 +23,7 @@ const CardHeader = React.forwardRef<
>(({ className, ...props }, ref) => (
));
@@ -54,9 +55,19 @@ CardDescription.displayName = "CardDescription";
const CardContent = React.forwardRef<
HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
+ React.HTMLAttributes & { flush?: boolean }
+>(({ className, flush = true, ...props }, ref) => (
+
));
CardContent.displayName = "CardContent";
diff --git a/packages/ui/src/components/ui/checkbox.tsx b/packages/ui/src/components/ui/checkbox.tsx
index 2e1c5eb..bb8cedd 100644
--- a/packages/ui/src/components/ui/checkbox.tsx
+++ b/packages/ui/src/components/ui/checkbox.tsx
@@ -1,8 +1,9 @@
-import { cn } from "@manifold/ui/lib/utils";
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
import { CheckIcon } from "@radix-ui/react-icons";
import * as React from "react";
+import { cn } from "#lib/utils.ts";
+
const Checkbox = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
diff --git a/packages/ui/src/components/ui/resizable.tsx b/packages/ui/src/components/ui/resizable.tsx
index 4009556..a09d114 100644
--- a/packages/ui/src/components/ui/resizable.tsx
+++ b/packages/ui/src/components/ui/resizable.tsx
@@ -1,7 +1,8 @@
-import { cn } from "@manifold/ui/lib/utils";
import { DragHandleDots2Icon } from "@radix-ui/react-icons";
import * as ResizablePrimitive from "react-resizable-panels";
+import { cn } from "#lib/utils.ts";
+
const ResizablePanelGroup = ({
className,
...props