···
import { css, html, LitElement } from "lit";
import { customElement, state } from "lit/decorators.js";
3
+
import type { MeetingTime } from "./meeting-time-picker";
4
+
import "./meeting-time-picker";
···
@state() showCreateModal = false;
@state() activeTab: "classes" | "waitlist" = "classes";
@state() approvingEntry: WaitlistEntry | null = null;
38
-
@state() meetingTimes: string[] = [""];
40
+
@state() meetingTimes: MeetingTime[] = [];
41
+
@state() editingClass = {
46
+
year: new Date().getFullYear(),
static override styles = css`
···
319
-
.form-group input:focus {
328
+
.form-group input:focus,
329
+
.form-group select:focus {
border-color: var(--primary);
334
+
.form-group select {
337
+
border: 2px solid var(--secondary);
338
+
border-radius: 6px;
340
+
font-family: inherit;
341
+
background: var(--background);
342
+
color: var(--text);
343
+
box-sizing: border-box;
348
+
grid-template-columns: 1fr 1fr;
350
+
margin-bottom: 1rem;
354
+
grid-column: 1 / -1;
···
private handleApproveWaitlist(entry: WaitlistEntry) {
this.approvingEntry = entry;
727
+
// Pre-fill form with waitlist data
728
+
this.editingClass = {
729
+
courseCode: entry.course_code,
730
+
courseName: entry.course_name,
731
+
professor: entry.professor,
732
+
semester: entry.semester,
// Parse meeting times from JSON if available, otherwise use empty array
if (entry.meeting_times) {
const parsed = JSON.parse(entry.meeting_times);
698
-
this.meetingTimes = Array.isArray(parsed) && parsed.length > 0 ? parsed : [""];
740
+
this.meetingTimes = Array.isArray(parsed) && parsed.length > 0 ? parsed : [];
700
-
this.meetingTimes = [""];
742
+
this.meetingTimes = [];
703
-
this.meetingTimes = [""];
745
+
this.meetingTimes = [];
707
-
private addMeetingTime() {
708
-
this.meetingTimes = [...this.meetingTimes, ""];
711
-
private removeMeetingTime(index: number) {
712
-
this.meetingTimes = this.meetingTimes.filter((_, i) => i !== index);
749
+
private handleMeetingTimesChange(e: CustomEvent) {
750
+
this.meetingTimes = e.detail;
715
-
private updateMeetingTime(index: number, value: string) {
716
-
this.meetingTimes = this.meetingTimes.map((time, i) =>
717
-
i === index ? value : time,
753
+
private handleClassFieldInput(field: string, e: Event) {
754
+
const value = (e.target as HTMLInputElement | HTMLSelectElement).value;
755
+
this.editingClass = { ...this.editingClass, [field]: value };
private cancelApproval() {
this.approvingEntry = null;
723
-
this.meetingTimes = [""];
760
+
this.meetingTimes = [];
761
+
this.editingClass = {
766
+
year: new Date().getFullYear(),
private async submitApproval() {
if (!this.approvingEntry) return;
729
-
const entry = this.approvingEntry;
730
-
const times = this.meetingTimes.filter((t) => t.trim() !== "");
732
-
if (times.length === 0) {
773
+
if (this.meetingTimes.length === 0) {
this.error = "Please add at least one meeting time";
778
+
// Convert MeetingTime objects to label strings
779
+
const labels = this.meetingTimes.map((t) => t.label);
const response = await fetch("/api/classes", {
headers: { "Content-Type": "application/json" },
742
-
course_code: entry.course_code,
743
-
name: entry.course_name,
744
-
professor: entry.professor,
745
-
semester: entry.semester,
747
-
meeting_times: times,
786
+
course_code: this.editingClass.courseCode,
787
+
name: this.editingClass.courseName,
788
+
professor: this.editingClass.professor,
789
+
semester: this.editingClass.semester,
790
+
year: this.editingClass.year,
791
+
meeting_times: labels,
752
-
throw new Error("Failed to create class");
796
+
const data = await response.json();
797
+
console.error("Failed to create class:", data);
798
+
throw new Error(data.error || "Failed to create class");
755
-
await fetch(`/api/admin/waitlist/${entry.id}`, {
801
+
await fetch(`/api/admin/waitlist/${this.approvingEntry.id}`, {
···
this.activeTab = "classes";
this.approvingEntry = null;
763
-
this.meetingTimes = [""];
765
-
this.error = "Failed to approve waitlist entry. Please try again.";
809
+
this.meetingTimes = [];
810
+
this.editingClass = {
815
+
year: new Date().getFullYear(),
818
+
console.error("Error in submitApproval:", error);
819
+
this.error = error instanceof Error ? error.message : "Failed to approve waitlist entry. Please try again.";
private renderApprovalModal() {
if (!this.approvingEntry) return "";
772
-
const entry = this.approvingEntry;
<div class="modal-overlay" @click=${this.cancelApproval}>
<div class="modal" @click=${(e: Event) => e.stopPropagation()}>
777
-
<h2 class="modal-title">Add Meeting Times</h2>
829
+
<h2 class="modal-title">Review & Create Class</h2>
<p style="margin-bottom: 1.5rem; color: var(--paynes-gray);">
780
-
Creating class: <strong>${entry.course_code} - ${entry.course_name}</strong>
832
+
Review the class details and make any edits before creating
783
-
<div class="form-group">
784
-
<label>Meeting Times</label>
785
-
<div class="meeting-times-list">
786
-
${this.meetingTimes.map(
787
-
(time, index) => html`
788
-
<div class="meeting-time-row">
791
-
placeholder="e.g., Monday Lecture, Wednesday Lab"
793
-
@input=${(e: Event) =>
794
-
this.updateMeetingTime(
796
-
(e.target as HTMLInputElement).value,
800
-
this.meetingTimes.length > 1
804
-
@click=${() => this.removeMeetingTime(index)}
814
-
<button class="btn-add" @click=${this.addMeetingTime}>
835
+
${this.error ? html`<div class="error-message">${this.error}</div>` : ""}
837
+
<div class="form-grid">
838
+
<div class="form-group">
839
+
<label>Course Code *</label>
843
+
.value=${this.editingClass.courseCode}
844
+
@input=${(e: Event) => this.handleClassFieldInput("courseCode", e)}
847
+
<div class="form-group">
848
+
<label>Course Name *</label>
852
+
.value=${this.editingClass.courseName}
853
+
@input=${(e: Event) => this.handleClassFieldInput("courseName", e)}
856
+
<div class="form-group">
857
+
<label>Professor *</label>
861
+
.value=${this.editingClass.professor}
862
+
@input=${(e: Event) => this.handleClassFieldInput("professor", e)}
865
+
<div class="form-group">
866
+
<label>Semester *</label>
869
+
.value=${this.editingClass.semester}
870
+
@change=${(e: Event) => this.handleClassFieldInput("semester", e)}
872
+
<option value="">Select semester</option>
873
+
<option value="Spring">Spring</option>
874
+
<option value="Summer">Summer</option>
875
+
<option value="Fall">Fall</option>
876
+
<option value="Winter">Winter</option>
879
+
<div class="form-group">
880
+
<label>Year *</label>
886
+
.value=${this.editingClass.year.toString()}
887
+
@input=${(e: Event) => this.handleClassFieldInput("year", e)}
890
+
<div class="form-group form-group-full">
891
+
<label>Meeting Times *</label>
892
+
<meeting-time-picker
893
+
.value=${this.meetingTimes}
894
+
@change=${this.handleMeetingTimesChange}
895
+
></meeting-time-picker>
···
@click=${this.submitApproval}
827
-
?disabled=${this.meetingTimes.every((t) => t.trim() === "")}
906
+
?disabled=${this.meetingTimes.length === 0}