Skip to content

Commit f401e1b

Browse files
📝 Add docstrings to add-organizations-types
Docstrings generation was requested by @izadoesdev. * #51 (comment) The following files were modified: * `apps/dashboard/app/(main)/organizations/[slug]/components/invitation-list.tsx` * `apps/dashboard/app/(main)/organizations/[slug]/components/invite-member-dialog.tsx` * `apps/dashboard/app/(main)/organizations/[slug]/components/member-list.tsx` * `apps/dashboard/app/(main)/organizations/[slug]/components/organization-logo-uploader.tsx` * `apps/dashboard/app/(main)/organizations/[slug]/components/overview-tab.tsx` * `apps/dashboard/app/(main)/organizations/[slug]/components/settings-tab.tsx` * `apps/dashboard/app/(main)/organizations/[slug]/components/team-view.tsx` * `apps/dashboard/app/(main)/organizations/[slug]/components/teams-tab.tsx` * `apps/dashboard/app/(main)/organizations/[slug]/page.tsx` * `apps/dashboard/app/(main)/organizations/page.tsx` * `apps/dashboard/hooks/use-organizations.ts`
1 parent 066fed1 commit f401e1b

File tree

11 files changed

+257
-38
lines changed

11 files changed

+257
-38
lines changed

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from '@/components/ui/alert-dialog';
1717
import { Badge } from '@/components/ui/badge';
1818
import { Button } from '@/components/ui/button';
19+
import type { CancelInvitation, Invitation } from '@/hooks/use-organizations';
1920

2021
dayjs.extend(relativeTime);
2122

@@ -24,11 +25,24 @@ interface InvitationToCancel {
2425
email: string;
2526
}
2627

28+
/**
29+
* Displays a list of pending invitations with the ability to cancel individual invitations.
30+
*
31+
* Renders each invitation with its details and provides a confirmation dialog for cancellation. Returns `null` if there are no invitations to display.
32+
*
33+
* @param invitations - The list of pending invitations to display
34+
* @param onCancelInvitation - Callback to cancel an invitation by its ID
35+
* @param isCancellingInvitation - Indicates if a cancellation is currently in progress
36+
*/
2737
export function InvitationList({
2838
invitations,
2939
onCancelInvitation,
3040
isCancellingInvitation,
31-
}: any) {
41+
}: {
42+
invitations: Invitation[];
43+
onCancelInvitation: CancelInvitation;
44+
isCancellingInvitation: boolean;
45+
}) {
3246
const [invitationToCancel, setInvitationToCancel] =
3347
useState<InvitationToCancel | null>(null);
3448

@@ -54,7 +68,7 @@ export function InvitationList({
5468
</Badge>
5569
</div>
5670
<div className="space-y-3">
57-
{invitations.map((invitation: any) => (
71+
{invitations.map((invitation) => (
5872
<div
5973
className="flex items-center justify-between rounded border border-border/50 bg-muted/30 p-4"
6074
key={invitation.id}

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

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,33 @@ import {
1919
SelectTrigger,
2020
SelectValue,
2121
} from '@/components/ui/select';
22-
import { useOrganizationMembers } from '@/hooks/use-organizations';
22+
import {
23+
type Organization,
24+
useOrganizationMembers,
25+
} from '@/hooks/use-organizations';
26+
27+
type InviteRole = 'owner' | 'admin' | 'member';
2328

24-
export function InviteMemberDialog({ isOpen, onClose, organizationId }: any) {
29+
/**
30+
* Renders a modal dialog for inviting a new member to an organization.
31+
*
32+
* Allows users to enter an email address and select a role for the invitee, then sends an invitation to join the specified organization. The dialog can be opened or closed via props.
33+
*
34+
* @param isOpen - Whether the dialog is visible
35+
* @param onClose - Callback to close the dialog
36+
* @param organizationId - Identifier of the organization to invite a member to
37+
*/
38+
export function InviteMemberDialog({
39+
isOpen,
40+
onClose,
41+
organizationId,
42+
}: {
43+
isOpen: boolean;
44+
onClose: () => void;
45+
organizationId: Organization['id'];
46+
}) {
2547
const [inviteEmail, setInviteEmail] = useState('');
26-
const [inviteRole, setInviteRole] = useState<'owner' | 'admin' | 'member'>(
27-
'member'
28-
);
48+
const [inviteRole, setInviteRole] = useState<InviteRole>('member');
2949
const { inviteMember, isInvitingMember } =
3050
useOrganizationMembers(organizationId);
3151

@@ -63,7 +83,7 @@ export function InviteMemberDialog({ isOpen, onClose, organizationId }: any) {
6383
<div className="space-y-2">
6484
<Label htmlFor="role">Role</Label>
6585
<Select
66-
onValueChange={(value) => setInviteRole(value as any)}
86+
onValueChange={(value) => setInviteRole(value as InviteRole)}
6787
value={inviteRole}
6888
>
6989
<SelectTrigger>

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

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ import {
3030
SelectTrigger,
3131
SelectValue,
3232
} from '@/components/ui/select';
33+
import type {
34+
OrganizationMember,
35+
UpdateMemberData,
36+
} from '@/hooks/use-organizations';
3337

3438
dayjs.extend(relativeTime);
3539

@@ -38,12 +42,33 @@ interface MemberToRemove {
3842
name: string;
3943
}
4044

45+
interface MemberListProps {
46+
members: OrganizationMember[];
47+
onRemoveMember: (memberId: string) => void;
48+
isRemovingMember: boolean;
49+
onUpdateRole: (member: UpdateMemberData) => void;
50+
isUpdatingMember: boolean;
51+
organizationId: string;
52+
}
53+
54+
interface RoleSelectorProps {
55+
member: MemberListProps['members'][number];
56+
onUpdateRole: MemberListProps['onUpdateRole'];
57+
isUpdatingMember: MemberListProps['isUpdatingMember'];
58+
organizationId: MemberListProps['organizationId'];
59+
}
60+
61+
/**
62+
* Renders a role selector for an organization member, allowing role changes between "admin" and "member" unless the member is an "owner".
63+
*
64+
* Displays a static "Owner" badge for owner members. For other roles, provides a dropdown to select and update the member's role.
65+
*/
4166
function RoleSelector({
4267
member,
4368
onUpdateRole,
4469
isUpdatingMember,
4570
organizationId,
46-
}: any) {
71+
}: RoleSelectorProps) {
4772
if (member.role === 'owner') {
4873
return (
4974
<Badge
@@ -60,7 +85,11 @@ function RoleSelector({
6085
defaultValue={member.role}
6186
disabled={isUpdatingMember}
6287
onValueChange={(newRole) =>
63-
onUpdateRole({ memberId: member.id, role: newRole, organizationId })
88+
onUpdateRole({
89+
memberId: member.id,
90+
role: newRole as UpdateMemberData['role'],
91+
organizationId,
92+
})
6493
}
6594
>
6695
<SelectTrigger className="w-32 rounded">
@@ -74,14 +103,19 @@ function RoleSelector({
74103
);
75104
}
76105

106+
/**
107+
* Displays a list of organization members with role management and removal functionality.
108+
*
109+
* Renders each member with their avatar, name, email, join date, and current role. Allows updating member roles and removing non-owner members. Shows a confirmation dialog before removing a member. If no members are present, displays a placeholder message.
110+
*/
77111
export function MemberList({
78112
members,
79113
onRemoveMember,
80114
isRemovingMember,
81115
onUpdateRole,
82116
isUpdatingMember,
83117
organizationId,
84-
}: any) {
118+
}: MemberListProps) {
85119
const [memberToRemove, setMemberToRemove] = useState<MemberToRemove | null>(
86120
null
87121
);
@@ -106,7 +140,7 @@ export function MemberList({
106140

107141
{members && members.length > 0 ? (
108142
<div className="space-y-3">
109-
{members.map((member: any) => (
143+
{members.map((member) => (
110144
<div
111145
className="flex items-center justify-between rounded border border-border/50 bg-muted/30 p-4"
112146
key={member.id}

apps/dashboard/app/(main)/organizations/[slug]/components/organization-logo-uploader.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,29 @@ import {
1919
} from '@/components/ui/dialog';
2020
import { Input } from '@/components/ui/input';
2121
import { Label } from '@/components/ui/label';
22-
import { useOrganizations } from '@/hooks/use-organizations';
22+
import { type Organization, useOrganizations } from '@/hooks/use-organizations';
2323
import { getOrganizationInitials } from '@/lib/utils';
2424
import 'react-image-crop/dist/ReactCrop.css';
2525
import { UploadSimpleIcon } from '@phosphor-icons/react';
2626
import { getCroppedImage } from '@/lib/canvas-utils';
2727

2828
interface OrganizationLogoUploaderProps {
29-
organization: {
30-
id: string;
31-
name: string;
32-
logo: string | null;
33-
};
29+
organization: Organization;
3430
}
3531

32+
/**
33+
* React component for uploading, cropping, and updating an organization's logo.
34+
*
35+
* Allows users to select an image file, crop it to a circular aspect ratio, and upload the cropped image as the organization's new logo. Displays the current logo or organization initials as a fallback, and provides UI feedback for upload progress and errors.
36+
*
37+
* @param organization - The organization whose logo is being managed.
38+
*/
3639
export function OrganizationLogoUploader({
3740
organization,
3841
}: OrganizationLogoUploaderProps) {
3942
const { uploadOrganizationLogo, isUploadingOrganizationLogo } =
4043
useOrganizations();
41-
const [preview, setPreview] = useState<string | null>(organization.logo);
44+
const [preview, setPreview] = useState(organization.logo);
4245
const [imageSrc, setImageSrc] = useState<string | null>(null);
4346
const [crop, setCrop] = useState<Crop>();
4447
const [completedCrop, setCompletedCrop] = useState<PixelCrop>();

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,24 @@ import {
2222
CardTitle,
2323
} from '@/components/ui/card';
2424
import { Skeleton } from '@/components/ui/skeleton';
25-
import { useOrganizationMembers } from '@/hooks/use-organizations';
25+
import {
26+
type Organization,
27+
useOrganizationMembers,
28+
} from '@/hooks/use-organizations';
2629

2730
dayjs.extend(relativeTime);
2831

2932
interface OverviewTabProps {
30-
organization: any;
33+
organization: Organization;
3134
}
3235

36+
/**
37+
* Displays an overview of an organization's details, team statistics, and recent members.
38+
*
39+
* Renders organization metadata, quick statistics on member roles, and a list of the most recent team members with loading states and navigation controls.
40+
*
41+
* @param organization - The organization whose overview information is displayed.
42+
*/
3343
export function OverviewTab({ organization }: OverviewTabProps) {
3444
const { members, isLoading: isLoadingMembers } = useOrganizationMembers(
3545
organization.id

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,22 @@ import {
3232
import { Input } from '@/components/ui/input';
3333
import { Label } from '@/components/ui/label';
3434
import { Skeleton } from '@/components/ui/skeleton';
35-
import { useOrganizations } from '@/hooks/use-organizations';
35+
import { type Organization, useOrganizations } from '@/hooks/use-organizations';
3636
import { trpc } from '@/lib/trpc';
3737
import { OrganizationLogoUploader } from './organization-logo-uploader';
3838
import { TransferAssets } from './transfer-assets';
3939

4040
interface SettingsTabProps {
41-
organization: any;
41+
organization: Organization;
4242
}
4343

44+
/**
45+
* Displays and manages organization settings, including editing basic information, viewing associated websites, transferring assets, and deleting the organization.
46+
*
47+
* Renders UI for updating the organization's name and slug, uploading a logo, listing associated websites, transferring assets, and performing irreversible deletion with confirmation.
48+
*
49+
* @param organization - The organization whose settings are being managed
50+
*/
4451
export function SettingsTab({ organization }: SettingsTabProps) {
4552
const router = useRouter();
4653
const [name, setName] = useState(organization.name);

apps/dashboard/app/(main)/organizations/[slug]/components/team-view.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ import {
55
EnvelopeIcon,
66
PlusIcon,
77
UsersIcon,
8+
type Icon as IconType,
89
} from '@phosphor-icons/react';
910
import { useState } from 'react';
1011
import { Button } from '@/components/ui/button';
1112
import { Skeleton } from '@/components/ui/skeleton';
1213
import {
1314
useOrganizationInvitations,
1415
useOrganizationMembers,
16+
type ActiveOrganization,
17+
type Organization,
1518
} from '@/hooks/use-organizations';
1619
import { InvitationList } from './invitation-list';
1720
import { InviteMemberDialog } from './invite-member-dialog';
@@ -23,7 +26,7 @@ const StatCard = ({
2326
label,
2427
value,
2528
}: {
26-
icon: any;
29+
icon: IconType;
2730
label: string;
2831
value: number;
2932
}) => (
@@ -55,7 +58,18 @@ const ViewSkeleton = () => (
5558
</div>
5659
);
5760

58-
export function TeamView({ organization }: { organization: any }) {
61+
/**
62+
* Displays and manages the team members and invitations for a given organization.
63+
*
64+
* Renders team statistics, member and invitation lists, and provides controls for inviting new members and managing existing ones. Handles loading and error states for team data.
65+
*
66+
* @param organization - The organization whose team is being managed and displayed.
67+
*/
68+
export function TeamView({
69+
organization,
70+
}: {
71+
organization: NonNullable<Organization | ActiveOrganization>;
72+
}) {
5973
const [showInviteDialog, setShowInviteDialog] = useState(false);
6074

6175
const {

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,20 @@ import {
99
CardTitle,
1010
} from '@/components/ui/card';
1111
import { TeamView } from './team-view';
12+
import type { ActiveOrganization, Organization } from '@/hooks/use-organizations';
1213

13-
export function TeamsTab({ organization }: { organization: any }) {
14+
/**
15+
* Displays the team management interface or a prompt to select an organization.
16+
*
17+
* Renders team management features if a valid organization is provided; otherwise, shows guidance to select an organization before managing teams.
18+
*
19+
* @param organization - The current organization context, or undefined if none is selected
20+
*/
21+
export function TeamsTab({
22+
organization,
23+
}: {
24+
organization: Organization | ActiveOrganization;
25+
}) {
1426
if (!(organization && organization.id)) {
1527
return (
1628
<div className="py-12 text-center">

0 commit comments

Comments
 (0)