diff --git a/apps/playground/next.config.js b/apps/playground/next.config.js index dfeb418f..3f4065ce 100644 --- a/apps/playground/next.config.js +++ b/apps/playground/next.config.js @@ -12,7 +12,6 @@ const config = { transpilePackages: [ "@swy/liveblocks", "@swy/notion", - "@swy/prisma", "@swy/ui", "@swy/validators", "lucide-react", @@ -43,6 +42,14 @@ const config = { protocol: "https", hostname: "www.notion.so", }, + { + protocol: "https", + hostname: "upload.wikimedia.org", + }, + { + protocol: "https", + hostname: "avatars.githubusercontent.com", + }, ], }, }; diff --git a/apps/playground/package.json b/apps/playground/package.json index 472157cb..180d0e13 100644 --- a/apps/playground/package.json +++ b/apps/playground/package.json @@ -6,7 +6,7 @@ "scripts": { "build": "pnpm with-env next build", "clean": "git clean -xdf .next .turbo node_modules", - "dev": "pnpm with-env next dev -p 3001", + "dev": "pnpm with-env next dev -p 3002", "format": "prettier --check . --ignore-path ../../.gitignore", "lint": "eslint", "start": "pnpm with-env next start", diff --git a/apps/playground/src/app/(marketing)/_components/heading.tsx b/apps/playground/src/app/(marketing)/_components/heading.tsx index 365ece1f..9a99175d 100644 --- a/apps/playground/src/app/(marketing)/_components/heading.tsx +++ b/apps/playground/src/app/(marketing)/_components/heading.tsx @@ -16,7 +16,7 @@ const Heading = () => { Steeeee WorXpace is the connected workspace where better, faster work happens. - + Get Started diff --git a/apps/playground/src/app/(platform)/(auth)/sign-in/_components/sign-in-button.tsx b/apps/playground/src/app/(platform)/(auth)/sign-in/_components/sign-in-button.tsx new file mode 100644 index 00000000..e0c02b66 --- /dev/null +++ b/apps/playground/src/app/(platform)/(auth)/sign-in/_components/sign-in-button.tsx @@ -0,0 +1,36 @@ +import React from "react"; +import Image from "next/image"; + +import { Button } from "@swy/ui/shadcn"; + +interface SignInButtonProps { + name: string; + avatarUrl: string; +} + +export const SignInButton: React.FC = ({ + name, + avatarUrl, +}) => { + return ( + + + + + + + + {name} + + + Fake user + + + + + ); +}; diff --git a/apps/playground/src/app/(platform)/(auth)/sign-in/page.tsx b/apps/playground/src/app/(platform)/(auth)/sign-in/page.tsx new file mode 100644 index 00000000..cc7cbd71 --- /dev/null +++ b/apps/playground/src/app/(platform)/(auth)/sign-in/page.tsx @@ -0,0 +1,25 @@ +import { IconBlock } from "@swy/ui/shared"; + +import { accounts } from "~/db/accounts"; +import { SignInButton } from "./_components/sign-in-button"; + +export default function Page() { + return ( + + + + + Sign in with ... + + + {Object.values(accounts).map(({ name, avatarUrl }) => ( + + ))} + + + + ); +} diff --git a/apps/playground/src/app/(platform)/layout.tsx b/apps/playground/src/app/(platform)/layout.tsx new file mode 100644 index 00000000..12c23dc3 --- /dev/null +++ b/apps/playground/src/app/(platform)/layout.tsx @@ -0,0 +1,19 @@ +"use client"; + +import React, { useEffect } from "react"; + +import { mockDB } from "~/db"; +import { useMockDB } from "~/hooks"; + +export default function Layout({ children }: React.PropsWithChildren) { + const { update } = useMockDB(); + + useEffect(() => { + update(mockDB); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( + {children} + ); +} diff --git a/apps/playground/src/app/layout.tsx b/apps/playground/src/app/layout.tsx index 83bf2407..7b4e5958 100644 --- a/apps/playground/src/app/layout.tsx +++ b/apps/playground/src/app/layout.tsx @@ -12,7 +12,7 @@ const inter = Inter({ subsets: ["latin", "latin-ext"] }); export const metadata: Metadata = { metadataBase: new URL( env.VERCEL_ENV === "production" - ? "https://worxpace.steeeee0223.vercel.app" + ? "https://playground.steeeee0223.vercel.app" : `http://localhost:${env.PORT}`, ), title: "Steeeee WorXpace", diff --git a/apps/playground/src/components/mock-provider.tsx b/apps/playground/src/components/mock-provider.tsx deleted file mode 100644 index cb41e441..00000000 --- a/apps/playground/src/components/mock-provider.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import React from "react"; - -export const MockProvider: React.FC = ({children}) => { - return <>{children}> - }; \ No newline at end of file diff --git a/apps/playground/src/db/accounts.ts b/apps/playground/src/db/accounts.ts index 0f95d38c..93c279fe 100644 --- a/apps/playground/src/db/accounts.ts +++ b/apps/playground/src/db/accounts.ts @@ -1,40 +1,47 @@ import { AccountModel } from "./types"; +export enum _USER { + U1 = "a97f4e50-0b72-44f4-a95a-aba319534af5", + U2 = "22bd2a9e-bbee-4f3f-9c78-6a430a2c29b2", + U3 = "83e2f249-f02c-4971-b8fc-cda5cf71dd77", +} + export const accounts: Record = { - "45d7e133-d354-47c2-881b-441b7f95a327": { - id: "45d7e133-d354-47c2-881b-441b7f95a327", - name: "John Wick", - clerkId: "user_1", - email: "john-wick@example.com", - avatarUrl: "", - preferredName: "John Wick", - updatedAt: Date.UTC(2024, 1, 1), - }, - "a97f4e50-0b72-44f4-a95a-aba319534af5": { - id: "a97f4e50-0b72-44f4-a95a-aba319534af5", + [_USER.U1]: { + id: _USER.U1, name: "Steve Yu", clerkId: "user_2", email: "steve-yu@example.com", - avatarUrl: "", + avatarUrl: + "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2d/Go_gopher_favicon.svg/1200px-Go_gopher_favicon.svg.png", preferredName: "Steve", updatedAt: Date.UTC(2024, 1, 1), }, - "22bd2a9e-bbee-4f3f-9c78-6a430a2c29b2": { - id: "22bd2a9e-bbee-4f3f-9c78-6a430a2c29b2", + [_USER.U2]: { + id: _USER.U2, name: "Chien Pong", clerkId: "user_3", email: "pong123@example.com", - avatarUrl: "", + avatarUrl: "https://avatars.githubusercontent.com/u/91364382", preferredName: "Pong", updatedAt: Date.UTC(2024, 1, 1), }, - "83e2f249-f02c-4971-b8fc-cda5cf71dd77": { - id: "83e2f249-f02c-4971-b8fc-cda5cf71dd77", + [_USER.U3]: { + id: _USER.U3, name: "Chia Ming", clerkId: "user_4", email: "chiaming@example.com", - avatarUrl: "", + avatarUrl: "https://avatars.githubusercontent.com/u/15240773", preferredName: "Mark", updatedAt: Date.UTC(2024, 1, 1), }, + // "45d7e133-d354-47c2-881b-441b7f95a327": { + // id: "45d7e133-d354-47c2-881b-441b7f95a327", + // name: "John Wick", + // clerkId: "user_1", + // email: "john-wick@example.com", + // avatarUrl: "", + // preferredName: "John Wick", + // updatedAt: Date.UTC(2024, 1, 1), + // }, }; diff --git a/apps/playground/src/db/index.ts b/apps/playground/src/db/index.ts index 6e511854..3bbf07b2 100644 --- a/apps/playground/src/db/index.ts +++ b/apps/playground/src/db/index.ts @@ -1,19 +1,16 @@ -/** Mock data */ -export * from "./accounts"; -/** Types */ -export type * from "./types"; +import { accounts } from "./accounts"; +import { memberships } from "./memberships"; +import type { AccountModel, MembershipModel, WorkspaceModel } from "./types"; +import { workspaces } from "./workspaces"; -/** +export interface MockDB { + accounts: Record; + workspaces: Record; + memberships: MembershipModel[]; +} -ff86a28d-88a2-4bfa-8526-626724a52aff - -fd5f3c3f-e2d9-4e8b-a336-061bcce54681 - -e478ea0e-d20f-42e9-a2b3-38401bd72b71 - -35233f19-b5f8-46a8-a6cc-b73e6ef686e8 - -69161f49-d6d0-4ad8-b4a7-c44bc85737f0 - -85e02808-25d5-44ab-adc4-b6d4867e37d3 - */ +export const mockDB: MockDB = { + accounts, + workspaces, + memberships, +}; diff --git a/apps/playground/src/db/memberships.ts b/apps/playground/src/db/memberships.ts new file mode 100644 index 00000000..c7a9b6a7 --- /dev/null +++ b/apps/playground/src/db/memberships.ts @@ -0,0 +1,71 @@ +import { Role } from "@swy/validators"; + +import { _USER } from "./accounts"; +import type { MembershipModel } from "./types"; +import { _WORKSPACE } from "./workspaces"; + +export const memberships: MembershipModel[] = [ + { + id: "mem-1", + role: Role.OWNER, + accountId: _USER.U1, + workspaceId: _WORKSPACE.W1, + joinedAt: Date.UTC(2024, 1, 1), + }, + { + id: "mem-2", + role: Role.MEMBER, + accountId: _USER.U2, + workspaceId: _WORKSPACE.W1, + joinedAt: Date.UTC(2024, 1, 1), + }, + { + id: "mem-3", + role: Role.GUEST, + accountId: _USER.U3, + workspaceId: _WORKSPACE.W1, + joinedAt: Date.UTC(2024, 1, 1), + }, + { + id: "mem-4", + role: Role.OWNER, + accountId: _USER.U3, + workspaceId: _WORKSPACE.W2, + joinedAt: Date.UTC(2024, 1, 1), + }, + { + id: "mem-5", + role: Role.MEMBER, + accountId: _USER.U1, + workspaceId: _WORKSPACE.W2, + joinedAt: Date.UTC(2024, 1, 1), + }, + { + id: "mem-6", + role: Role.OWNER, + accountId: _USER.U1, + workspaceId: _WORKSPACE.W3, + joinedAt: Date.UTC(2024, 1, 1), + }, + { + id: "mem-7", + role: Role.OWNER, + accountId: _USER.U2, + workspaceId: _WORKSPACE.W4, + joinedAt: Date.UTC(2024, 1, 1), + }, + { + id: "mem-8", + role: Role.OWNER, + accountId: _USER.U2, + workspaceId: _WORKSPACE.W5, + joinedAt: Date.UTC(2024, 1, 1), + }, + { + id: "mem-9", + role: Role.OWNER, + accountId: _USER.U3, + workspaceId: _WORKSPACE.W5, + joinedAt: Date.UTC(2024, 1, 1), + }, +]; diff --git a/apps/playground/src/db/types.ts b/apps/playground/src/db/types.ts index fddad84d..48acf6eb 100644 --- a/apps/playground/src/db/types.ts +++ b/apps/playground/src/db/types.ts @@ -13,20 +13,20 @@ export interface AccountModel { } export interface WorkspaceModel { - id: string; // default uuid + id: string; // (uuid) name: string; - icon: IconInfo; + icon?: IconInfo | null; domain: string; plan: Plan; - inviteToken: string; // default uuid - createdBy: string; // account.id + inviteToken: string; // (uuid) default: same as `id` + createdBy: string; // (uuid) account.id lastEditedAt: number; // ts in 'ms' } export interface MembershipModel { - id: string; // default uuid + id: string; // (uuid) role: Role; - accountId: string; // account.id - workspaceId: string; // workspace.id + accountId: string; // (uuid) account.id + workspaceId: string; // (uuid) workspace.id joinedAt: number; // ts in 'ms' } diff --git a/apps/playground/src/db/workspaces.ts b/apps/playground/src/db/workspaces.ts new file mode 100644 index 00000000..1e9d5115 --- /dev/null +++ b/apps/playground/src/db/workspaces.ts @@ -0,0 +1,65 @@ +import { Plan } from "@swy/validators"; + +import { _USER } from "./accounts"; +import type { WorkspaceModel } from "./types"; + +export enum _WORKSPACE { + W1 = "f12d4c5b-2d3b-4d2b-aef3-8f7319c5d481", + W2 = "b3c2a6e8-9231-4a9b-a89e-7d36d3f35ec2", + W3 = "a2c4e8d7-4b7e-45d9-bb3d-1f9e6fbe7d4f", + W4 = "c1d7e9b6-7a3d-4b2e-a8b3-9f7e6c5d3a2f", + W5 = "d9b3f6a2-5c4e-7b2d-8a3f-1f9e6c7d4b2e", +} + +export const workspaces: Record = { + [_WORKSPACE.W1]: { + id: _WORKSPACE.W1, + name: "Alpha Workspace", + icon: { type: "emoji", emoji: "🚀" }, + domain: "alphaworkspace.com", + plan: Plan.FREE, + inviteToken: _WORKSPACE.W1, + createdBy: _USER.U1, + lastEditedAt: Date.UTC(2024, 1, 31), + }, + [_WORKSPACE.W2]: { + id: _WORKSPACE.W2, + name: "Beta Labs", + icon: { type: "lucide", name: "goal", color: "#D44C47" }, + domain: "betalabs.org", + plan: Plan.EDUCATION, + inviteToken: _WORKSPACE.W2, + createdBy: _USER.U3, + lastEditedAt: Date.UTC(2024, 2, 26), + }, + [_WORKSPACE.W3]: { + id: _WORKSPACE.W3, + name: "Gamma Studio", + icon: { type: "emoji", emoji: "🎨" }, + domain: "gammastudio.net", + plan: Plan.PLUS, + inviteToken: _WORKSPACE.W3, + createdBy: _USER.U1, + lastEditedAt: Date.UTC(2024, 3, 14), + }, + [_WORKSPACE.W4]: { + id: _WORKSPACE.W4, + name: "Delta Group", + icon: { type: "text", text: "D" }, + domain: "deltagroup.com", + plan: Plan.BUSINESS, + inviteToken: _WORKSPACE.W4, + createdBy: _USER.U2, + lastEditedAt: Date.UTC(2024, 4, 29), + }, + [_WORKSPACE.W5]: { + id: _WORKSPACE.W5, + name: "Epsilon Enterprises", + icon: null, + domain: "epsilonent.com", + plan: Plan.ENTERPRISE, + inviteToken: _WORKSPACE.W5, + createdBy: _USER.U2, + lastEditedAt: Date.UTC(2024, 7, 17), + }, +}; diff --git a/apps/playground/src/env.ts b/apps/playground/src/env.ts index 45c45ad6..7639a296 100644 --- a/apps/playground/src/env.ts +++ b/apps/playground/src/env.ts @@ -8,30 +8,21 @@ export const env = createEnv({ NODE_ENV: z .enum(["development", "production", "test"]) .default("development"), - PORT: z.coerce.number().default(3001), + PORT: z.coerce.number().default(3002), }, /** * Specify your server-side environment variables schema here. * This way you can ensure the app isn't built with invalid env vars. */ server: { - DB_AUTH: z.string(), - DB_WORXPACE: z.string(), // LIVEBLOCKS LIVEBLOCKS_SECRET_KEY: z.string(), - // CLERK - CLERK_SECRET_KEY: z.string(), - // EDGESTORE - EDGE_STORE_ACCESS_KEY: z.string(), - EDGE_STORE_SECRET_KEY: z.string(), }, /** * Specify your client-side environment variables schema here. * For them to be exposed to the client, prefix them with `NEXT_PUBLIC_`. */ client: { - // CLERK - NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string(), // UNSPLASH NEXT_PUBLIC_UNSPLASH_ACCESS_KEY: z.string(), }, @@ -42,16 +33,6 @@ export const env = createEnv({ NODE_ENV: process.env.NODE_ENV, // NEXT PORT: process.env.PORT, - // CLERK - NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: - process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, - CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY, - // DB - DB_AUTH: process.env.DB_AUTH, - DB_WORXPACE: process.env.DB_WORXPACE, - // EDGESTORE - EDGE_STORE_ACCESS_KEY: process.env.EDGE_STORE_ACCESS_KEY, - EDGE_STORE_SECRET_KEY: process.env.EDGE_STORE_SECRET_KEY, // LIVEBLOCKS LIVEBLOCKS_SECRET_KEY: process.env.LIVEBLOCKS_SECRET_KEY, // UNSPLASH diff --git a/apps/playground/src/hooks/useMockDB.ts b/apps/playground/src/hooks/useMockDB.ts index d0b4bd3d..2bf080db 100644 --- a/apps/playground/src/hooks/useMockDB.ts +++ b/apps/playground/src/hooks/useMockDB.ts @@ -2,18 +2,16 @@ import { useLocalStorage } from "usehooks-ts"; -import { accounts, type AccountModel } from "~/db"; - -export interface MockDB { - accounts: Record; -} +import type { MockDB } from "~/db"; const initial: MockDB = { - accounts, + accounts: {}, + workspaces: {}, + memberships: [], }; export const useMockDB = () => { - const [value, update] = useLocalStorage("mock:database", initial); + const [value, update] = useLocalStorage("mock:db", initial); return { ...value,