feat: implemented delete application endpoint and dashboard action
This commit is contained in:
parent
7b76b62490
commit
3fa875ed98
6 changed files with 74 additions and 6 deletions
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<typeof mockApplications[0] | null>(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() {
|
|||
<MessageSquare className="h-4 w-4 mr-2" />
|
||||
Message
|
||||
</Button>
|
||||
<Button
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
className="flex-1 sm:flex-none"
|
||||
onClick={(e) => handleDelete(app.id, e)}
|
||||
>
|
||||
<Trash className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
|
@ -338,11 +364,19 @@ export default function ApplicationsPage() {
|
|||
<MessageSquare className="h-4 w-4 mr-2" />
|
||||
Contact
|
||||
</Button>
|
||||
<Button
|
||||
className="flex-none"
|
||||
variant="destructive"
|
||||
onClick={() => handleDelete(selectedApp.id)}
|
||||
>
|
||||
<Trash className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div >
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<any[]>(`/api/v1/applications?${query.toString()}`);
|
||||
},
|
||||
delete: (id: string) => {
|
||||
return apiRequest<void>(`/api/v1/applications/${id}`, {
|
||||
method: "DELETE"
|
||||
})
|
||||
},
|
||||
};
|
||||
|
||||
// --- Helper Functions ---
|
||||
|
|
|
|||
Loading…
Reference in a new issue