Skip to content

Commit 54c6caf

Browse files
committed
fix: UI consistencies, icon colors, organization improvements
1 parent 03207f6 commit 54c6caf

File tree

8 files changed

+213
-124
lines changed

8 files changed

+213
-124
lines changed

apps/dashboard/app/(main)/organizations/[slug]/components/member-list.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ function RoleSelector({
7777

7878
return (
7979
<Select
80-
defaultValue={member.role}
8180
disabled={isUpdatingMember}
8281
onValueChange={(newRole) =>
8382
onUpdateRole({
@@ -86,6 +85,7 @@ function RoleSelector({
8685
organizationId,
8786
})
8887
}
88+
value={member.role}
8989
>
9090
<SelectTrigger className="w-32 rounded">
9191
<SelectValue placeholder="Select a role" />

apps/dashboard/app/(main)/organizations/[slug]/components/settings-tab.tsx

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ export function SettingsTab({ organization }: SettingsTabProps) {
4949
const [isSaving, setIsSaving] = useState(false);
5050
const [isDeleting, setIsDeleting] = useState(false);
5151

52-
const { updateOrganization, deleteOrganization } = useOrganizations();
52+
const { updateOrganizationAsync, deleteOrganizationAsync } =
53+
useOrganizations();
5354

5455
// Fetch organization websites using tRPC
5556
const { data: websites, isLoading: isLoadingWebsites } =
@@ -69,24 +70,22 @@ export function SettingsTab({ organization }: SettingsTabProps) {
6970
setSlug(cleanSlug(value));
7071
};
7172

72-
const handleSave = () => {
73+
const handleSave = async () => {
7374
if (!(name.trim() && slug.trim())) {
7475
toast.error('Name and slug are required');
7576
return;
7677
}
7778

7879
setIsSaving(true);
7980
try {
80-
updateOrganization({
81+
await updateOrganizationAsync({
8182
organizationId: organization.id,
8283
data: {
8384
name: name.trim(),
8485
slug: slug.trim(),
8586
},
8687
});
8788

88-
toast.success('Organization updated successfully');
89-
9089
// If slug changed, redirect to new URL
9190
if (slug !== organization.slug) {
9291
router.push(`/organizations/${slug}`);
@@ -101,7 +100,7 @@ export function SettingsTab({ organization }: SettingsTabProps) {
101100
const handleDelete = async () => {
102101
setIsDeleting(true);
103102
try {
104-
await deleteOrganization(organization.id);
103+
await deleteOrganizationAsync(organization.id);
105104
toast.success('Organization deleted successfully');
106105
router.push('/organizations');
107106
} catch (_error) {
@@ -120,7 +119,11 @@ export function SettingsTab({ organization }: SettingsTabProps) {
120119
<Card>
121120
<CardHeader>
122121
<CardTitle className="flex items-center gap-2">
123-
<GearIcon className="h-5 w-5" size={16} weight="duotone" />
122+
<GearIcon
123+
className="h-5 w-5 not-dark:text-primary"
124+
size={16}
125+
weight="duotone"
126+
/>
124127
Organization Settings
125128
</CardTitle>
126129
<CardDescription>
@@ -135,7 +138,7 @@ export function SettingsTab({ organization }: SettingsTabProps) {
135138
<div className="space-y-2">
136139
<Label htmlFor="org-name">Organization Name</Label>
137140
<Input
138-
className="rounded-lg"
141+
className="rounded"
139142
id="org-name"
140143
onChange={(e) => setName(e.target.value)}
141144
placeholder="My Organization"
@@ -147,7 +150,7 @@ export function SettingsTab({ organization }: SettingsTabProps) {
147150
<div className="space-y-2">
148151
<Label htmlFor="org-slug">Organization Slug</Label>
149152
<Input
150-
className="rounded-lg font-mono"
153+
className="rounded font-mono"
151154
id="org-slug"
152155
onChange={(e) => handleSlugChange(e.target.value)}
153156
placeholder="my-organization"
@@ -162,7 +165,7 @@ export function SettingsTab({ organization }: SettingsTabProps) {
162165
{/* Save Button */}
163166
<div className="flex justify-end pt-4">
164167
<Button
165-
className="rounded-lg"
168+
className="rounded"
166169
disabled={!hasChanges || isSaving}
167170
onClick={handleSave}
168171
>
@@ -186,7 +189,11 @@ export function SettingsTab({ organization }: SettingsTabProps) {
186189
<Card>
187190
<CardHeader>
188191
<CardTitle className="flex items-center gap-2">
189-
<GlobeIcon className="h-5 w-5" size={16} weight="duotone" />
192+
<GlobeIcon
193+
className="h-5 w-5 not-dark:text-primary"
194+
size={16}
195+
weight="duotone"
196+
/>
190197
Organization Websites
191198
</CardTitle>
192199
<CardDescription>
@@ -236,16 +243,16 @@ export function SettingsTab({ organization }: SettingsTabProps) {
236243
))}
237244
</div>
238245
) : (
239-
<div className="py-8 text-center">
246+
<div className="mx-auto py-8 text-center">
240247
<GlobeIcon
241-
className="mx-auto mb-2 h-8 w-8 text-muted-foreground"
248+
className="mx-auto mb-2 h-8 w-8 not-dark:text-primary"
242249
size={32}
243250
weight="duotone"
244251
/>
245-
<p className="text-muted-foreground text-sm">
252+
<p className="mx-auto text-muted-foreground text-sm">
246253
No websites in this organization
247254
</p>
248-
<p className="mt-1 text-muted-foreground text-xs">
255+
<p className="mx-auto mt-1 text-muted-foreground text-xs">
249256
Transfer websites from your personal account or create new ones
250257
</p>
251258
</div>

apps/dashboard/app/(main)/organizations/[slug]/components/transfer-assets.tsx

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,11 @@ export function TransferAssets({ organizationId }: { organizationId: string }) {
8585
<Card>
8686
<CardHeader className="pb-4">
8787
<CardTitle className="flex items-center gap-2 text-base">
88-
<UserIcon size={18} weight="duotone" />
88+
<UserIcon
89+
className="not-dark:text-primary"
90+
size={18}
91+
weight="duotone"
92+
/>
8993
Your Personal Websites
9094
</CardTitle>
9195
<CardDescription>
@@ -118,7 +122,11 @@ export function TransferAssets({ organizationId }: { organizationId: string }) {
118122
<Card>
119123
<CardHeader className="pb-4">
120124
<CardTitle className="flex items-center gap-2 text-base">
121-
<BuildingsIcon size={18} weight="duotone" />
125+
<BuildingsIcon
126+
className="not-dark:text-primary"
127+
size={18}
128+
weight="duotone"
129+
/>
122130
Organization Websites
123131
</CardTitle>
124132
<CardDescription>
@@ -162,7 +170,10 @@ export function TransferAssets({ organizationId }: { organizationId: string }) {
162170
}`}
163171
>
164172
<div className="rounded bg-primary/20 p-1.5">
165-
<UserIcon className="h-3.5 w-3.5 text-primary" size={14} />
173+
<UserIcon
174+
className="h-3.5 w-3.5 not-dark:text-primary"
175+
size={14}
176+
/>
166177
</div>
167178
<div className="min-w-0">
168179
<p className="truncate font-medium text-foreground text-sm">
@@ -178,7 +189,7 @@ export function TransferAssets({ organizationId }: { organizationId: string }) {
178189
<div className="-translate-x-1/2 -translate-y-1/2 absolute top-1/2 left-1/2">
179190
<div className="flex items-center gap-2 rounded-full bg-primary/20 px-4 py-2 shadow-lg">
180191
<ArrowRightIcon
181-
className={`text-primary transition-transform duration-1000 ${
192+
className={`not-dark:text-primary transition-transform duration-1000 ${
182193
transferringWebsite.fromSide === 'organization'
183194
? 'rotate-180'
184195
: ''
@@ -199,7 +210,11 @@ export function TransferAssets({ organizationId }: { organizationId: string }) {
199210
<Card>
200211
<CardHeader className="pb-4">
201212
<CardTitle className="flex items-center gap-2 text-base">
202-
<UserIcon size={18} weight="duotone" />
213+
<UserIcon
214+
className="not-dark:text-primary"
215+
size={18}
216+
weight="duotone"
217+
/>
203218
Your Personal Websites
204219
</CardTitle>
205220
<CardDescription>
@@ -240,7 +255,11 @@ export function TransferAssets({ organizationId }: { organizationId: string }) {
240255
<Card>
241256
<CardHeader className="pb-4">
242257
<CardTitle className="flex items-center gap-2 text-base">
243-
<BuildingsIcon size={18} weight="duotone" />
258+
<BuildingsIcon
259+
className="not-dark:text-primary"
260+
size={18}
261+
weight="duotone"
262+
/>
244263
Organization Websites
245264
</CardTitle>
246265
<CardDescription>

apps/dashboard/app/(main)/organizations/[slug]/components/website-selector.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function WebsiteCard({
2525
type="button"
2626
>
2727
<div className="flex-shrink-0 rounded bg-primary/10 p-1.5">
28-
<GlobeIcon className="h-3.5 w-3.5 text-primary" size={14} />
28+
<GlobeIcon className="h-3.5 w-3.5 not-dark:text-primary" size={14} />
2929
</div>
3030
<div className="min-w-0 flex-1">
3131
<p className="truncate font-medium text-foreground text-sm">
@@ -66,7 +66,7 @@ export function WebsiteSelector({
6666
) : (
6767
<div className="py-8 text-center">
6868
<GlobeIcon
69-
className="mx-auto mb-2 h-8 w-8 text-muted-foreground"
69+
className="mx-auto mb-2 h-8 w-8 not-dark:text-primary"
7070
size={32}
7171
weight="duotone"
7272
/>

apps/dashboard/app/(main)/organizations/components/organizations-tab.tsx

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ import relativeTime from 'dayjs/plugin/relativeTime';
1212
import Link from 'next/link';
1313
import { useState } from 'react';
1414
import { toast } from 'sonner';
15+
import {
16+
AlertDialog,
17+
AlertDialogAction,
18+
AlertDialogCancel,
19+
AlertDialogContent,
20+
AlertDialogDescription,
21+
AlertDialogFooter,
22+
AlertDialogHeader,
23+
AlertDialogTitle,
24+
} from '@/components/ui/alert-dialog';
1525
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
1626
import { Badge } from '@/components/ui/badge';
1727
import { Button } from '@/components/ui/button';
@@ -48,36 +58,36 @@ export function OrganizationsTab({
4858
}: OrganizationsTabProps) {
4959
const {
5060
setActiveOrganization,
51-
deleteOrganization,
61+
deleteOrganizationAsync,
5262
isSettingActiveOrganization,
5363
isDeletingOrganization,
5464
} = useOrganizations();
5565
const [deletingId, setDeletingId] = useState<string | null>(null);
66+
const [confirmDelete, setConfirmDelete] = useState<{
67+
id: string;
68+
name: string;
69+
} | null>(null);
5670

5771
const handleSetActive = (organizationId: string) => {
5872
setActiveOrganization(organizationId);
5973
};
6074

61-
const handleDelete = async (
62-
organizationId: string,
63-
organizationName: string
64-
) => {
65-
if (
66-
!confirm(
67-
`Are you sure you want to delete "${organizationName}"? This action cannot be undone.`
68-
)
69-
) {
75+
const handleDelete = (organizationId: string, organizationName: string) => {
76+
setConfirmDelete({ id: organizationId, name: organizationName });
77+
};
78+
79+
const confirmDeleteAction = async () => {
80+
if (!confirmDelete) {
7081
return;
7182
}
72-
73-
setDeletingId(organizationId);
83+
setDeletingId(confirmDelete.id);
7484
try {
75-
deleteOrganization(organizationId);
76-
} catch (error) {
77-
console.error('Failed to delete organization:', error);
85+
await deleteOrganizationAsync(confirmDelete.id);
86+
} catch (_error) {
7887
toast.error('Failed to delete organization');
7988
} finally {
8089
setDeletingId(null);
90+
setConfirmDelete(null);
8191
}
8292
};
8393

@@ -262,6 +272,30 @@ export function OrganizationsTab({
262272
);
263273
})}
264274
</div>
275+
276+
<AlertDialog
277+
onOpenChange={(open) => !open && setConfirmDelete(null)}
278+
open={!!confirmDelete}
279+
>
280+
<AlertDialogContent>
281+
<AlertDialogHeader>
282+
<AlertDialogTitle>Delete organization</AlertDialogTitle>
283+
<AlertDialogDescription>
284+
This will permanently delete "{confirmDelete?.name}" and all
285+
associated resources. This action cannot be undone.
286+
</AlertDialogDescription>
287+
</AlertDialogHeader>
288+
<AlertDialogFooter>
289+
<AlertDialogCancel>Cancel</AlertDialogCancel>
290+
<AlertDialogAction
291+
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
292+
onClick={confirmDeleteAction}
293+
>
294+
Delete
295+
</AlertDialogAction>
296+
</AlertDialogFooter>
297+
</AlertDialogContent>
298+
</AlertDialog>
265299
</div>
266300
);
267301
}

0 commit comments

Comments
 (0)