Skip to content

Commit 4163a6a

Browse files
committed
wip: update membership system
1 parent 65ab205 commit 4163a6a

File tree

19 files changed

+589
-270
lines changed

19 files changed

+589
-270
lines changed

apps/dashboard/src/app/(internal)/arrangementer/components/qr-code-scanned-modal.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import {
55
type User,
66
findActiveMembership,
77
getAttendeeQueuePosition,
8-
getMembershipGrade,
98
getUnreservedAttendeeCount,
9+
getMembershipTypeName,
1010
} from "@dotkomonline/types"
11-
import { getCurrentUTC } from "@dotkomonline/utils"
11+
import { getCurrentUTC, getStudyGrade } from "@dotkomonline/utils"
1212
import { Button, Flex, Group, Image, Stack, Text, Title, useComputedColorScheme } from "@mantine/core"
1313
import { useMediaQuery } from "@mantine/hooks"
1414
import { type ContextModalProps, modals } from "@mantine/modals"
@@ -167,7 +167,8 @@ const UserBox = ({ user, isMobile }: UserBoxProps) => {
167167
const isLightMode = useComputedColorScheme() === "light"
168168

169169
const membership = findActiveMembership(user)
170-
const grade = membership ? getMembershipGrade(membership) : null
170+
const grade = getStudyGrade(membership?.semester)
171+
const membershipType = membership && getMembershipTypeName(membership.type)
171172

172173
return (
173174
<Stack>
@@ -183,7 +184,8 @@ const UserBox = ({ user, isMobile }: UserBoxProps) => {
183184
<Image src={user.imageUrl} alt={user.name ?? user.profileSlug} radius="md" w={100} h={100} />
184185
<Stack gap={2}>
185186
<Title order={4}>{user.name}</Title>
186-
<Text size="sm">Klasse: {grade}</Text>
187+
<Text size="sm">{membership ? `Medlemskap: ${membershipType}` : "Ingen aktivt medlemskap"}</Text>
188+
<Text size="sm">{membership ? (grade ? `Klasse: ${grade}` : "Ingen klassetrinn") : "-"}</Text>
187189
<Text size="sm">Kjønn: {user.gender || "Ikke oppgitt"}</Text>
188190
<Text size="sm">Kostholdsrestriksjoner: {user.dietaryRestrictions || "Ingen"}</Text>
189191
</Stack>

apps/dashboard/src/app/(internal)/brukere/[id]/edit-card.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
import { env } from "@/lib/env"
22
import { useSession } from "@dotkomonline/oauth2/react"
3-
import {
4-
UserWriteSchema,
5-
type WorkspaceUser,
6-
findActiveMembership,
7-
getMembershipGrade,
8-
getMembershipTypeName,
9-
} from "@dotkomonline/types"
3+
import { UserWriteSchema, type WorkspaceUser, findActiveMembership, getMembershipTypeName } from "@dotkomonline/types"
104
import { Button, Group, Loader, Stack, Text, TextInput, Title } from "@mantine/core"
115
import { useDebouncedValue } from "@mantine/hooks"
126
import { IconCheck, IconLink, IconUsersGroup, IconX, IconArrowUpRight } from "@tabler/icons-react"
@@ -15,6 +9,7 @@ import { useLinkOwUserToWorkspaceUserMutation, useUpdateUserMutation } from "../
159
import { useFindWorkspaceUserQuery, useGroupAllByMemberQuery, useIsAdminQuery } from "../queries"
1610
import { useUserProfileEditForm } from "./edit-form"
1711
import { useUserDetailsContext } from "./provider"
12+
import { getStudyGrade } from "@dotkomonline/utils"
1813

1914
export const UserEditCard: FC = () => {
2015
const session = useSession()
@@ -57,7 +52,7 @@ export const UserEditCard: FC = () => {
5752
})
5853

5954
const activeMembership = findActiveMembership(user)
60-
const grade = activeMembership ? getMembershipGrade(activeMembership) : null
55+
const grade = getStudyGrade(activeMembership?.semester)
6156
const membershipType = activeMembership ? getMembershipTypeName(activeMembership.type) : null
6257

6358
return (

apps/dashboard/src/app/(internal)/brukere/components/membership-form.tsx

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ import {
99
getMembershipTypeName,
1010
getSpecializationName,
1111
} from "@dotkomonline/types"
12-
import { getCurrentUTC } from "@dotkomonline/utils"
13-
import { addYears, isBefore } from "date-fns"
12+
import { getNextSemesterStart, getCurrentSemesterStart } from "@dotkomonline/utils"
13+
import { isBefore } from "date-fns"
1414
import type { z } from "zod"
15+
import { createNumberInput } from "@/components/forms/NumberInput"
16+
import { Code, Stack, Text } from "@mantine/core"
1517

1618
export const MembershipWriteFormSchema = MembershipWriteSchema.superRefine((data, ctx) => {
17-
if (isBefore(data.end, data.start)) {
19+
if (data.end && isBefore(data.end, data.start)) {
1820
ctx.addIssue({
1921
code: "custom",
2022
message: "Sluttdato må være etter startdato",
@@ -26,13 +28,14 @@ export const MembershipWriteFormSchema = MembershipWriteSchema.superRefine((data
2628
type MembershipWriteFormSchema = z.infer<typeof MembershipWriteFormSchema>
2729

2830
const DEFAULT_VALUES: Partial<MembershipWriteFormSchema> = {
29-
start: getCurrentUTC(),
30-
end: addYears(getCurrentUTC(), 1),
31+
start: getCurrentSemesterStart(),
32+
end: getNextSemesterStart(),
3133
specialization: null,
34+
semester: 0,
3235
}
3336

3437
interface UseMembershipWriteFormProps {
35-
onSubmit(data: z.infer<typeof MembershipWriteFormSchema>): void
38+
onSubmit(data: MembershipWriteFormSchema): void
3639
defaultValues?: Partial<MembershipWrite>
3740
label?: string
3841
}
@@ -59,6 +62,7 @@ export const useMembershipWriteForm = ({
5962
}),
6063
specialization: createSelectInput({
6164
label: "Spesialisering",
65+
description: "Masterspesialisering",
6266
required: false,
6367
clearable: true,
6468
placeholder: "Velg spesialisering",
@@ -68,6 +72,7 @@ export const useMembershipWriteForm = ({
6872
value: specialization,
6973
label: getSpecializationName(specialization) ?? specialization,
7074
})),
75+
disabled: false,
7176
}),
7277
start: createDateTimeInput({
7378
label: "Startdato",
@@ -77,6 +82,40 @@ export const useMembershipWriteForm = ({
7782
label: "Sluttdato",
7883
required: true,
7984
}),
85+
semester: createNumberInput({
86+
label: "Semester",
87+
description: (
88+
<Stack gap="xs">
89+
<Text size="xs" c="dimmed">
90+
Hvilket semester medlemskapet innebærer. 0-indeksert.
91+
</Text>
92+
<Stack gap="0.25rem">
93+
<Text size="xs" c="dimmed">
94+
<Code>0</Code> → 1. semester (1. årstrinn)
95+
</Text>
96+
<Text size="xs" c="dimmed">
97+
<Code>1</Code> → 2. semester (1. årstrinn)
98+
</Text>
99+
<Text size="xs" c="dimmed">
100+
<Code>2</Code> → 3. semester (2. årstrinn)
101+
</Text>
102+
<Text size="xs" c="dimmed">
103+
...
104+
</Text>
105+
<Text size="xs" c="dimmed">
106+
<Code>8</Code> → 9. semester (5. årstrinn)
107+
</Text>
108+
<Text size="xs" c="dimmed">
109+
<Code>9</Code> → 10. semester (5. årstrinn)
110+
</Text>
111+
</Stack>
112+
</Stack>
113+
),
114+
required: false,
115+
min: 0,
116+
max: 9,
117+
allowDecimal: false,
118+
}),
80119
},
81120
})
82121
}

apps/rpc/src/modules/event/attendance-service.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,17 @@ import {
2323
type User,
2424
type UserId,
2525
findActiveMembership,
26-
getMembershipGrade,
2726
hasAttendeePaid,
2827
isAttendable,
2928
} from "@dotkomonline/types"
30-
import { createAbsoluteEventPageUrl, createPoolName, getCurrentUTC, ogJoin, slugify } from "@dotkomonline/utils"
29+
import {
30+
createAbsoluteEventPageUrl,
31+
createPoolName,
32+
getCurrentUTC,
33+
ogJoin,
34+
slugify,
35+
getStudyGrade,
36+
} from "@dotkomonline/utils"
3137
import {
3238
addDays,
3339
addHours,
@@ -600,6 +606,8 @@ export function getAttendanceService(
600606
(!isFuture(reservationActiveAt) && (pool.capacity === 0 || poolAttendees.length < pool.capacity)) ||
601607
options.immediateReservation
602608

609+
const userGrade = membership.semester != null ? getStudyGrade(membership.semester) : null
610+
603611
const attendee = await attendanceRepository.createAttendee(
604612
handle,
605613
attendance.id,
@@ -610,7 +618,7 @@ export function getAttendanceService(
610618
earliestReservationAt: reservationActiveAt,
611619
reserved: isImmediateReservation,
612620
selections: [],
613-
userGrade: getMembershipGrade(membership),
621+
userGrade,
614622
} satisfies AttendeeWrite)
615623
)
616624

apps/rpc/src/modules/event/attendance.e2e-spec.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
type MembershipWrite,
66
findActiveMembership,
77
} from "@dotkomonline/types"
8-
import { getCurrentUTC } from "@dotkomonline/utils"
8+
import { getCurrentUTC, getCurrentSemesterStart, getNextSemesterStart, isSpringSemester } from "@dotkomonline/utils"
99
import { faker } from "@faker-js/faker"
1010
import type { ApiResponse, GetUsers200ResponseOneOfInner } from "auth0"
1111
import { addDays, addHours, addMinutes, isFuture, subHours } from "date-fns"
@@ -41,9 +41,10 @@ export function getMockAttendancePool(input: Partial<AttendancePoolWrite> = {}):
4141
export function getMockMembership(input: Partial<MembershipWrite> = {}): MembershipWrite {
4242
return {
4343
type: "BACHELOR_STUDENT",
44-
start: addDays(getCurrentUTC(), -100),
45-
end: addDays(getCurrentUTC(), 100),
44+
start: getCurrentSemesterStart(),
45+
end: getNextSemesterStart(),
4646
specialization: null,
47+
semester: isSpringSemester() ? 1 : 2,
4748
...input,
4849
}
4950
}

0 commit comments

Comments
 (0)