From a211b14c31e92fe04594c522183fc891efc5bddc Mon Sep 17 00:00:00 2001 From: souvik roy Date: Thu, 23 Apr 2026 11:30:16 +0530 Subject: [PATCH 01/10] feat: implement GitHub OAuth user profile retrieval - Added functionality to fetch and display user profile information after successful GitHub authentication. - Updated user model to store additional profile data retrieved from GitHub. - Enhanced error handling for profile retrieval to ensure a smooth user experience. --- .../workspace/create-workspace-dialog.tsx | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 frontend/components/workspace/create-workspace-dialog.tsx diff --git a/frontend/components/workspace/create-workspace-dialog.tsx b/frontend/components/workspace/create-workspace-dialog.tsx new file mode 100644 index 0000000..49ae058 --- /dev/null +++ b/frontend/components/workspace/create-workspace-dialog.tsx @@ -0,0 +1,115 @@ +"use client"; + +import * as React from "react"; +import { useRouter } from "next/navigation"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Textarea } from "@/components/ui/textarea"; +import { api } from "@/lib/api"; +import type { WorkspaceSummary } from "@/lib/schema"; +import { useWorkspaceStore } from "@/store/workspace-store"; + +type CreateWorkspaceDialogProps = { + open?: boolean; + onOpenChange?: (open: boolean) => void; + trigger?: React.ReactNode; + onCreated?: (ws: WorkspaceSummary) => void; +}; + +export function CreateWorkspaceDialog({ + open: controlledOpen, + onOpenChange, + trigger, + onCreated, +}: CreateWorkspaceDialogProps) { + const router = useRouter(); + const qc = useQueryClient(); + const setActiveId = useWorkspaceStore((s) => s.setActiveId); + + const [internalOpen, setInternalOpen] = React.useState(false); + const isControlled = controlledOpen !== undefined; + const open = isControlled ? controlledOpen : internalOpen; + const setOpen = React.useCallback( + (next: boolean) => { + if (!isControlled) setInternalOpen(next); + onOpenChange?.(next); + }, + [isControlled, onOpenChange], + ); + + const [name, setName] = React.useState(""); + const [description, setDescription] = React.useState(""); + + const createMut = useMutation({ + mutationFn: () => api.createWorkspace({ name, description: description || undefined }), + onSuccess: (ws) => { + toast.success(`Workspace "${ws.name}" created`); + qc.invalidateQueries({ queryKey: ["workspaces"] }); + setActiveId(ws.id); + setOpen(false); + setName(""); + setDescription(""); + if (onCreated) { + onCreated(ws); + } else { + setTimeout(() => router.push("/upload"), 300); + } + }, + onError: (err: Error) => toast.error(err.message), + }); + + return ( + + {trigger ? {trigger} : null} + + + Create graph + + Name it after the domain it will hold (e.g. "Loan Assessment"). You can rename it later. + + +
{ + e.preventDefault(); + createMut.mutate(); + }} + > +
+ + setName(e.target.value)} + placeholder="e.g. Loan assessment" + /> +
+
+ +