diff --git a/src/components/admin/services/contacts/Contact.jsx b/src/components/admin/services/contacts/Contact.tsx
similarity index 54%
rename from src/components/admin/services/contacts/Contact.jsx
rename to src/components/admin/services/contacts/Contact.tsx
index 8a54a8724..aef903a93 100644
--- a/src/components/admin/services/contacts/Contact.jsx
+++ b/src/components/admin/services/contacts/Contact.tsx
@@ -7,9 +7,9 @@ import { api } from "@/utils/api";
import toaster from "@/utils/toaster";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
-const STATUSES = ["confirmed", "pending", "not attending"];
+const STATUSES = ["confirmed", "pending", "not attending"] as const;
-const MAPPINGS = {
+const MAPPINGS: Record<(typeof STATUSES)[number], number> = {
confirmed: 1,
pending: 0,
"not attending": -1,
@@ -24,28 +24,43 @@ const roleIcons = {
committees: ,
};
-const Contact = ({ role, disabled, setDisabled }) => {
- const [status, setStatus] = useState({
- status: "",
- });
+interface ContactProps {
+ role: keyof typeof roleIcons;
+ disabled: boolean;
+ setDisabled: (value: boolean) => void;
+}
- const onClick = async () => {
- setDisabled(true);
- const number = MAPPINGS[status.status];
+type Status = (typeof STATUSES)[number];
- const { items } = await api({
- method: "GET",
- url: `/api/contacts?role=${role}&status=${number}`,
- });
+const Contact: React.FC = ({ role, disabled, setDisabled }) => {
+ const [status, setStatus] = useState("");
- if (items.length === 0) {
- toaster("The email list is empty!", "error");
- setDisabled(false);
+ const onClick = async () => {
+ if (status === "") {
+ toaster("Please select a status!", "error");
return;
}
- navigator.clipboard.writeText(items);
- toaster("Copied all email addresses!", "success");
+ setDisabled(true);
+ const number = MAPPINGS[status];
+
+ try {
+ const { items }: { items: string[] } = await api({
+ method: "GET",
+ url: `/api/contacts?role=${role}&status=${number}`,
+ });
+
+ if (items.length === 0) {
+ toaster("The email list is empty!", "error");
+ setDisabled(false);
+ return;
+ }
+
+ navigator.clipboard.writeText(items.join(", "));
+ toaster("Copied all email addresses!", "success");
+ } catch (error) {
+ toaster("Failed to fetch email addresses!", "error");
+ }
setDisabled(false);
};
@@ -64,14 +79,15 @@ const Contact = ({ role, disabled, setDisabled }) => {
field="status"
user={status}
setUser={setStatus}
- onChange={() => setDisabled(status.status === "")}
- className="placeholder-gray-400"
+ required={false}
+ title="Status Selection"
/>
diff --git a/src/components/admin/services/contacts/Contacts.tsx b/src/components/admin/services/contacts/Contacts.tsx
index 8f5913546..88e1c6392 100644
--- a/src/components/admin/services/contacts/Contacts.tsx
+++ b/src/components/admin/services/contacts/Contacts.tsx
@@ -3,14 +3,9 @@ import { useState } from "react";
import Title from "../../Title";
import Contact from "./Contact";
-const contacts = [
- "participants",
- "judges",
- "volunteers",
- "mentors",
- "admins",
- "committees",
-];
+const contacts: Array<
+ "participants" | "judges" | "volunteers" | "mentors" | "admins" | "committees"
+> = ["participants", "judges", "volunteers", "mentors", "admins", "committees"];
const Contacts = () => {
const [disabled, setDisabled] = useState(false);