diff --git a/app/(customer)/dashboard/layout.tsx b/app/(customer)/dashboard/layout.tsx index 6de904b3..13b0f9e6 100644 --- a/app/(customer)/dashboard/layout.tsx +++ b/app/(customer)/dashboard/layout.tsx @@ -11,7 +11,6 @@ import {prisma} from "@/prisma"; export default async function Layout({children}: { children: React.ReactNode }) { const user = await currentUser() - console.log(user) if (user) { const userInfo = await prisma.user.findUnique({ where: { diff --git a/app/(customer)/dashboard/projects/[projectId]/edit/page.tsx b/app/(customer)/dashboard/projects/[projectId]/edit/page.tsx index 1d02ea5c..383cd987 100644 --- a/app/(customer)/dashboard/projects/[projectId]/edit/page.tsx +++ b/app/(customer)/dashboard/projects/[projectId]/edit/page.tsx @@ -3,7 +3,7 @@ import {Page, PageContent, PageHeader, PageTitle} from "@/features/layout/page"; import {requiredCurrentUser} from "@/auth/current-user"; import {prisma} from "@/prisma"; import {notFound} from "next/navigation"; -import {ProjectForm} from "@/components/wrappers/project/ProjectForm"; +import {ProjectForm} from "@/components/wrappers/Project/ProjectForm"; export default async function RoutePage(props: PageParams<{ @@ -16,12 +16,31 @@ export default async function RoutePage(props: PageParams<{ const project = await prisma.project.findUnique({ where: { id: projectId, + }, + include: { + databases: {} } }); if (!project) { notFound(); } + const organization = await prisma.organization.findFirst({ + where: { + slug: 'default', + } + }) + const availableDatabases = await prisma.database.findMany({ + where: { + OR: [ + { projectId: null }, + { projectId: project.id }, + ], + }, + orderBy: { + createdAt: 'desc', + }, + }) return ( @@ -32,7 +51,7 @@ export default async function RoutePage(props: PageParams<{ - + ) diff --git a/app/(customer)/dashboard/projects/[projectId]/page.tsx b/app/(customer)/dashboard/projects/[projectId]/page.tsx index 5fc8b175..f57372c9 100644 --- a/app/(customer)/dashboard/projects/[projectId]/page.tsx +++ b/app/(customer)/dashboard/projects/[projectId]/page.tsx @@ -12,13 +12,15 @@ export default async function RoutePage(props: PageParams<{ projectId: string }> const {projectId} = await props.params - // const project = await prisma.project.findUnique({ - // where: { - // id: projectId, - // }, - // }) + const project = await prisma.project.findUnique({ + where: { + id: projectId, + }, + include:{ + databases: {} + } + }) - const project = projects.find(p => p.id === projectId) return ( @@ -35,7 +37,7 @@ export default async function RoutePage(props: PageParams<{ projectId: string }> - {/*{project.description}*/} + {/*{Project.description}*/} diff --git a/app/(customer)/dashboard/projects/new/page.tsx b/app/(customer)/dashboard/projects/new/page.tsx index 19f9466e..cf677fdf 100644 --- a/app/(customer)/dashboard/projects/new/page.tsx +++ b/app/(customer)/dashboard/projects/new/page.tsx @@ -1,7 +1,7 @@ import {PageParams} from "@/types/next"; import {Page, PageContent, PageHeader, PageTitle} from "@/features/layout/page"; import {prisma} from "@/prisma"; -import {ProjectForm} from "@/components/wrappers/project/ProjectForm"; +import {ProjectForm} from "@/components/wrappers/Project/ProjectForm"; export default async function RoutePage(props: PageParams<{}>) { @@ -15,6 +15,12 @@ export default async function RoutePage(props: PageParams<{}>) { }, }) + const organization = await prisma.organization.findFirst({ + where: { + slug: 'default', + } + }) + return ( @@ -23,12 +29,7 @@ export default async function RoutePage(props: PageParams<{}>) { - Add databases - {availableDatabases.map(database => -
- {database.name} -
)} - +
) diff --git a/app/(customer)/dashboard/projects/page.tsx b/app/(customer)/dashboard/projects/page.tsx index 4a5a979a..86e10d0f 100644 --- a/app/(customer)/dashboard/projects/page.tsx +++ b/app/(customer)/dashboard/projects/page.tsx @@ -5,11 +5,21 @@ import {Button} from "@/components/ui/button"; import Link from 'next/link' import {Page, PageActions, PageContent, PageHeader, PageTitle} from "@/features/layout/page"; import {projects} from "@/utils/mock-data"; -import {ProjectCard} from "@/components/wrappers/project/ProjectCard"; +import {ProjectCard} from "@/components/wrappers/Project/ProjectCard"; export default async function RoutePage(props: PageParams<{}>) { - // const projects = await prisma.project.findMany({}) + + const projects = await prisma.project.findMany({ + where: { + organization: { + slug: "default", + } + }, + include:{ + databases: {} + } + }) return ( @@ -44,8 +54,6 @@ export default async function RoutePage(props: PageParams<{}>) { } - - ) diff --git a/prisma/migrations/20241129121410_2024_11_29/migration.sql b/prisma/migrations/20241130153218_2024_11_30/migration.sql similarity index 80% rename from prisma/migrations/20241129121410_2024_11_29/migration.sql rename to prisma/migrations/20241130153218_2024_11_30/migration.sql index 751d3172..506bda3d 100644 --- a/prisma/migrations/20241129121410_2024_11_29/migration.sql +++ b/prisma/migrations/20241130153218_2024_11_30/migration.sql @@ -1,9 +1,3 @@ -/* - Warnings: - - - A unique constraint covering the columns `[generatedId]` on the table `databases` will be added. If there are existing duplicate values, this will fail. - -*/ -- AlterTable ALTER TABLE "databases" ADD COLUMN "project_id" TEXT; @@ -34,9 +28,6 @@ CREATE UNIQUE INDEX "organizations_slug_key" ON "organizations"("slug"); -- CreateIndex CREATE UNIQUE INDEX "projects_slug_key" ON "projects"("slug"); --- CreateIndex -CREATE UNIQUE INDEX "databases_generatedId_key" ON "databases"("generatedId"); - -- AddForeignKey ALTER TABLE "projects" ADD CONSTRAINT "projects_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "organizations"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/src/auth/auth.ts b/src/auth/auth.ts index d475fff6..3f225040 100644 --- a/src/auth/auth.ts +++ b/src/auth/auth.ts @@ -6,6 +6,7 @@ import {env} from "@/env.mjs"; import GoogleProvider from "next-auth/providers/google"; + export const {handlers, auth: baseAuth, signIn, signOut} = NextAuth({ adapter: PrismaAdapter(prisma), theme: { @@ -78,22 +79,20 @@ export const {handlers, auth: baseAuth, signIn, signOut} = NextAuth({ // // session.user.authMethod = user.authMethod; // return session // }, - async jwt({token, trigger, session, user}) { + async jwt({ token, trigger, session, user }) { if (trigger === "update" && session) { - return {...session, user: {...token, ...session?.user}}; - // return {...token, ...session?.user}; + return { ...token, ...session?.user }; } - return {...token, ...user}; + return { ...token, ...user }; }, - async session({session, token, user}) { - session.user = token.user; - // session.user = token; + async session({ session, token, user }) { + session.user = token; return session; }, - async signIn({account, user, profile}) { + async signIn({ account, user, profile }) { const existingUser = await prisma.user.findFirst({ - where: {email: user.email}, + where: { email: user.email }, }); if (!existingUser) { @@ -126,7 +125,7 @@ export const {handlers, auth: baseAuth, signIn, signOut} = NextAuth({ // Update auth method if user exists await prisma.user.update({ - where: {id: existingUser.id}, + where: { id: existingUser.id }, data: { authMethod: account.provider, }, @@ -136,5 +135,4 @@ export const {handlers, auth: baseAuth, signIn, signOut} = NextAuth({ }, } -}); - +}); \ No newline at end of file diff --git a/src/auth/current-user.ts b/src/auth/current-user.ts index 27ef7a05..e7ba0bff 100644 --- a/src/auth/current-user.ts +++ b/src/auth/current-user.ts @@ -3,7 +3,6 @@ import {User} from "@prisma/client"; export const currentUser = async () => { const session = await baseAuth(); - console.log("mysession", session) if (!session?.user) { return null; } diff --git a/src/components/wrappers/Dashboard/SideBar/app-sidebar.tsx b/src/components/wrappers/Dashboard/SideBar/app-sidebar.tsx index 6c4628d7..7b6e27ad 100644 --- a/src/components/wrappers/Dashboard/SideBar/app-sidebar.tsx +++ b/src/components/wrappers/Dashboard/SideBar/app-sidebar.tsx @@ -3,12 +3,12 @@ import { SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, - SidebarMenu, + SidebarMenu, SidebarMenuButton, SidebarMenuItem, } from "@/components/ui/sidebar" import {LoggedInButton} from "@/components/wrappers/Dashboard/LoggedInButton/LoggedInButton"; import {SidebarMenuCustom} from "@/components/wrappers/Dashboard/SideBar/SideBarMenu/SideBarMenu"; -import {OrganizationComboBox} from "@/components/wrappers/organization/OrganizationCombobox"; +import {OrganizationComboBox} from "@/components/wrappers/Organization/OrganizationCombobox"; import {prisma} from "@/prisma"; export async function AppSidebar() { diff --git a/src/components/wrappers/MultiSelect/MultiSelect.tsx b/src/components/wrappers/MultiSelect/MultiSelect.tsx new file mode 100644 index 00000000..da212531 --- /dev/null +++ b/src/components/wrappers/MultiSelect/MultiSelect.tsx @@ -0,0 +1,382 @@ +//https://github.com/sersavan/shadcn-multi-select-component + +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; +import { + CheckIcon, + XCircle, + ChevronDown, + XIcon, + WandSparkles, +} from "lucide-react"; + +import { cn } from "@/lib/utils"; +import { Separator } from "@/components/ui/separator"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + CommandSeparator, +} from "@/components/ui/command"; + +/** + * Variants for the multi-select component to handle different styles. + * Uses class-variance-authority (cva) to define different styles based on "variant" prop. + */ +const multiSelectVariants = cva( + "m-1 transition ease-in-out delay-150 hover:-translate-y-1 hover:scale-110 duration-300", + { + variants: { + variant: { + default: + "border-foreground/10 text-foreground bg-card hover:bg-card/80", + secondary: + "border-foreground/10 bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + inverted: "inverted", + }, + }, + defaultVariants: { + variant: "default", + }, + } +); + +/** + * Props for MultiSelect component + */ +interface MultiSelectProps + extends React.ButtonHTMLAttributes, + VariantProps { + /** + * An array of option objects to be displayed in the multi-select component. + * Each option object has a label, value, and an optional icon. + */ + options: { + /** The text to display for the option. */ + label: string; + /** The unique value associated with the option. */ + value: string; + /** Optional icon component to display alongside the option. */ + icon?: React.ComponentType<{ className?: string }>; + }[]; + + /** + * Callback function triggered when the selected values change. + * Receives an array of the new selected values. + */ + onValueChange: (value: string[]) => void; + + /** The default selected values when the component mounts. */ + defaultValue?: string[]; + + /** + * Placeholder text to be displayed when no values are selected. + * Optional, defaults to "Select options". + */ + placeholder?: string; + + /** + * Animation duration in seconds for the visual effects (e.g., bouncing badges). + * Optional, defaults to 0 (no animation). + */ + animation?: number; + + /** + * Maximum number of items to display. Extra selected items will be summarized. + * Optional, defaults to 3. + */ + maxCount?: number; + + /** + * The modality of the popover. When set to true, interaction with outside elements + * will be disabled and only popover content will be visible to screen readers. + * Optional, defaults to false. + */ + modalPopover?: boolean; + + /** + * If true, renders the multi-select component as a child of another component. + * Optional, defaults to false. + */ + asChild?: boolean; + + /** + * Additional class names to apply custom styles to the multi-select component. + * Optional, can be used to add custom styles. + */ + className?: string; +} + +export const MultiSelect = React.forwardRef< + HTMLButtonElement, + MultiSelectProps +>( + ( + { + options, + onValueChange, + variant, + defaultValue = [], + placeholder = "Select options", + animation = 0, + maxCount = 3, + modalPopover = false, + asChild = false, + className, + ...props + }, + ref + ) => { + const [selectedValues, setSelectedValues] = + React.useState(defaultValue); + const [isPopoverOpen, setIsPopoverOpen] = React.useState(false); + const [isAnimating, setIsAnimating] = React.useState(false); + + const handleInputKeyDown = ( + event: React.KeyboardEvent + ) => { + if (event.key === "Enter") { + setIsPopoverOpen(true); + } else if (event.key === "Backspace" && !event.currentTarget.value) { + const newSelectedValues = [...selectedValues]; + newSelectedValues.pop(); + setSelectedValues(newSelectedValues); + onValueChange(newSelectedValues); + } + }; + + const toggleOption = (option: string) => { + const newSelectedValues = selectedValues.includes(option) + ? selectedValues.filter((value) => value !== option) + : [...selectedValues, option]; + setSelectedValues(newSelectedValues); + onValueChange(newSelectedValues); + }; + + const handleClear = () => { + setSelectedValues([]); + onValueChange([]); + }; + + const handleTogglePopover = () => { + setIsPopoverOpen((prev) => !prev); + }; + + const clearExtraOptions = () => { + const newSelectedValues = selectedValues.slice(0, maxCount); + setSelectedValues(newSelectedValues); + onValueChange(newSelectedValues); + }; + + const toggleAll = () => { + if (selectedValues.length === options.length) { + handleClear(); + } else { + const allValues = options.map((option) => option.value); + setSelectedValues(allValues); + onValueChange(allValues); + } + }; + + return ( + + + + + setIsPopoverOpen(false)} + > + + + + No results found. + + +
+ +
+ (Select All) +
+ {options.map((option) => { + const isSelected = selectedValues.includes(option.value); + return ( + toggleOption(option.value)} + className="cursor-pointer" + > +
+ +
+ {option.icon && ( + + )} + {option.label} +
+ ); + })} +
+ + +
+ {selectedValues.length > 0 && ( + <> + + Clear + + + + )} + setIsPopoverOpen(false)} + className="flex-1 justify-center cursor-pointer max-w-full" + > + Close + +
+
+
+
+
+ {animation > 0 && selectedValues.length > 0 && ( + setIsAnimating(!isAnimating)} + /> + )} +
+ ); + } +); + +MultiSelect.displayName = "MultiSelect"; \ No newline at end of file diff --git a/src/components/wrappers/organization/OrganizationCombobox.tsx b/src/components/wrappers/Organization/OrganizationCombobox.tsx similarity index 84% rename from src/components/wrappers/organization/OrganizationCombobox.tsx rename to src/components/wrappers/Organization/OrganizationCombobox.tsx index df1d0928..9e6955f8 100644 --- a/src/components/wrappers/organization/OrganizationCombobox.tsx +++ b/src/components/wrappers/Organization/OrganizationCombobox.tsx @@ -8,6 +8,7 @@ import {Organization} from "@prisma/client"; export type organizationComboBoxProps = { organizations: Organization[] defaultOrganization: Organization + } @@ -31,6 +32,10 @@ export function OrganizationComboBox(props: organizationComboBoxProps) { } return ( - + ) } \ No newline at end of file diff --git a/src/components/wrappers/project/ProjectCard.tsx b/src/components/wrappers/Project/ProjectCard.tsx similarity index 90% rename from src/components/wrappers/project/ProjectCard.tsx rename to src/components/wrappers/Project/ProjectCard.tsx index 3fcbdfa4..f80a9a98 100644 --- a/src/components/wrappers/project/ProjectCard.tsx +++ b/src/components/wrappers/Project/ProjectCard.tsx @@ -11,12 +11,14 @@ export const ProjectCard = (props: projectCardProps) => { const {data: project} = props; + return (
{project.name} + {project.databases.length} databases
diff --git a/src/components/wrappers/Project/ProjectForm.action.ts b/src/components/wrappers/Project/ProjectForm.action.ts new file mode 100644 index 00000000..d4ea80e9 --- /dev/null +++ b/src/components/wrappers/Project/ProjectForm.action.ts @@ -0,0 +1,62 @@ +"use server" + +import {userAction} from "@/safe-actions"; +import {prisma} from "@/prisma"; +import {ProjectSchema} from "@/components/wrappers/Project/ProjectForm.schema"; +import {z} from "zod"; +import {ServerActionResult} from "@/types/action-type"; +import {Projects} from "@prisma/client"; + + +export const createProjectAction = userAction + .schema( + z.object({ + data: ProjectSchema, + organizationId: z.string(), + }) + ) + .action(async ({parsedInput, ctx}): Promise> => { + try { + + const project = await prisma.project.create({ + data: { + name: parsedInput.data.name, + slug: parsedInput.data.slug, + organizationId: parsedInput.organizationId, + } + }) + + for (const db of parsedInput.data.databases) { + + await prisma.database.update({ + where: { + id: db, + }, + data:{ + projectId: project.id, + } + }) + } + + return { + success: true, + value: project, + actionSuccess: { + message: "Project has been successfully created.", + messageParams: {projectName: parsedInput.data.name}, + }, + }; + } catch (error) { + return { + success: false, + actionError: { + message: "Failed to create Project.", + status: 500, // Optional: Use a meaningful status code + cause: error instanceof Error ? error.message : "Unknown error", + messageParams: {projectName: parsedInput.data.name}, + }, + }; + } + + + }); \ No newline at end of file diff --git a/src/components/wrappers/project/ProjectForm.schema.ts b/src/components/wrappers/Project/ProjectForm.schema.ts similarity index 69% rename from src/components/wrappers/project/ProjectForm.schema.ts rename to src/components/wrappers/Project/ProjectForm.schema.ts index 3ee6b62b..a66f21c7 100644 --- a/src/components/wrappers/project/ProjectForm.schema.ts +++ b/src/components/wrappers/Project/ProjectForm.schema.ts @@ -1,9 +1,10 @@ import {z} from "zod"; - +import Database from "@prisma/client" export const ProjectSchema = z.object({ name: z.string(), slug: z.string(), + databases: z.array(z.string()), }); export type ProjectSchema = z.infer; diff --git a/src/components/wrappers/Project/ProjectForm.tsx b/src/components/wrappers/Project/ProjectForm.tsx new file mode 100644 index 00000000..38556250 --- /dev/null +++ b/src/components/wrappers/Project/ProjectForm.tsx @@ -0,0 +1,156 @@ +"use client"; + +import {Card, CardContent, CardHeader} from "@/components/ui/card"; +import { + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, + useZodForm +} from "@/components/ui/form"; +import {Input} from "@/components/ui/input"; +import {Form} from "@/components/ui/form" +import {Button} from "@/components/ui/button"; +import {useMutation} from "@tanstack/react-query"; +import {ProjectSchema} from "@/components/wrappers/Project/ProjectForm.schema"; +import {createProjectAction} from "@/components/wrappers/Project/ProjectForm.action"; +import {useRouter} from "next/navigation"; +import {Database, Organization} from "@prisma/client" +import {MultiSelect} from "@/components/wrappers/MultiSelect/MultiSelect"; +import {ZodString} from "zod"; + + +export type projectFormProps = { + defaultValues?: ProjectSchema; + databases: Database[], + organization: Organization, + projectId?: string; + +} + +export const ProjectForm = (props: projectFormProps) => { + + const router = useRouter(); + const isCreate = !Boolean(props.defaultValues) + + + const formatDatabasesList = (databases: Database[]) => { + return databases.map(database => ({ + value: database.id, + label: `${database.name} | ${database.generatedId}`, + })); + }; + + const formatDefaultDatabases = (databases: ProjectSchema["databases"]): string[] => { + return databases.map(database => database.id); + }; + + const formattedDefaultValues = { + ...props.defaultValues, + databases: !isCreate ? formatDefaultDatabases(props.defaultValues?.databases) : [] + } + + + const form = useZodForm({ + schema: ProjectSchema, + defaultValues: formattedDefaultValues, + + }); + + const mutation = useMutation({ + mutationFn: async (values: ProjectSchema) => { + console.log(values) + const projectCreated = await createProjectAction({data: values, organizationId: props.organization.id}); + console.log(projectCreated) + // + // if (data) { + // toast.success(`Success`); + // router.push(`/dashboard/projects/${data.id}`); + // router.refresh() + // } + // + // if (validationErrors) { + // toast.success(`Error`); + // + // } + + + } + }) + + return ( + + + + + +
{ + await mutation.mutateAsync(values); + }} + > + ( + + Name + + + + + + )} + /> + ( + + Slug + + + + + + )} + /> + ( + + Databases + + + + + Select databases you want to add to this project + + + ) + } + /> + + +
+
+ ) +} \ No newline at end of file diff --git a/src/components/wrappers/combobox.tsx b/src/components/wrappers/combobox.tsx index cdf64874..b31c0f88 100644 --- a/src/components/wrappers/combobox.tsx +++ b/src/components/wrappers/combobox.tsx @@ -20,12 +20,14 @@ import { PopoverTrigger, } from "@/components/ui/popover" import {FormControl} from "@/components/ui/form"; +import {SidebarMenuButton} from "@/components/ui/sidebar"; export type comboBoxProps = { values: Array<{ value: string, label: string }> defaultValue?: string onValueChange?: any searchField?: boolean + sideBar?: boolean } @@ -41,19 +43,33 @@ export function ComboBox(props: comboBoxProps) { return ( - + {props.sideBar ? + + {value + ? choices.find((choice) => choice.value === value)?.label + : "Select choice..."} + + + : + + } + + - + {searchField ? : null} diff --git a/src/components/wrappers/project/ProjectForm.action.ts b/src/components/wrappers/project/ProjectForm.action.ts deleted file mode 100644 index d90784da..00000000 --- a/src/components/wrappers/project/ProjectForm.action.ts +++ /dev/null @@ -1,21 +0,0 @@ -"use server" - -import {userAction} from "@/safe-actions"; -import {prisma} from "@/prisma"; -import {ProjectSchema} from "@/components/wrappers/project/ProjectForm.schema"; - - -export const createProjectAction = userAction - .schema(ProjectSchema) - .action(async ({parsedInput, ctx}) => { - // Verify if slug already exist - // await verifySlugUniqueness(parsedInput.slug); - - console.log("ctx", ctx) - return prisma.project.create({ - data: { - ...parsedInput, - } - }); - - }); \ No newline at end of file diff --git a/src/components/wrappers/project/ProjectForm.tsx b/src/components/wrappers/project/ProjectForm.tsx deleted file mode 100644 index 79157d37..00000000 --- a/src/components/wrappers/project/ProjectForm.tsx +++ /dev/null @@ -1,99 +0,0 @@ -"use client"; - -import {Card, CardContent, CardHeader} from "@/components/ui/card"; -import {FormControl, FormField, FormItem, FormLabel, FormMessage, useZodForm} from "@/components/ui/form"; -import {Input} from "@/components/ui/input"; -import {Form} from "@/components/ui/form" -import {Button} from "@/components/ui/button"; -import {useMutation} from "@tanstack/react-query"; -import {ProjectSchema} from "@/components/wrappers/project/ProjectForm.schema"; -import {createProjectAction} from "@/components/wrappers/project/ProjectForm.action"; -import {toast} from "sonner"; -import {useRouter} from "next/navigation"; -import {useSession} from "next-auth/react"; - -export type projectFormProps = { - defaultValues?: ProjectSchema; -} - -export const ProjectForm = (props: projectFormProps) => { - - const router = useRouter(); - - const {data: session} = useSession() - console.log("organization", session) - - const form = useZodForm({ - schema: ProjectSchema, - }); - - const mutation = useMutation({ - mutationFn: async (values: ProjectSchema) => { - - const {data, validationErrors} = await createProjectAction({...values, organizationId: organization?.id}); - - if (data) { - toast.success(`Success`); - router.push(`/dashboard/projects/${data.id}`); - router.refresh() - } - - if (validationErrors) { - toast.success(`Error`); - - } - - - } - }) - - return ( - - - - - -
{ - await mutation.mutateAsync(values); - }} - > - ( - - Name - - - - - - )} - /> - ( - - Slug - - - - - - )} - /> - - -
-
- ) -} \ No newline at end of file diff --git a/src/utils/init.ts b/src/utils/init.ts index 4a7875df..d0b2d2a4 100644 --- a/src/utils/init.ts +++ b/src/utils/init.ts @@ -74,7 +74,7 @@ async function createDefaultOrganization() { } }) if (!defaultOrganization) { - console.log("==== Creating default organization... ====\n") + console.log("==== Creating default Organization... ====\n") await prisma.organization.create({ data: { ...defaultOrganizationConf