Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions src/app/manage/[slug]/(dashboard)/(forms)/MemberSettings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
'use client';

import {
Button,
FormControl,
InputLabel,
MenuItem,
Select,
} from '@mui/material';
import { useMutation } from '@tanstack/react-query';
import { useState } from 'react';
import Panel from '@src/components/common/Panel';
import { setSnackbar, SnackbarPresets } from '@src/components/global/Snackbar';
import type { SelectClub } from '@src/server/db/models';
import { useTRPC } from '@src/trpc/react';

type MemberSettingsProps = {
club: SelectClub;
};

const policyLabels: Record<string, string> = {
open: 'Anyone can join',
request: 'Request to join',
closed: 'No new members',
};

export default function MemberSettings({ club }: MemberSettingsProps) {
const api = useTRPC();
const [policy, setPolicy] = useState(club.membershipPolicy);

const updatePolicy = useMutation(
api.club.updateMembershipPolicy.mutationOptions({
onSuccess: () => {
setSnackbar({
message: 'Membership policy updated!',
type: 'success',
autoHideDuration: true,
fitContent: true,
closeOn: ['timeout', 'escapeKeyDown', 'dismiss'],
});
},
onError: (error) => {
setSnackbar(
SnackbarPresets.errorCustomMessage(
'Failed to update membership policy',
error.message,
),
);
},
}),
);

const hasChanges = policy !== club.membershipPolicy;

return (
<Panel heading="Member Settings">
<div className="flex flex-col gap-4 ml-2">
<FormControl className="max-w-xs">
<InputLabel id="membership-policy-label">
Membership Policy
</InputLabel>
<Select
labelId="membership-policy-label"
value={policy}
label="Membership Policy"
onChange={(e) =>
setPolicy(e.target.value as 'open' | 'request' | 'closed')
}
>
{Object.entries(policyLabels).map(([value, label]) => (
<MenuItem key={value} value={value}>
{label}
</MenuItem>
))}
</Select>
</FormControl>
<div>
<Button
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want a discard button here like on other forms?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a discard button

variant="contained"
className="normal-case"
disabled={!hasChanges || updatePolicy.isPending}
loading={updatePolicy.isPending}
onClick={() => updatePolicy.mutate({ clubId: club.id, policy })}
>
Save
</Button>
</div>
</div>
</Panel>
);
}
2 changes: 2 additions & 0 deletions src/app/manage/[slug]/(dashboard)/ClubManageForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Collaborators from './(forms)/Collaborators';
import Contacts from './(forms)/Contacts';
import DeleteClub from './(forms)/DeleteClub';
import Details from './(forms)/Details';
import MemberSettings from './(forms)/MemberSettings';
import MembershipForms from './(forms)/MembershipForms';
import Officers from './(forms)/Officers';
import Slug from './(forms)/Slug';
Expand Down Expand Up @@ -57,6 +58,7 @@ const ClubManageForm = async ({
club={club}
listedMembershipForms={listedMembershipForms}
/>
<MemberSettings club={club} />
<Collaborators
club={club}
officers={officers}
Expand Down
2 changes: 1 addition & 1 deletion src/app/manage/[slug]/(dashboard)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const Page = async (props: { params: Promise<{ slug: string }> }) => {
startIcon={<PeopleIcon />}
size="large"
>
Followers
Members & Followers
</LinkButton>
<LinkButton
href={`/manage/${slug}/events`}
Expand Down
4 changes: 3 additions & 1 deletion src/app/manage/[slug]/followers/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export default async function Page({
<main>
<ManageHeader
club={club}
path={[{ text: 'Followers', href: `/manage/${slug}/followers` }]}
path={[
{ text: 'Members & Followers', href: `/manage/${slug}/followers` },
]}
hrefBack={`/manage/${slug}/`}
/>
<div className="flex w-full flex-col items-center">
Expand Down
Loading
Loading