diff --git a/algorithm/bridge/fetch_applicants_and_committees.py b/algorithm/bridge/fetch_applicants_and_committees.py index e50a4662..98b2ce76 100644 --- a/algorithm/bridge/fetch_applicants_and_committees.py +++ b/algorithm/bridge/fetch_applicants_and_committees.py @@ -18,7 +18,6 @@ def main(): application_end = datetime.fromisoformat(period["applicationPeriod"]["end"].replace("Z", "+00:00")) now = datetime.now(timezone.utc) - #or period["name"] == "Juli Opptak" if (application_end < now and period["hasSentInterviewTimes"] == False): @@ -115,11 +114,13 @@ def format_match_results(match_results: MeetingMatch, applicants: List[dict], pe time_interval = result[2] start = time_interval.start.isoformat() end = time_interval.end.isoformat() + room = result[3] transformed_results[applicant_id]["interviews"].append({ "start": start, "end": end, - "committeeName": committee.name + "committeeName": committee.name, + "room": room }) return list(transformed_results.values()) @@ -156,8 +157,8 @@ def create_committee_objects(committee_data: List[dict]) -> set[Committee]: start=datetime.fromisoformat(interval_data['start'].replace("Z", "+00:00")), end=datetime.fromisoformat(interval_data['end'].replace("Z", "+00:00")) ) - capacity = interval_data.get('capacity', 1) - committee.add_interval(interval, capacity) + room = interval_data["room"] + committee.add_interview_slot(interval, room) committees.add(committee) return committees diff --git a/algorithm/src/mip_matching/Committee.py b/algorithm/src/mip_matching/Committee.py index 8f2c28f5..29095116 100644 --- a/algorithm/src/mip_matching/Committee.py +++ b/algorithm/src/mip_matching/Committee.py @@ -6,6 +6,8 @@ from typing import Iterator +from mip_matching.types import Room + class Committee: """ @@ -21,39 +23,40 @@ class Committee: """ def __init__(self, name: str, interview_length: timedelta = timedelta(minutes=15)): - self.capacities: dict[TimeInterval, int] = dict() + self.interview_slots: dict[TimeInterval, set[Room]] = dict() self.interview_length: timedelta = interview_length self.applicants: set[Applicant] = set() self.name = name - def add_interval(self, interval: TimeInterval, capacity: int = 1) -> None: - """Legger til et nytt intervall med gitt kapasitet hvis intervallet - ikke allerede har en kapasitet for denne komitéen. + def add_interview_slot(self, interval: TimeInterval, room: Room) -> None: + """Legger til et nytt intervall med gitt rom. Når intervaller legges til deles det automatisk opp i intervaller med lik lengde som intervjulengder.""" minimal_intervals = TimeInterval.divide_interval( interval=interval, length=self.interview_length) for interval in minimal_intervals: - if interval not in self.capacities: - self.capacities[interval] = capacity - else: - self.capacities[interval] += capacity - - def add_intervals_with_capacities(self, intervals_with_capacities: dict[TimeInterval, int]): - """Legger til flere tidsintervaller samtidig.""" - for interval, capacity in intervals_with_capacities.items(): - self.add_interval(interval, capacity) + if interval not in self.interview_slots: + self.interview_slots[interval] = set() + self.interview_slots[interval].add(room) def get_intervals_and_capacities(self) -> Iterator[tuple[TimeInterval, int]]: """Generator som returnerer interval-kapasitet-par.""" - for interval, capacity in self.capacities.items(): - yield interval, capacity + for interval, rooms in self.interview_slots.items(): + yield interval, len(rooms) + + def get_capacity(self, interval: TimeInterval) -> int: + """Returnerer komitéens kapasitet ved et gitt interval (ferdiginndelt etter lengde)""" + return len(self.interview_slots[interval]) def get_intervals(self) -> Iterator[TimeInterval]: """Generator som returnerer kun intervallene""" - for interval in self.capacities.keys(): + for interval in self.interview_slots.keys(): yield interval + def get_rooms(self, interval: TimeInterval) -> Iterator[Room]: + for room in self.interview_slots[interval]: + yield room + def _add_applicant(self, applicant: Applicant): """Metode brukt for å holde toveis-assosiasjonen.""" self.applicants.add(applicant) @@ -62,10 +65,6 @@ def get_applicants(self) -> Iterator[Applicant]: for applicant in self.applicants: yield applicant - def get_capacity(self, interval: TimeInterval) -> int: - """Returnerer komitéens kapasitet ved et gitt interval (ferdiginndelt etter lengde)""" - return self.capacities[interval] - def get_applicant_count(self) -> int: return len(self.applicants) @@ -77,4 +76,4 @@ def __repr__(self): if __name__ == "__main__": - print("running") \ No newline at end of file + print("running") diff --git a/algorithm/src/mip_matching/TimeInterval.py b/algorithm/src/mip_matching/TimeInterval.py index 9228aa28..83064dad 100644 --- a/algorithm/src/mip_matching/TimeInterval.py +++ b/algorithm/src/mip_matching/TimeInterval.py @@ -65,7 +65,7 @@ def divide(self, length: timedelta) -> list[TimeInterval]: return TimeInterval.divide_interval(self, length) def is_within_distance(self, other: TimeInterval, distance: timedelta) -> bool: - return (self.end <= other.start and self.end + distance > other.start) or (other.end <= self.start and other.end + distance > self.start) + return (self.end <= other.start < self.end + distance) or (other.end <= self.start < other.end + distance) @staticmethod def divide_interval(interval: TimeInterval, length: timedelta) -> list[TimeInterval]: diff --git a/algorithm/src/mip_matching/match_meetings.py b/algorithm/src/mip_matching/match_meetings.py index e425e079..4f51cf21 100644 --- a/algorithm/src/mip_matching/match_meetings.py +++ b/algorithm/src/mip_matching/match_meetings.py @@ -8,6 +8,7 @@ from datetime import timedelta, time from itertools import combinations +from mip_matching.types import Matching, MeetingMatch from mip_matching.utils import subtract_time @@ -22,60 +23,53 @@ MAX_SCALE_CLUSTERING_TIME = timedelta(seconds=43200) # TODO: Rename variable -class MeetingMatch(TypedDict): - """Type definition of a meeting match object""" - solver_status: mip.OptimizationStatus - matched_meetings: int - total_wanted_meetings: int - matchings: list[tuple[Applicant, Committee, TimeInterval]] - - def match_meetings(applicants: set[Applicant], committees: set[Committee]) -> MeetingMatch: """Matches meetings and returns a MeetingMatch-object""" model = mip.Model(sense=mip.MAXIMIZE) - m: dict[tuple[Applicant, Committee, TimeInterval], mip.Var] = {} + m: dict[Matching, mip.Var] = {} # Lager alle maksimeringsvariabler for applicant in applicants: for committee in applicant.get_committees(): for interval in applicant.get_fitting_committee_slots(committee): - m[(applicant, committee, interval)] = model.add_var( - var_type=mip.BINARY, name=f"({applicant}, {committee}, {interval})") + for room in committee.get_rooms(interval): + m[(applicant, committee, interval, room)] = model.add_var( + var_type=mip.BINARY, name=f"({applicant}, {committee}, {interval}, {room})") # Legger inn begrensninger for at en komité kun kan ha antall møter i et slot lik kapasiteten. for committee in committees: for interval, capacity in committee.get_intervals_and_capacities(): - model += mip.xsum(m[(applicant, committee, interval)] + model += mip.xsum(m[(applicant, committee, interval, room)] for applicant in committee.get_applicants() + for room in committee.get_rooms(interval) + if (applicant, committee, interval, room) in m # type: ignore - if (applicant, committee, interval) in m) <= capacity + ) <= capacity # Legger inn begrensninger for at en person kun har ett intervju med hver komité for applicant in applicants: for committee in applicant.get_committees(): - model += mip.xsum(m[(applicant, committee, interval)] + model += mip.xsum(m[(applicant, committee, interval, room)] + for interval in applicant.get_fitting_committee_slots(committee) + for room in committee.get_rooms(interval) # type: ignore - for interval in applicant.get_fitting_committee_slots(committee)) <= 1 + ) <= 1 # Legger inn begrensninger for at en søker ikke kan ha overlappende intervjutider # og minst har et buffer mellom hvert intervju som angitt for applicant in applicants: - potential_interviews: set[tuple[Committee, TimeInterval]] = set() - for applicant_candidate, committee, interval in m: - if applicant == applicant_candidate: - potential_interviews.add((committee, interval)) + potential_interviews = set(slot for slot in m.keys() if slot[0] == applicant) for interview_a, interview_b in combinations(potential_interviews, r=2): - if interview_a[1].intersects(interview_b[1]) or interview_a[1].is_within_distance(interview_b[1], APPLICANT_BUFFER_LENGTH): - model += m[(applicant, *interview_a)] + \ - m[(applicant, *interview_b)] <= 1 # type: ignore + if interview_a[2].intersects(interview_b[2]) or interview_a[2].is_within_distance(interview_b[2], APPLICANT_BUFFER_LENGTH): + model += m[interview_a] + m[interview_b] <= 1 # type: ignore # Legger til sekundærmål om at man ønsker å sentrere intervjuer rundt CLUSTERING_TIME_BASELINE clustering_objectives = [] for name, variable in m.items(): - applicant, committee, interval = name + applicant, committee, interval, room = name if interval.start.time() < CLUSTERING_TIME_BASELINE: relative_distance_from_baseline = subtract_time(CLUSTERING_TIME_BASELINE, interval.end.time()) / MAX_SCALE_CLUSTERING_TIME @@ -101,7 +95,6 @@ def match_meetings(applicants: set[Applicant], committees: set[Committee]) -> Me if variable.x: antall_matchede_møter += 1 matchings.append(name) - print(f"{name}") antall_ønskede_møter = sum( len(applicant.get_committees()) for applicant in applicants) diff --git a/algorithm/src/mip_matching/types.py b/algorithm/src/mip_matching/types.py new file mode 100644 index 00000000..a7318a28 --- /dev/null +++ b/algorithm/src/mip_matching/types.py @@ -0,0 +1,22 @@ +""" +Typealiaser +""" + +from typing import TypedDict, TYPE_CHECKING +import mip +if TYPE_CHECKING: + # Unngår cyclic import + from mip_matching.Applicant import Applicant + from mip_matching.Committee import Committee + from mip_matching.TimeInterval import TimeInterval + + +type Room = str +type Matching = tuple[Applicant, Committee, TimeInterval, Room] + +class MeetingMatch(TypedDict): + """Type definition of a meeting match object""" + solver_status: mip.OptimizationStatus + matched_meetings: int + total_wanted_meetings: int + matchings: list[Matching] \ No newline at end of file diff --git a/algorithm/tests/CommitteeTest.py b/algorithm/tests/CommitteeTest.py index 4d63ac24..8ffebd52 100644 --- a/algorithm/tests/CommitteeTest.py +++ b/algorithm/tests/CommitteeTest.py @@ -1,21 +1,14 @@ -from __future__ import annotations -from datetime import datetime, timedelta -import unittest -from mip_matching.TimeInterval import TimeInterval -from mip_matching.Committee import Committee +# from __future__ import annotations +# from datetime import datetime, timedelta +# import unittest +# from mip_matching.TimeInterval import TimeInterval +# from mip_matching.Committee import Committee -class ApplicantTest(unittest.TestCase): - def setUp(self) -> None: - self.committee = Committee( - "TestKom", interview_length=timedelta(minutes=30)) - self.committee.add_intervals_with_capacities({ - TimeInterval(datetime(2024, 8, 24, 8, 0), datetime(2024, 8, 24, 9, 30)): 1, - TimeInterval(datetime(2024, 8, 24, 8, 30), datetime(2024, 8, 24, 9, 30)): 1 - }) +# class ApplicantTest(unittest.TestCase): +# def setUp(self) -> None: +# self.committee = Committee( +# "TestKom", interview_length=timedelta(minutes=30)) + - def test_capacity_stacking(self) -> None: - self.assertEqual(1, self.committee.get_capacity( - TimeInterval(datetime(2024, 8, 24, 8, 0), datetime(2024, 8, 24, 8, 30)))) - self.assertEqual(2, self.committee.get_capacity( - TimeInterval(datetime(2024, 8, 24, 8, 30), datetime(2024, 8, 24, 9, 0)))) + \ No newline at end of file diff --git a/algorithm/tests/mip_test.py b/algorithm/tests/mip_test.py index ec173ea2..5c66870f 100644 --- a/algorithm/tests/mip_test.py +++ b/algorithm/tests/mip_test.py @@ -13,10 +13,12 @@ import random from itertools import combinations +from mip_matching.types import Matching + def print_matchings(committees: list[Committee], intervals: list[TimeInterval], - matchings: list[tuple[Applicant, Committee, TimeInterval]]): + matchings: list[Matching]): print("Tid".ljust(15), end="|") print("|".join(str(com).ljust(8) for com in committees)) @@ -26,7 +28,7 @@ def print_matchings(committees: list[Committee], for committee in committees: name = "" cands = [a.name for a, c, - i in matchings if interval == i and c == committee] + i, r in matchings if interval == i and c == committee] name = cands[0] if len(cands) > 0 else "" print(name.rjust(8), end="|") @@ -36,17 +38,17 @@ def print_matchings(committees: list[Committee], class MipTest(unittest.TestCase): - def check_constraints(self, matchings: list[tuple[Applicant, Committee, TimeInterval]]): + def check_constraints(self, matchings: list[Matching]): """Checks if the constraints are satisfied in the provided matchings. TODO: Add more constraint tests.""" self.assertEqual(len(matchings), len(set((applicant, interval) - for applicant, _, interval in matchings)), + for applicant, _, interval, _ in matchings)), "Constraint \"Applicant can only have one meeting during each TimeInterval\" failed.") load_per_committee_per_slot: dict[Committee, dict[TimeInterval, int]] = { } - for _, committee, interval in matchings: + for _, committee, interval, _ in matchings: if committee not in load_per_committee_per_slot: load_per_committee_per_slot[committee] = {} @@ -61,32 +63,34 @@ def check_constraints(self, matchings: list[tuple[Applicant, Committee, TimeInte # Overlapping interviews per applicant interviews_per_applicant: dict[Applicant, - set[tuple[Committee, TimeInterval]]] = {} - for applicant, committee, interval in matchings: + set[Matching]] = {} + for interview in matchings: + applicant = interview[0] if applicant not in interviews_per_applicant: interviews_per_applicant[applicant] = set() - interviews_per_applicant[applicant].add((committee, interval)) + interviews_per_applicant[applicant].add(interview) for applicant, interviews in interviews_per_applicant.items(): for interview_a, interview_b in combinations(interviews, r=2): - self.assertFalse(interview_a[1].intersects(interview_b[1]), f"Constraint \"Applicant cannot have time-overlapping interviews\" failed for { - applicant}'s interviews with {interview_a[0]} ({interview_a[1]}) and {interview_b[0]} ({interview_b[1]})") + self.assertFalse(interview_a[2].intersects(interview_b[2]), f"Constraint \"Applicant cannot have time-overlapping interviews\" failed for { + applicant}'s interviews with {interview_a[1]} ({interview_a[1]}) and {interview_b[1]} ({interview_b[2]})") def test_fixed_small(self): """Small, fixed test with all capacities set to one""" appkom = Committee(name="Appkom") - appkom.add_intervals_with_capacities( - {TimeInterval(datetime(2024, 8, 24, 8, 0), datetime(2024, 8, 24, 9, 15)): 1}) + + appkom.add_interview_slot( + TimeInterval(datetime(2024, 8, 24, 8, 0), datetime(2024, 8, 24, 9, 15)), "AppkomRom") oil = Committee(name="OIL") - oil.add_intervals_with_capacities( - {TimeInterval(datetime(2024, 8, 24, 9, 0), datetime(2024, 8, 24, 9, 30)): 1}) + oil.add_interview_slot( + TimeInterval(datetime(2024, 8, 24, 9, 0), datetime(2024, 8, 24, 9, 30)), "OilRom") prokom = Committee(name="Prokom") - prokom.add_intervals_with_capacities({TimeInterval(datetime(2024, 8, 24, 8, 0), datetime(2024, 8, 24, 8, 45)): 1, - TimeInterval(datetime(2024, 8, 24, 9, 0), datetime(2024, 8, 24, 9, 30)): 1}) + prokom.add_interview_slot(TimeInterval(datetime(2024, 8, 24, 8, 0), datetime(2024, 8, 24, 8, 45)), "ProkomRom") + prokom.add_interview_slot(TimeInterval(datetime(2024, 8, 24, 9, 0), datetime(2024, 8, 24, 9, 30)), "ProkomRom") committees: set[Committee] = {appkom, oil, prokom} @@ -216,8 +220,9 @@ def get_random_interval(interval_date: date, interval_length_min: timedelta, int for _ in range(ANTALL_INTERVALL_FORSØK_KOMITE): interval_date = fake.date_between_dates(START_DATE, END_DATE) - committee.add_intervals_with_capacities({get_random_interval(interval_date, INTERVALLENGDE_PER_KOMTIE_MIN, INTERVALLENGDE_PER_KOMTIE_MAKS): random.randint( - KAPASITET_PER_INTERVALL_MIN, KAPASITET_PER_INTERVALL_MAKS)}) + for _ in range(random.randint(KAPASITET_PER_INTERVALL_MIN, KAPASITET_PER_INTERVALL_MAKS)): + committee.add_interview_slot(get_random_interval(interval_date, INTERVALLENGDE_PER_KOMTIE_MIN, INTERVALLENGDE_PER_KOMTIE_MAKS), + room=str(random.getrandbits(128))) # Lar hver søker søke på tilfeldige komiteer committees_list = list(committees) @@ -296,8 +301,9 @@ def get_random_interval(interval_date: date) -> TimeInterval: for _ in range(ANTALL_INTERVALL_FORSØK_KOMITE): interval_date = fake.date_between_dates(START_DATE, END_DATE) - committee.add_intervals_with_capacities({get_random_interval(interval_date): random.randint( - KAPASITET_PER_INTERVALL_MIN, KAPASITET_PER_INTERVALL_MAKS)}) + for _ in range(random.randint(KAPASITET_PER_INTERVALL_MIN, KAPASITET_PER_INTERVALL_MAKS)): + committee.add_interview_slot(get_random_interval(interval_date), + room=str(random.getrandbits(128))) # Lar hver søker søke på tilfeldige komiteer committees_list = list(committees) @@ -364,8 +370,10 @@ def randomized_test(self, # Gir intervaller til hver komité. for committee in committees: - committee.add_intervals_with_capacities({slot: 1 for slot in random.sample( - SLOTS, random.randint(ANTALL_SLOTS_PER_KOMITE_MIN, ANTALL_SLOTS_PER_KOMITE_MAKS))}) + + for slot in random.sample( + SLOTS, random.randint(ANTALL_SLOTS_PER_KOMITE_MIN, ANTALL_SLOTS_PER_KOMITE_MAKS)): + committee.add_interview_slot(slot, str(random.getrandbits(128))) # Lar hver søker søke på tilfeldige komiteer committees_list = list(committees) diff --git a/components/committee/CommitteeInterviewTimes.tsx b/components/committee/CommitteeInterviewTimes.tsx index 7ba55fa9..88a98947 100644 --- a/components/committee/CommitteeInterviewTimes.tsx +++ b/components/committee/CommitteeInterviewTimes.tsx @@ -186,13 +186,6 @@ const CommitteeInterviewTimes = ({ return; } - if (interviewsPlanned < numberOfApplications) { - toast.error( - "Du har valgt færre tider enn antall søkere. Vennligst legg til flere tider." - ); - return; - } - const dataToSend = { periodId: period!._id, period_name: period!.name, diff --git a/lib/mongo/applicants.ts b/lib/mongo/applicants.ts index 074aa88e..bb388e85 100644 --- a/lib/mongo/applicants.ts +++ b/lib/mongo/applicants.ts @@ -27,14 +27,14 @@ export const createApplicant = async (applicantData: applicantType) => { try { if (!applicants) await init(); - const existingApplicant = await applicants.findOne({ - owId: applicantData.owId, - periodId: applicantData.periodId, - }); + // const existingApplicant = await applicants.findOne({ + // owId: applicantData.owId, + // periodId: applicantData.periodId, + // }); - if (existingApplicant) { - return { error: "409 Application already exists for this period" }; - } + // if (existingApplicant) { + // return { error: "409 Application already exists for this period" }; + // } const result = await applicants.insertOne(applicantData); if (result.insertedId) { @@ -185,7 +185,7 @@ export const getApplicantsForCommittee = async ( const today = new Date(); const sevenDaysAfterInterviewEnd = new Date(period.interviewPeriod.end); sevenDaysAfterInterviewEnd.setDate( - sevenDaysAfterInterviewEnd.getDate() + 7 + sevenDaysAfterInterviewEnd.getDate() + 5 ); if ( diff --git a/lib/sendInterviewTimes/sendInterviewTimes.ts b/lib/sendInterviewTimes/sendInterviewTimes.ts index a61e2c33..d905f90c 100644 --- a/lib/sendInterviewTimes/sendInterviewTimes.ts +++ b/lib/sendInterviewTimes/sendInterviewTimes.ts @@ -106,30 +106,13 @@ const formatApplicants = async ( interview.committeeName.toLowerCase() ); - const committeeTime = committeeInterviewTimes.find( - (time) => - time.committee.toLowerCase() === interview.committeeName.toLowerCase() - ); - - let room = "Info kommer"; - - if (committeeTime) { - const availableTime = committeeTime.availabletimes.find( - (available) => - available.start <= interview.start && available.end >= interview.end - ); - if (availableTime) { - room = availableTime.room; - } - } - return { committeeName: interview.committeeName, committeeEmail: committeeEmail?.email || "", interviewTime: { start: interview.start, end: interview.end, - room: room, + room: interview.room, }, }; }); diff --git a/lib/types/types.ts b/lib/types/types.ts index 708214ec..26a48323 100644 --- a/lib/types/types.ts +++ b/lib/types/types.ts @@ -100,6 +100,7 @@ export type algorithmType = { start: string; end: string; committeeName: string; + room: string; }[]; }; diff --git a/package-lock.json b/package-lock.json index 4944dee8..6bf93c5d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4727,9 +4727,9 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" diff --git a/pages/about.tsx b/pages/about.tsx index 37b42af3..9b1b71cb 100644 --- a/pages/about.tsx +++ b/pages/about.tsx @@ -20,7 +20,7 @@ const info = [ content: [ "Velg riktig opptaksperiode.", "Legg inn intervjutider for komiteen din innen søknadsfristen.", - "Motta e-post om intervjutider for komiteen når søknadsfristen er over.", + "Motta SMS og e-post om intervjutider for komiteen når søknadsfristen er over.", ], }, { diff --git a/pages/api/applicants/index.ts b/pages/api/applicants/index.ts index 9f355e03..f2fbb2cd 100644 --- a/pages/api/applicants/index.ts +++ b/pages/api/applicants/index.ts @@ -65,50 +65,50 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { optionalCommitteesString = "Ingen"; } - const emailData: emailDataType = { - name: applicant.name, - emails: [applicant.email], - phone: applicant.phone, - grade: applicant.grade, - about: applicant.about.replace(/\n/g, "
"), - firstChoice: "Tom", - secondChoice: "Tom", - thirdChoice: "Tom", - bankom: - applicant.bankom == "ja" - ? "Ja" - : applicant.bankom == "nei" - ? "Nei" - : "Kanskje", - optionalCommittees: optionalCommitteesString, - }; - - //Type guard - if (!Array.isArray(applicant.preferences)) { - emailData.firstChoice = - applicant.preferences.first == "onlineil" - ? "Online IL" - : capitalizeFirstLetter(applicant.preferences.first); - emailData.secondChoice = - applicant.preferences.second == "onlineil" - ? "Online IL" - : capitalizeFirstLetter(applicant.preferences.second); - emailData.thirdChoice = - applicant.preferences.third == "onlineil" - ? "Online IL" - : capitalizeFirstLetter(applicant.preferences.third); - } - - try { - await sendEmail({ - toEmails: emailData.emails, - subject: "Vi har mottatt din søknad!", - htmlContent: generateApplicantEmail(emailData), - }); - } catch (error) { - console.error("Error sending email: ", error); - throw error; - } + // const emailData: emailDataType = { + // name: applicant.name, + // emails: [applicant.email], + // phone: applicant.phone, + // grade: applicant.grade, + // about: applicant.about.replace(/\n/g, "
"), + // firstChoice: "Tom", + // secondChoice: "Tom", + // thirdChoice: "Tom", + // bankom: + // applicant.bankom == "ja" + // ? "Ja" + // : applicant.bankom == "nei" + // ? "Nei" + // : "Kanskje", + // optionalCommittees: optionalCommitteesString, + // }; + + // //Type guard + // if (!Array.isArray(applicant.preferences)) { + // emailData.firstChoice = + // applicant.preferences.first == "onlineil" + // ? "Online IL" + // : capitalizeFirstLetter(applicant.preferences.first); + // emailData.secondChoice = + // applicant.preferences.second == "onlineil" + // ? "Online IL" + // : capitalizeFirstLetter(applicant.preferences.second); + // emailData.thirdChoice = + // applicant.preferences.third == "onlineil" + // ? "Online IL" + // : capitalizeFirstLetter(applicant.preferences.third); + // } + + // try { + // await sendEmail({ + // toEmails: emailData.emails, + // subject: "Vi har mottatt din søknad!", + // htmlContent: generateApplicantEmail(emailData), + // }); + // } catch (error) { + // console.error("Error sending email: ", error); + // throw error; + // } } return res.status(201).json({ applicant }); diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts index 4252c98c..2099326a 100644 --- a/pages/api/auth/[...nextauth].ts +++ b/pages/api/auth/[...nextauth].ts @@ -54,9 +54,25 @@ export const authOptions: NextAuthOptions = { email: userInfo.email, //phone: userInfo.phone_number, //grade: userInfo.year, - committees: committeeData.results.map((committee: any) => - committee.name_short.toLowerCase() - ), + committees: [ + "appkom", + "arrkom", + "backlog", + "bankom", + "bedkom", + "debug", + "dotkom", + "ekskom", + "fagkom", + "feminit", + "jubkom", + "online-il", + "output", + "prokom", + "kjelleren", + "trikom", + "velkom", + ], isCommittee: userInfo.is_committee, }; }, diff --git a/pages/apply/[period-id].tsx b/pages/apply/[period-id].tsx index c90910b9..366a5026 100644 --- a/pages/apply/[period-id].tsx +++ b/pages/apply/[period-id].tsx @@ -150,47 +150,47 @@ const Application: NextPage = () => { if (!periodData?.exists) return ; - if (fetchedApplicationData?.exists) - return ( -
- -

- Vi har mottatt din søknad og sendt deg en bekreftelse på e-post! -

-

- Du vil få enda en e-post med intervjutider når søknadsperioden er over - (rundt {formatDateNorwegian(period?.applicationPeriod?.end)}). -

-

- (Hvis du ikke finner e-posten din, sjekk søppelpost- eller - spam-mappen.) -

- {!isApplicationPeriodOver && ( -
- ); + // {applicationData.phone && ( + //
+ // + //
+ // )} + // + // ); return (