diff --git a/frontend/src/components/application/ApplicationModal.tsx b/frontend/src/components/application/ApplicationModal.tsx index 754c17b..723c4e2 100644 --- a/frontend/src/components/application/ApplicationModal.tsx +++ b/frontend/src/components/application/ApplicationModal.tsx @@ -10,7 +10,6 @@ import { Timeline } from "primereact/timeline"; import { Calendar } from "primereact/calendar"; import { Dropdown } from "primereact/dropdown"; import { deleteApplication, updateApplication } from "../../api/applications"; -import { FiEdit, FiTrash } from "react-icons/fi"; import { Toast } from "primereact/toast"; import { statusColors } from "../../constants/statusColors"; import Dialog from "../public/Dialog"; @@ -18,9 +17,12 @@ import { getEmployeesLabel, getIndustryLabel, } from "../../utils/valuesToLabels"; -import { LuLayers, LuUsers } from "react-icons/lu"; +import { + LuLayers, LuUsers, LuPencil, LuTrash2, LuSave, LuX, LuLink, LuPlus, +} from "react-icons/lu"; import { parseErrorResponse } from "../../utils/errorHandler"; + const defaultLogo = "/assets/defaultLogo.png"; interface ApplicationModalProps { @@ -50,9 +52,7 @@ const ApplicationModal = ({ date: new Date(), note: "", }); - const [editingStatusIndex, setEditingStatusIndex] = useState( - null, - ); + const [editingStatusIndex, setEditingStatusIndex] = useState(null); const [updatedApplication, setUpdatedApplication] = useState({ process: [] }); const [isValidLink, setIsValidLink] = useState(true); @@ -234,7 +234,13 @@ const ApplicationModal = ({ return (
{editingStatusIndex === index ? ( -
+
-
+
@@ -302,38 +318,32 @@ const ApplicationModal = ({ <>
- {statusLabel} -

{formattedDate}

+ {statusLabel} +

{formattedDate}

{!isEditing && !isAddingStatus && ( -
+
)}
- {item.note &&

{item.note}

} + {item.note &&

{item.note}

} )}
@@ -351,240 +361,316 @@ const ApplicationModal = ({ setUpdatedApplication({ process: [] }); onClose(); }} - className="w-full max-w-2xl h-[80%] rounded-xl flex flex-col p-6" + className="w-full max-w-2xl h-[80%] rounded-2xl flex flex-col p-0 overflow-hidden" + style={{ + background: "linear-gradient(145deg, #1e2433, #1a1f2e)", + border: "1px solid #2d3748", + }} > -
-

Application Details

-
+ {/* Gradient top bar */} +
-
- {application.company.name} - -
-

- {application.company.name} -

- {application.company.industry && ( -
-

- - {getIndustryLabel(application.company.industry)} -

-
- )} - {application.company.employees && ( -
- -

- {getEmployeesLabel(application.company.employees)} -

-
- )} +
+ {/* Header */} +
+

Application Details

+
-
-
-
- - {isEditing ? ( - - setUpdatedApplication((prev) => ({ - ...prev, - position: e.target.value, - })) - } - className="w-full p-2 border-2 rounded-md focus:outline-blue-600" - /> - ) : ( -

{application.position}

- )} -
-
- - {isEditing ? ( - - setUpdatedApplication((prev) => ({ - ...prev, - location: e.target.value, - })) - } - className="w-full p-2 border-2 rounded-md focus:outline-blue-600" - /> - ) : ( -

{application.location || "Not specified"}

- )} -
-
- - {isEditing ? ( - +
+ {application.company.name} - ) : ( -

- {application.link ? ( - - View Job Posting - - ) : ( - "Not specified" +

+ +
+

+ {application.company.name} +

+
+ {application.company.industry && ( +
+ + {getIndustryLabel(application.company.industry)} +
)} -

- )} + {application.company.employees && ( +
+ + {getEmployeesLabel(application.company.employees)} +
+ )} +
+
-
-
-
-

Application Timeline

- {!isEditing && editingStatusIndex === null && ( - - )} -
+ {/* Application details */} +
+
+ + {isEditing ? ( + + setUpdatedApplication((prev) => ({ + ...prev, + position: e.target.value, + })) + } + className="w-full p-2.5 rounded-lg text-sm text-[#e8eaed] outline-none transition-all" + style={{ + background: "#141920", + border: "1px solid #2d3748", + }} + onFocus={e => (e.target as HTMLInputElement).style.borderColor = "#5b8ef4"} + onBlur={e => (e.target as HTMLInputElement).style.borderColor = "#2d3748"} + /> + ) : ( +

{application.position}

+ )} +
-
- {isAddingStatus && ( -
-

Add New Status

-
- - setNewStatus({ ...newStatus, status: e.value }) - } - placeholder="Select Status" - className="w-full" - /> - - setNewStatus({ ...newStatus, date: e.value as Date }) - } - placeholder="Select Date" - className="w-full" - inputClassName="p-2" - /> - - setNewStatus({ ...newStatus, note: e.target.value }) - } - placeholder="Add notes (optional)" - className="w-full p-2 rounded-md focus:outline-none focus:ring focus:ring-ring" - /> -
-
- - +
+ + {isEditing ? ( + + setUpdatedApplication((prev) => ({ + ...prev, + location: e.target.value, + })) + } + className="w-full p-2.5 rounded-lg text-sm text-[#e8eaed] outline-none transition-all" + style={{ + background: "#141920", + border: "1px solid #2d3748", + }} + onFocus={e => (e.target as HTMLInputElement).style.borderColor = "#5b8ef4"} + onBlur={e => (e.target as HTMLInputElement).style.borderColor = "#2d3748"} + /> + ) : ( +

{application.location || "Not specified"}

+ )} +
+ +
+ + {isEditing ? ( + (e.target as HTMLInputElement).style.borderColor = isValidLink ? "#5b8ef4" : "#f87171"} + onBlur={e => (e.target as HTMLInputElement).style.borderColor = isValidLink ? "#2d3748" : "#f87171"} + /> + ) : ( +
+ {application.link ? ( + + + View Job Posting + + ) : ( +

Not specified

+ )}
-
- )} - - {application.process && application.process.length > 0 ? ( - - ) : ( -

- No status updates yet. Add your first status update. -

- )} + )} +
-
- {!isEditing && ( -
- - -
- )} - {isEditing && ( -
- - + {/* Timeline */} +
+
+

Application Timeline

+ {!isEditing && editingStatusIndex === null && ( + + )} +
+ +
+ {isAddingStatus && ( +
+

Add New Status

+
+ + setNewStatus({ ...newStatus, status: e.value }) + } + placeholder="Select Status" + className="w-full" + /> + + setNewStatus({ ...newStatus, date: e.value as Date }) + } + placeholder="Select Date" + className="w-full" + inputClassName="p-2" + /> + + setNewStatus({ ...newStatus, note: e.target.value }) + } + placeholder="Add notes (optional)" + className="w-full p-2 rounded-lg text-[#e8eaed] outline-none" + style={{ + background: "#141920", + border: "1px solid #2d3748", + }} + /> +
+
+ + +
+
+ )} + + {application.process && application.process.length > 0 ? ( + + ) : ( +

+ No status updates yet. Add your first status update. +

+ )} +
- )} + + {/* Actions */} + {!isEditing && ( +
+ + +
+ )} + {isEditing && ( +
+ + +
+ )} +
{ const { user } = useAuth(); - const toast = useRef(null); const [company, setCompany] = useState(); @@ -71,7 +68,6 @@ const NewApplicationModal = ({ return; } - // Save the application try { await createApplication({ userId: user._id, @@ -91,7 +87,7 @@ const NewApplicationModal = ({ toast.current?.show({ severity: "error", summary: "Error", - detail: parseErrorResponse(error), + detail: "Failed to create application: " + (error as Error).message, }); } @@ -105,112 +101,152 @@ const NewApplicationModal = ({ -
-

Create a new application

-
-
-