diff --git a/backend/internal/api/handlers/core_handlers.go b/backend/internal/api/handlers/core_handlers.go index eae2668..055a44f 100644 --- a/backend/internal/api/handlers/core_handlers.go +++ b/backend/internal/api/handlers/core_handlers.go @@ -477,7 +477,7 @@ func extractClientIP(r *http.Request) *string { // @Accept json // @Produce json // @Security BearerAuth -// @Success 200 {array} models.Notification +// @Success 200 {array} object // @Failure 500 {string} string "Internal Server Error" // @Router /api/v1/notifications [get] func (h *CoreHandlers) ListNotifications(w http.ResponseWriter, r *http.Request) { @@ -566,7 +566,7 @@ func (h *CoreHandlers) MarkAllNotificationsAsRead(w http.ResponseWriter, r *http // @Produce json // @Security BearerAuth // @Param ticket body object true "Ticket Details" -// @Success 201 {object} models.Ticket +// @Success 201 {object} object // @Failure 400 {string} string "Invalid Request" // @Failure 500 {string} string "Internal Server Error" // @Router /api/v1/support/tickets [post] @@ -607,7 +607,7 @@ func (h *CoreHandlers) CreateTicket(w http.ResponseWriter, r *http.Request) { // @Accept json // @Produce json // @Security BearerAuth -// @Success 200 {array} models.Ticket +// @Success 200 {array} object // @Failure 500 {string} string "Internal Server Error" // @Router /api/v1/support/tickets [get] func (h *CoreHandlers) ListTickets(w http.ResponseWriter, r *http.Request) { @@ -680,7 +680,7 @@ func (h *CoreHandlers) GetTicket(w http.ResponseWriter, r *http.Request) { // @Security BearerAuth // @Param id path string true "Ticket ID" // @Param message body object true "Message" -// @Success 201 {object} models.TicketMessage +// @Success 201 {object} object // @Failure 400 {string} string "Invalid Request" // @Failure 500 {string} string "Internal Server Error" // @Router /api/v1/support/tickets/{id}/messages [post] diff --git a/backend/internal/handlers/application_handler.go b/backend/internal/handlers/application_handler.go index 5d95506..b4c8776 100644 --- a/backend/internal/handlers/application_handler.go +++ b/backend/internal/handlers/application_handler.go @@ -139,3 +139,23 @@ func (h *ApplicationHandler) UpdateApplicationStatus(w http.ResponseWriter, r *h w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(app) } + +// DeleteApplication removes an application +// @Summary Delete Application +// @Description Remove an application by ID +// @Tags Applications +// @Accept json +// @Produce json +// @Param id path string true "Application ID" +// @Success 204 {object} nil +// @Failure 400 {string} string "Bad Request" +// @Failure 500 {string} string "Internal Server Error" +// @Router /api/v1/applications/{id} [delete] +func (h *ApplicationHandler) DeleteApplication(w http.ResponseWriter, r *http.Request) { + id := r.PathValue("id") + if err := h.Service.DeleteApplication(id); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusNoContent) +} diff --git a/backend/internal/router/router.go b/backend/internal/router/router.go index eea3505..ccd76c9 100755 --- a/backend/internal/router/router.go +++ b/backend/internal/router/router.go @@ -200,6 +200,7 @@ func NewRouter() http.Handler { mux.HandleFunc("GET /api/v1/applications", applicationHandler.GetApplications) mux.HandleFunc("GET /api/v1/applications/{id}", applicationHandler.GetApplicationByID) mux.HandleFunc("PUT /api/v1/applications/{id}/status", applicationHandler.UpdateApplicationStatus) + mux.HandleFunc("DELETE /api/v1/applications/{id}", applicationHandler.DeleteApplication) // --- STORAGE ROUTES --- // Initialize S3 Storage (optional - graceful degradation if not configured) diff --git a/backend/internal/services/application_service.go b/backend/internal/services/application_service.go index 28bafd0..59b80e0 100644 --- a/backend/internal/services/application_service.go +++ b/backend/internal/services/application_service.go @@ -141,3 +141,9 @@ func (s *ApplicationService) GetApplicationsByCompany(companyID string) ([]model } return apps, nil } + +func (s *ApplicationService) DeleteApplication(id string) error { + query := `DELETE FROM applications WHERE id = $1` + _, err := s.DB.Exec(query, id) + return err +} diff --git a/frontend/src/app/dashboard/applications/page.tsx b/frontend/src/app/dashboard/applications/page.tsx index 7814cad..c4b50a6 100644 --- a/frontend/src/app/dashboard/applications/page.tsx +++ b/frontend/src/app/dashboard/applications/page.tsx @@ -33,7 +33,10 @@ import { X, Clock, Star, + Trash, } from "lucide-react" +import { applicationsApi } from "@/lib/api" +import { toast } from "sonner" // Mock data - in production this would come from API const mockApplications = [ @@ -108,6 +111,21 @@ export default function ApplicationsPage() { const [searchTerm, setSearchTerm] = useState("") const [selectedApp, setSelectedApp] = useState(null) + const handleDelete = async (id: string, e?: React.MouseEvent) => { + e?.stopPropagation() + if (!confirm("Are you sure you want to delete this application?")) return + + try { + await applicationsApi.delete(id) + setApplications(applications.filter(a => a.id !== id)) + toast.success("Application deleted") + if (selectedApp?.id === id) setSelectedApp(null) + } catch (error) { + console.error("Delete error:", error) + toast.error("Failed to delete application") + } + } + const filteredApplications = applications.filter((app) => { const matchesStatus = statusFilter === "all" || app.status === statusFilter const matchesSearch = @@ -265,6 +283,14 @@ export default function ApplicationsPage() { Message + @@ -338,11 +364,19 @@ export default function ApplicationsPage() { Contact + - )} - + ) + } + ) } diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index ea9133d..e44a375 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -307,6 +307,8 @@ export const adminCompaniesApi = { } }; + + // --- Jobs API (Public/Candidate) --- export interface CreateJobPayload { companyId: string; @@ -396,6 +398,11 @@ export const applicationsApi = { if (params.companyId) query.append("companyId", params.companyId); return apiRequest(`/api/v1/applications?${query.toString()}`); }, + delete: (id: string) => { + return apiRequest(`/api/v1/applications/${id}`, { + method: "DELETE" + }) + }, }; // --- Helper Functions ---