Skip to content

Commit 83ea444

Browse files
authored
Merge pull request #52 from Portabase/fix/dialogs
fix/dialogs
2 parents 9327331 + 966edfa commit 83ea444

File tree

12 files changed

+156
-121
lines changed

12 files changed

+156
-121
lines changed

app/(customer)/dashboard/(admin)/agents/[agentId]/page.tsx

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
import Link from "next/link";
2-
import {GearIcon} from "@radix-ui/react-icons";
31
import {PageParams} from "@/types/next";
4-
import {Page, PageActions, PageContent, PageDescription, PageTitle} from "@/features/layout/page";
5-
import {buttonVariants} from "@/components/ui/button";
2+
import {Page, PageContent, PageDescription, PageTitle} from "@/features/layout/page";
63
import {db} from "@/db";
74
import * as drizzleDb from "@/db";
85
import {eq} from "drizzle-orm";
@@ -39,18 +36,14 @@ export default async function RoutePage(props: PageParams<{ agentId: string }>)
3936
<div className="min-w-full md:min-w-fit ">
4037
{capitalizeFirstLetter(agent.name)}
4138
</div>
42-
<div className="flex items-center gap-2 md:justify-between w-full ">
43-
<div className="flex items-center gap-2">
44-
<AgentDialog agent={agent as AgentType & { id: string }}>
45-
<div className={buttonVariants({variant: "outline", className: "cursor-pointer"})}>
46-
<GearIcon className="w-7 h-7"/>
47-
</div>
48-
</AgentDialog>
49-
</div>
50-
<div className="flex items-center gap-2">
51-
<ButtonDeleteAgent agentId={agentId} text={"Delete Agent"}/>
52-
</div>
39+
<div className="flex items-center gap-2 md:justify-between w-full ">
40+
<div className="flex items-center gap-2">
41+
<AgentDialog agent={agent as AgentType & { id: string }} typeTrigger={"edit"}/>
5342
</div>
43+
<div className="flex items-center gap-2">
44+
<ButtonDeleteAgent agentId={agentId} text={"Delete Agent"}/>
45+
</div>
46+
</div>
5447
</PageTitle>
5548
</div>
5649

app/(customer)/dashboard/(admin)/agents/page.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import {PageParams} from "@/types/next";
22
import {AgentCard} from "@/components/wrappers/dashboard/agent/agent-card/agent-card";
33
import {CardsWithPagination} from "@/components/wrappers/common/cards-with-pagination";
4-
import {Button} from "@/components/ui/button";
54
import {Page, PageActions, PageContent, PageHeader, PageTitle} from "@/features/layout/page";
65
import {notFound} from "next/navigation";
76
import {db} from "@/db";
87
import * as drizzleDb from "@/db";
98
import {desc, eq, not} from "drizzle-orm";
10-
import {EmptyStatePlaceholder} from "@/components/wrappers/common/empty-state-placeholder";
119
import {Metadata} from "next";
1210
import {AgentDialog} from "@/features/agents/components/agent.dialog";
1311

@@ -25,7 +23,6 @@ export default async function RoutePage(props: PageParams<{}>) {
2523
orderBy: (fields) => desc(fields.lastContact),
2624
});
2725

28-
2926
if (!agents) {
3027
notFound();
3128
}
@@ -36,21 +33,15 @@ export default async function RoutePage(props: PageParams<{}>) {
3633
<PageTitle>Agents</PageTitle>
3734
{agents.length > 0 && (
3835
<PageActions>
39-
<AgentDialog>
40-
<Button>+ Create Agent</Button>
41-
</AgentDialog>
36+
<AgentDialog typeTrigger={"create"} />
4237
</PageActions>
4338
)}
4439
</PageHeader>
4540
<PageContent>
4641
{agents.length > 0 ? (
4742
<CardsWithPagination data={agents} cardItem={AgentCard} cardsPerPage={4} numberOfColumns={1}/>
4843
) : (
49-
<AgentDialog>
50-
<EmptyStatePlaceholder
51-
text={"Create new Agent"}
52-
/>
53-
</AgentDialog>
44+
<AgentDialog typeTrigger="empty"/>
5445
)}
5546
</PageContent>
5647
</Page>

app/(customer)/dashboard/(organization)/projects/[projectId]/page.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import {PageParams} from "@/types/next";
22
import {Page, PageContent, PageTitle} from "@/features/layout/page";
3-
import {buttonVariants} from "@/components/ui/button";
4-
import {GearIcon} from "@radix-ui/react-icons";
53
import {
64
ButtonDeleteProject
75
} from "@/components/wrappers/dashboard/projects/button-delete-project/button-delete-project";
@@ -17,6 +15,7 @@ import {capitalizeFirstLetter} from "@/utils/text";
1715
import {ProjectDialog} from "@/features/projects/components/project.dialog";
1816
import {DatabaseWith} from "@/db/schema/07_database";
1917
import {ProjectWith} from "@/db/schema/06_project";
18+
import {isUuidv4} from "@/utils/verify-uuid";
2019

2120

2221
export default async function RoutePage(props: PageParams<{
@@ -26,6 +25,10 @@ export default async function RoutePage(props: PageParams<{
2625
projectId
2726
} = await props.params;
2827

28+
if (!isUuidv4(projectId)) {
29+
notFound()
30+
}
31+
2932
const organization = await getOrganization({});
3033
const activeMember = await getActiveMember()
3134

@@ -78,15 +81,12 @@ export default async function RoutePage(props: PageParams<{
7881
{!isMember && (
7982
<div className="flex items-center gap-2 md:justify-between w-full ">
8083
<div className="flex items-center gap-2">
81-
<ProjectDialog
82-
databases={availableDatabases}
84+
<ProjectDialog
85+
databases={availableDatabases}
8386
organization={org}
8487
project={proj as ProjectWith}
85-
>
86-
<div className={buttonVariants({variant: "outline", className: "cursor-pointer"})}>
87-
<GearIcon className="w-7 h-7"/>
88-
</div>
89-
</ProjectDialog>
88+
isEdit={true}
89+
/>
9090
</div>
9191
<div className="flex items-center gap-2">
9292
<ButtonDeleteProject projectId={projectId} text={"Delete Project"}/>

app/(customer)/dashboard/(organization)/projects/page.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {PageParams} from "@/types/next";
22
import {CardsWithPagination} from "@/components/wrappers/common/cards-with-pagination";
3-
import {Button} from "@/components/ui/button";
43
import {Page, PageActions, PageContent, PageHeader, PageTitle} from "@/features/layout/page";
54
import {ProjectCard} from "@/components/wrappers/dashboard/projects/project-card/project-card";
65
import {db} from "@/db";
@@ -56,9 +55,7 @@ export default async function RoutePage(props: PageParams<{}>) {
5655
<PageTitle>Projects</PageTitle>
5756
{(projects.length > 0 && !isMember) && (
5857
<PageActions>
59-
<ProjectDialog databases={availableDatabases} organization={organization}>
60-
<Button>+ Create Project</Button>
61-
</ProjectDialog>
58+
<ProjectDialog databases={availableDatabases} organization={organization}/>
6259
</PageActions>
6360
)}
6461
</PageHeader>
@@ -75,9 +72,7 @@ export default async function RoutePage(props: PageParams<{}>) {
7572
) : isMember ? (
7673
<EmptyStatePlaceholder text="No project available"/>
7774
) : (
78-
<ProjectDialog databases={availableDatabases} organization={organization}>
79-
<EmptyStatePlaceholder text="Create new Project"/>
80-
</ProjectDialog>
75+
<ProjectDialog databases={availableDatabases} organization={organization} isEmpty={true}/>
8176
)}
8277
</PageContent>
8378
</Page>

app/(customer)/dashboard/(organization)/settings/page.tsx

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,10 @@ export default async function RoutePage(props: PageParams<{ slug: string }>) {
3434
const storageChannels = await getOrganizationStorageChannels(organization.id)
3535
const permissions = computeOrganizationPermissions(activeMember);
3636

37-
// Fetch users for the form
3837
const users = await db.query.user.findMany({
3938
where: (fields) => isNull(fields.deletedAt)
4039
});
4140

42-
// Re-fetch organization with members to match type expectations if needed,
43-
// although getOrganization returns OrganizationWithMembers usually, let's verify or cast.
44-
// getOrganization returns Organization type from database schema, which includes relations if defined in auth lib.
45-
// However, OrganizationForm expects OrganizationWithMembers.
46-
// Let's ensure we have members.
47-
4841
const organizationWithMembers = await db.query.organization.findFirst({
4942
where: eq(drizzleDb.schemas.organization.id, organization.id),
5043
with: {
@@ -58,7 +51,6 @@ export default async function RoutePage(props: PageParams<{ slug: string }>) {
5851

5952
if (!organizationWithMembers) notFound();
6053

61-
6254
return (
6355
<Page>
6456
<PageHeader>
@@ -73,11 +65,7 @@ export default async function RoutePage(props: PageParams<{ slug: string }>) {
7365
organization={organizationWithMembers}
7466
users={users}
7567
currentUser={user}
76-
>
77-
<Button variant="outline">
78-
<GearIcon className="w-7 h-7"/>
79-
</Button>
80-
</EditOrganizationDialog>
68+
/>
8169
)}
8270
</div>
8371
<div className="flex items-center gap-2">

src/components/wrappers/common/empty-state-placeholder.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import Link from "next/link";
22
import {cn} from "@/lib/utils";
33
import {Plus} from "lucide-react";
4-
import {forwardRef} from "react";
4+
import {forwardRef, HTMLAttributes} from "react";
55

66
type EmptyStatePlaceholderProps = {
77
url?: string;
88
onClick?: () => void;
99
text: string;
1010
className?: string;
11-
} & React.HTMLAttributes<HTMLDivElement>;
11+
} & HTMLAttributes<HTMLDivElement>;
1212

1313
export const EmptyStatePlaceholder = forwardRef<HTMLDivElement, EmptyStatePlaceholderProps>(({
1414
url,

src/components/wrappers/dashboard/admin/settings/settings-tabs.tsx

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {Setting} from "@/db/schema/01_setting";
77
import {SettingsEmailSection} from "@/components/wrappers/dashboard/admin/settings/email/settings-email-section";
88
import {SettingsStorageSection} from "@/components/wrappers/dashboard/admin/settings/storage/settings-storage-section";
99
import {StorageChannelWith} from "@/db/schema/12_storage-channel";
10+
import {MailboxIcon, Save} from "lucide-react";
1011

1112
export type SettingsTabsProps = {
1213
settings: Setting
@@ -30,29 +31,44 @@ export const SettingsTabs = ({settings, storageChannels}: SettingsTabsProps) =>
3031
};
3132

3233

34+
const tabs = [
35+
{
36+
name: 'System Email',
37+
value: 'email',
38+
icon: MailboxIcon,
39+
content: (
40+
<SettingsEmailSection settings={settings}/>
41+
)
42+
},
43+
{
44+
name: 'Default Storage',
45+
value: 'storage',
46+
icon: Save,
47+
content: (
48+
<SettingsStorageSection storageChannels={storageChannels} settings={settings}/>
49+
50+
)
51+
}
52+
]
53+
54+
3355
return (
3456
<div className="h-full mt-3">
35-
<Tabs className="h-full" value={tab} onValueChange={handleChangeTab}>
36-
<TabsList className='bg-background rounded-none border-b p-0 min-w-48'>
37-
<TabsTrigger
38-
value="email"
39-
className='bg-background data-[state=active]:border-primary dark:data-[state=active]:border-primary h-full rounded-none border-0 border-b-2 border-transparent data-[state=active]:shadow-none'
40-
>
41-
Email
42-
</TabsTrigger>
43-
<TabsTrigger
44-
value="storage"
45-
className='bg-background data-[state=active]:border-primary dark:data-[state=active]:border-primary h-full rounded-none border-0 border-b-2 border-transparent data-[state=active]:shadow-none'
46-
>
47-
Default storage
48-
</TabsTrigger>
57+
<Tabs className="h-full gap-4" value={tab} onValueChange={handleChangeTab}>
58+
<TabsList>
59+
{tabs.map(({icon: Icon, name, value}) => (
60+
<TabsTrigger key={value} value={value} className='flex items-center gap-1 px-2.5 sm:px-3'>
61+
<Icon/>
62+
{name}
63+
</TabsTrigger>
64+
))}
4965
</TabsList>
50-
<TabsContent className="h-full" value="email">
51-
<SettingsEmailSection settings={settings}/>
52-
</TabsContent>
53-
<TabsContent className="h-full" value="storage">
54-
<SettingsStorageSection storageChannels={storageChannels} settings={settings}/>
55-
</TabsContent>
66+
67+
{tabs.map(tab => (
68+
<TabsContent key={tab.value} value={tab.value} className="h-full">
69+
{tab.content}
70+
</TabsContent>
71+
))}
5672
</Tabs>
5773
</div>
5874

src/components/wrappers/dashboard/admin/settings/storage/settings-storage-section.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,26 +64,25 @@ export const SettingsStorageSection = ({settings, storageChannels}: SettingsStor
6464
await mutation.mutateAsync(values);
6565
}}
6666
>
67-
<div className="flex items-center gap-3">
67+
<div className="flex flex-wrap items-center gap-3">
6868
<FormField
6969
control={form.control}
7070
name="storageChannelId"
71-
render={({field}) => (
72-
<FormItem className="flex items-center justify-center">
71+
render={({ field }) => (
72+
<FormItem className="flex-grow min-w-[200px] sm:flex-grow-0 sm:w-64">
7373
<Select value={field.value} onValueChange={field.onChange}>
74-
<SelectTrigger className="w-90 h-full mb-0">
75-
<SelectValue placeholder="Select a default storage channel"/>
74+
<SelectTrigger className="w-full h-full mb-0">
75+
<SelectValue placeholder="Select a default storage channel" />
7676
</SelectTrigger>
7777
<SelectContent>
7878
{storageChannels.map((channel) => (
7979
<SelectItem key={channel.id} value={channel.id}>
8080
<div className="flex items-center gap-2">
8181
{getChannelIcon(channel.provider)}
8282
<span className="font-medium">{channel.name}</span>
83-
<span
84-
className="text-[9px] uppercase bg-secondary px-1.5 py-0.5 rounded">
85-
{channel.provider}
86-
</span>
83+
<span className="text-[9px] uppercase bg-secondary px-1.5 py-0.5 rounded">
84+
{channel.provider}
85+
</span>
8786
</div>
8887
</SelectItem>
8988
))}
@@ -92,10 +91,11 @@ export const SettingsStorageSection = ({settings, storageChannels}: SettingsStor
9291
</FormItem>
9392
)}
9493
/>
95-
<ButtonWithLoading type="submit">
94+
<ButtonWithLoading className="flex-shrink-0 w-full sm:w-auto" type="submit">
9695
Confirm
9796
</ButtonWithLoading>
9897
</div>
98+
9999
</Form>
100100
</div>
101101
</div>

src/components/wrappers/dashboard/projects/button-delete-project/button-delete-project.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export const ButtonDeleteProject = (props: ButtonDeleteProjectProps) => {
2424
onSuccess: async (result: any) => {
2525
if (result.data?.success) {
2626
toast.success(result.data.actionSuccess.message);
27-
router.push("/");
27+
router.push("/dashboard/projects");
2828
} else {
2929
toast.error(result.data.actionError.message || "Unknown error occurred.");
3030
}

0 commit comments

Comments
 (0)