Skip to content

Commit

Permalink
feat: added workspaces invites
Browse files Browse the repository at this point in the history
  • Loading branch information
Anthony Cueva committed Jan 13, 2024
1 parent 9681ca4 commit 275ef94
Show file tree
Hide file tree
Showing 24 changed files with 918 additions and 105 deletions.
16 changes: 14 additions & 2 deletions apps/web/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
NEXT_PUBLIC_URL=https://app.com

XATA_BRANCH=main
XATA_API_KEY=xau_3jy9x04JI305oa6nJd6EcFGYwOSvd95f0
NEXT_PUBLIC_URL=https://useretest.vercel.app
XATA_API_KEY=xau_1234567890

AUTH_SECRET="1234567890"

GOOGLE_CLIENT_ID="123-456-789-0"
GOOGLE_CLIENT_SECRET="GO-1234567890"

EMAIL_SERVER_USER=resend
EMAIL_SERVER_PASSWORD=YOUR_RESEND_API_KEY
EMAIL_SERVER_HOST=smtp.resend.com
EMAIL_SERVER_PORT=465
EMAIL_FROM=[email protected]
5 changes: 4 additions & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,18 @@
"@trpc/client": "^10.44.1",
"@trpc/react-query": "^10.44.1",
"@trpc/server": "^10.44.1",
"@xata.io/client": "^0.28.2",
"@xata.io/client": "^0.28.3",
"bright": "^0.8.4",
"class-variance-authority": "^0.7.0",
"date-fns": "^2.30.0",
"lucide-react": "^0.294.0",
"next": "^14.0.4",
"next-auth": "5.0.0-beta.4",
"next-themes": "^0.2.1",
"nodemailer": "^6.9.8",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"resend": "^2.1.0",
"superjson": "^2.2.1",
"tailwindcss-animate": "^1.0.7",
"zod": "^3.22.4"
Expand All @@ -39,6 +41,7 @@
"@retestlabs/typescript-config": "workspace:*",
"@types/eslint": "^8.44.9",
"@types/node": "^17.0.45",
"@types/nodemailer": "^6.4.14",
"@types/react": "^18.2.45",
"@types/react-dom": "^18.2.17",
"autoprefixer": "^10.4.16",
Expand Down
Binary file added apps/web/src/app/.page.tsx.swp
Binary file not shown.
3 changes: 1 addition & 2 deletions apps/web/src/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { GET, POST } from "@/auth";
export const runtime = "edge";
export { GET, POST } from "@/auth";
3 changes: 2 additions & 1 deletion apps/web/src/app/app/[workspace]/experiments/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from "@retestlabs/ui/accordion";
import { WrenchIcon } from "lucide-react";
import { useParams } from "next/navigation";
import { Title } from "@/components/title";

const Page = () => {
const params = useParams<{ workspace: string }>();
Expand All @@ -25,7 +26,7 @@ const Page = () => {
return (
<div className="space-y-2">
<div className="flex justify-between">
<h1 className="font-bold">Experiments</h1>
<Title>Experiments</Title>
<div className="flex items-center space-x-2">
<Button asChild variant="outline" size="sm">
<Link href="/app/setup">
Expand Down
98 changes: 98 additions & 0 deletions apps/web/src/app/app/[workspace]/members/invitations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"use client";

import { trpc } from "@/lib/trpc";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@retestlabs/ui/table";
import { useParams } from "next/navigation";
import { useQueryClient } from "@tanstack/react-query";
import { getQueryKey } from "@trpc/react-query";

import { Input } from "@retestlabs/ui/input";
import { Button } from "@retestlabs/ui/button";
import { Title } from "@/components/title";

export const Invitations = () => {
const params = useParams<{ workspace: string }>();
let queryClient = useQueryClient();

let listWorkspaceInvites = trpc.listWorkspaceInvites.useQuery({
workspaceHandle: params.workspace,
});

let listWorkspaceInvitesKeys = getQueryKey(
trpc.listWorkspaceInvites,
{
workspaceHandle: params.workspace,
},
"query",
);

let inviteUserToWorkspace = trpc.inviteUserToWorkspace.useMutation({
onSuccess: () => {
console.log("success");
queryClient.invalidateQueries(listWorkspaceInvitesKeys);
},
});

return (
<>
<Title>Invitations</Title>
<Table>
<TableHeader>
<TableRow>
<TableHead>From</TableHead>
<TableHead>To</TableHead>
<TableHead>Send</TableHead>
<TableHead>-</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{listWorkspaceInvites.data?.map((invite) => (
<TableRow key={invite.id}>
<TableCell className="font-medium">
<div>
<p className="font-bold">{invite.owner?.name}</p>
<p className="text-muted-foreground">{invite.owner?.email}</p>
</div>
</TableCell>
<TableCell>{invite.email}</TableCell>
<TableCell>
{invite.xata.updatedAt.toLocaleDateString()}
</TableCell>
<TableCell></TableCell>
</TableRow>
))}
</TableBody>
</Table>

<form
className="flex space-x-4 w-max mx-auto mt-4"
onSubmit={(event) => {
event.preventDefault();
let formData = new FormData(event.currentTarget);
let email = formData.get("email") as string;
inviteUserToWorkspace.mutate({
workspaceHandle: params.workspace,
email,
});
}}
>
<Input
required
name="email"
type="email"
placeholder="[email protected]"
/>
<Button type="submit" disabled={inviteUserToWorkspace.isLoading}>
Invite
</Button>
</form>
</>
);
};
86 changes: 44 additions & 42 deletions apps/web/src/app/app/[workspace]/members/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import { trpc } from "@/lib/trpc";
import {
Table,
TableBody,
Expand All @@ -8,52 +9,53 @@ import {
TableHeader,
TableRow,
} from "@retestlabs/ui/table";
import { useParams } from "next/navigation";

import { Title } from "@/components/title";
import { Invitations } from "./invitations";
import { useUser } from "@/hooks/use-user";

const users = [
{
name: "Anthony Cueva",
email: "[email protected]",
role: "admin",
},
{
name: "Railly Hugo",
email: "[email protected]",
role: "admin",
},
];

function TableDemo() {
return (
<Table>
<TableHeader>
<TableRow>
<TableHead>User</TableHead>
<TableHead>Role</TableHead>
<TableHead>_</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{users.map((user) => (
<TableRow key={user.email}>
<TableCell className="font-medium">
<div>
<p className="font-bold">{user.name}</p>
<p className="text-muted-foreground">{user.email}</p>
</div>
</TableCell>
<TableCell>{user.role}</TableCell>
<TableCell></TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}
const MembersPage = () => {
const params = useParams<{ workspace: string }>();

let listWorspaceUsers = trpc.listWorspaceUsers.useQuery({
workspaceHandle: params.workspace,
});

let { user } = useUser();

let isOwner =
listWorspaceUsers.data?.find((u) => u.email === user?.email)?.role ===
"owner";

return (
<div>
<h2 className="text-xl font-bold">Members</h2>
<TableDemo />
<Title>Members</Title>
<Table>
<TableHeader>
<TableRow>
<TableHead>User</TableHead>
<TableHead>Role</TableHead>
<TableHead>_</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{listWorspaceUsers.data?.map((user) => (
<TableRow key={user.email}>
<TableCell className="font-medium">
<div>
<p className="font-bold">{user.name}</p>
<p className="text-muted-foreground">{user.email}</p>
</div>
</TableCell>
<TableCell>{user.role}</TableCell>
<TableCell></TableCell>
</TableRow>
))}
</TableBody>
</Table>

{isOwner && <Invitations />}
</div>
);
};
Expand Down
8 changes: 7 additions & 1 deletion apps/web/src/app/app/[workspace]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { Title } from "@/components/title";

const Page = () => {
return <div>Page</div>;
return (
<div>
<Title>Hello</Title>
</div>
);
};

export default Page;
2 changes: 1 addition & 1 deletion apps/web/src/app/app/create-workspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const CreateWorkspace = () => {
await xata.db.workspace_user_relations.create({
workspace: workspace.id,
user: user.id,
isCreator: true,
isOwner: true,
});

redirect(`/app/${workspace.handle}`);
Expand Down
2 changes: 2 additions & 0 deletions apps/web/src/app/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CreateWorkspace } from "./create-workspace";
import { WorskpaceInvites } from "./workspace-invites";
import { WorkspaceList } from "./workspace-list";


Expand All @@ -11,6 +12,7 @@ const Page = () => {
<div>TODO: list the workspaces her has been invited to</div>
</div>
<CreateWorkspace />
<WorskpaceInvites />
</div>
);
};
Expand Down
Loading

0 comments on commit 275ef94

Please sign in to comment.