Update src/app/applications/page.tsx
This commit is contained in:
@@ -2,43 +2,125 @@
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleCentered from "@/components/navbar/NavbarStyleCentered/NavbarStyleCentered";
|
||||
import MetricCardTen from "@/components/sections/metrics/MetricCardTen";
|
||||
import FeatureBento from "@/components/sections/feature/FeatureBento";
|
||||
import FooterBase from "@/components/sections/footer/FooterBase";
|
||||
import {
|
||||
Users,
|
||||
BarChart3,
|
||||
Shield,
|
||||
Activity,
|
||||
TrendingUp,
|
||||
} from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { Briefcase, Clock, CheckCircle, AlertCircle, MapPin, DollarSign, Building2, Calendar, ArrowRight } from "lucide-react";
|
||||
|
||||
const navItems = [
|
||||
{ name: "Dashboard", id: "/admin" },
|
||||
{ name: "Jobs", id: "/admin#jobs" },
|
||||
{ name: "Users", id: "/admin#users" },
|
||||
{ name: "Moderation", id: "/admin#moderation" },
|
||||
{ name: "Analytics", id: "/admin#analytics" },
|
||||
{ name: "Search Jobs", id: "search" },
|
||||
{ name: "Post a Job", id: "post-job" },
|
||||
{ name: "Admin", id: "admin-login" },
|
||||
{ name: "Browse", id: "browse" },
|
||||
{ name: "Contact", id: "contact" },
|
||||
{ name: "Applications", id: "/applications" },
|
||||
];
|
||||
|
||||
const footerColumns = [
|
||||
{
|
||||
title: "Admin", items: [
|
||||
{ label: "Dashboard", href: "/admin" },
|
||||
{ label: "Settings", href: "/admin#settings" },
|
||||
{ label: "Reports", href: "/admin#reports" },
|
||||
title: "Product", items: [
|
||||
{ label: "Search Jobs", href: "/search" },
|
||||
{ label: "Post a Job", href: "/post-job" },
|
||||
{ label: "Browse by Province", href: "#provinces" },
|
||||
{ label: "For Employers", href: "#" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Quick Links", items: [
|
||||
{ label: "Help", href: "#" },
|
||||
title: "Company", items: [
|
||||
{ label: "About Jobee", href: "#about" },
|
||||
{ label: "Careers", href: "#" },
|
||||
{ label: "Contact Us", href: "#contact" },
|
||||
{ label: "Blog", href: "#" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Resources", items: [
|
||||
{ label: "Privacy Policy", href: "#" },
|
||||
{ label: "Terms of Service", href: "#" },
|
||||
{ label: "FAQ", href: "#" },
|
||||
{ label: "Support", href: "#" },
|
||||
{ label: "Documentation", href: "#" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
interface Application {
|
||||
id: string;
|
||||
jobTitle: string;
|
||||
company: string;
|
||||
location: string;
|
||||
salary: string;
|
||||
appliedDate: string;
|
||||
status: "pending" | "reviewed" | "accepted" | "rejected";
|
||||
logoSrc?: string;
|
||||
}
|
||||
|
||||
const mockApplications: Application[] = [
|
||||
{
|
||||
id: "1", jobTitle: "Senior React Developer", company: "TechFlow Solutions", location: "Amsterdam, Netherlands", salary: "€65,000 - €80,000", appliedDate: "2025-01-15", status: "reviewed", logoSrc: "https://api.dicebear.com/7.x/initials/svg?seed=TF"},
|
||||
{
|
||||
id: "2", jobTitle: "UX/UI Designer", company: "Creative Studios Amsterdam", location: "Amsterdam, Netherlands", salary: "€50,000 - €65,000", appliedDate: "2025-01-10", status: "accepted", logoSrc: "https://api.dicebear.com/7.x/initials/svg?seed=CSA"},
|
||||
{
|
||||
id: "3", jobTitle: "Full Stack Developer", company: "Innovate Inc", location: "Rotterdam, Netherlands", salary: "€55,000 - €70,000", appliedDate: "2025-01-12", status: "pending", logoSrc: "https://api.dicebear.com/7.x/initials/svg?seed=II"},
|
||||
{
|
||||
id: "4", jobTitle: "Marketing Manager", company: "Digital Growth Partners", location: "Utrecht, Netherlands", salary: "€48,000 - €60,000", appliedDate: "2025-01-08", status: "rejected", logoSrc: "https://api.dicebear.com/7.x/initials/svg?seed=DGP"},
|
||||
{
|
||||
id: "5", jobTitle: "Data Scientist", company: "Analytics Pro", location: "The Hague, Netherlands", salary: "€60,000 - €75,000", appliedDate: "2025-01-05", status: "reviewed", logoSrc: "https://api.dicebear.com/7.x/initials/svg?seed=AP"},
|
||||
{
|
||||
id: "6", jobTitle: "Product Manager", company: "Tech Ventures", location: "Eindhoven, Netherlands", salary: "€65,000 - €85,000", appliedDate: "2025-01-02", status: "pending", logoSrc: "https://api.dicebear.com/7.x/initials/svg?seed=TV"},
|
||||
];
|
||||
|
||||
const getStatusColor = (status: string) => {
|
||||
switch (status) {
|
||||
case "accepted":
|
||||
return "bg-green-100 text-green-800";
|
||||
case "rejected":
|
||||
return "bg-red-100 text-red-800";
|
||||
case "reviewed":
|
||||
return "bg-blue-100 text-blue-800";
|
||||
case "pending":
|
||||
return "bg-yellow-100 text-yellow-800";
|
||||
default:
|
||||
return "bg-gray-100 text-gray-800";
|
||||
}
|
||||
};
|
||||
|
||||
const getStatusIcon = (status: string) => {
|
||||
switch (status) {
|
||||
case "accepted":
|
||||
return <CheckCircle className="w-4 h-4" />;
|
||||
case "rejected":
|
||||
return <AlertCircle className="w-4 h-4" />;
|
||||
case "reviewed":
|
||||
return <Clock className="w-4 h-4" />;
|
||||
case "pending":
|
||||
return <Clock className="w-4 h-4" />;
|
||||
default:
|
||||
return <Clock className="w-4 h-4" />;
|
||||
}
|
||||
};
|
||||
|
||||
const getStatusLabel = (status: string) => {
|
||||
switch (status) {
|
||||
case "accepted":
|
||||
return "Accepted";
|
||||
case "rejected":
|
||||
return "Rejected";
|
||||
case "reviewed":
|
||||
return "Under Review";
|
||||
case "pending":
|
||||
return "Pending";
|
||||
default:
|
||||
return status;
|
||||
}
|
||||
};
|
||||
|
||||
export default function ApplicationsPage() {
|
||||
const [selectedApplication, setSelectedApplication] = useState<Application | null>(null);
|
||||
const [statusFilter, setStatusFilter] = useState<string>("all");
|
||||
|
||||
const filteredApplications = statusFilter === "all"
|
||||
? mockApplications
|
||||
: mockApplications.filter(app => app.status === statusFilter);
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="text-stagger"
|
||||
@@ -54,67 +136,218 @@ export default function ApplicationsPage() {
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarStyleCentered
|
||||
brandName="Jobee Admin"
|
||||
brandName="Jobee"
|
||||
navItems={navItems}
|
||||
button={{
|
||||
text: "Logout", onClick: () => console.log("logout"),
|
||||
}}
|
||||
text: "Post a Job", href: "/post-job"}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="applications" data-section="applications" className="pt-20">
|
||||
<MetricCardTen
|
||||
title="Job Management"
|
||||
description="Monitor and manage all job postings across the platform"
|
||||
tag="Active Jobs"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
animationType="slide-up"
|
||||
metrics={[
|
||||
{
|
||||
id: "1", title: "Senior Software Engineer, Backend", subtitle: "Amsterdam, Netherlands · Full-time · Remote eligible", category: "Engineering", value: "Posted 2 days ago", buttons: [
|
||||
{ text: "View", href: "#" },
|
||||
{ text: "Manage", href: "#" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "2", title: "Product Manager, Enterprise", subtitle: "Rotterdam, Netherlands · Full-time", category: "Product", value: "Posted 5 days ago", buttons: [
|
||||
{ text: "View", href: "#" },
|
||||
{ text: "Manage", href: "#" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "3", title: "UX Designer, B2B", subtitle: "Utrecht, Netherlands · Full-time", category: "Design", value: "Posted 1 week ago", buttons: [
|
||||
{ text: "View", href: "#" },
|
||||
{ text: "Manage", href: "#" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "4", title: "Data Scientist, ML Platform", subtitle: "Remote · Full-time", category: "Data", value: "Posted 10 days ago", buttons: [
|
||||
{ text: "View", href: "#" },
|
||||
{ text: "Manage", href: "#" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "5", title: "DevOps Engineer, Infrastructure", subtitle: "Amsterdam, Netherlands · Full-time · Remote", category: "Infrastructure", value: "Posted 3 weeks ago", buttons: [
|
||||
{ text: "View", href: "#" },
|
||||
{ text: "Manage", href: "#" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "6", title: "Marketing Manager, Growth", subtitle: "The Hague, Netherlands · Full-time", category: "Marketing", value: "Posted 1 month ago", buttons: [
|
||||
{ text: "View", href: "#" },
|
||||
{ text: "Manage", href: "#" },
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<main className="min-h-screen bg-gradient-to-br from-background via-card to-background">
|
||||
<div className="container mx-auto px-4 py-16">
|
||||
{/* Header Section */}
|
||||
<div className="mb-12">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<Briefcase className="w-8 h-8 text-primary-cta" />
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-foreground">My Applications</h1>
|
||||
</div>
|
||||
<p className="text-lg text-foreground/70 mb-8">
|
||||
Track and manage all your job applications in one place. Monitor your application status and stay updated on opportunities.
|
||||
</p>
|
||||
|
||||
{/* Status Filter */}
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<button
|
||||
onClick={() => setStatusFilter("all")}
|
||||
className={`px-6 py-2 rounded-full font-medium transition-all ${
|
||||
statusFilter === "all"
|
||||
? "bg-primary-cta text-white"
|
||||
: "bg-card border border-accent/30 text-foreground hover:border-accent"
|
||||
}`}
|
||||
>
|
||||
All Applications ({mockApplications.length})
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setStatusFilter("pending")}
|
||||
className={`px-6 py-2 rounded-full font-medium transition-all ${
|
||||
statusFilter === "pending"
|
||||
? "bg-yellow-500 text-white"
|
||||
: "bg-card border border-accent/30 text-foreground hover:border-accent"
|
||||
}`}
|
||||
>
|
||||
Pending
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setStatusFilter("reviewed")}
|
||||
className={`px-6 py-2 rounded-full font-medium transition-all ${
|
||||
statusFilter === "reviewed"
|
||||
? "bg-blue-500 text-white"
|
||||
: "bg-card border border-accent/30 text-foreground hover:border-accent"
|
||||
}`}
|
||||
>
|
||||
Under Review
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setStatusFilter("accepted")}
|
||||
className={`px-6 py-2 rounded-full font-medium transition-all ${
|
||||
statusFilter === "accepted"
|
||||
? "bg-green-500 text-white"
|
||||
: "bg-card border border-accent/30 text-foreground hover:border-accent"
|
||||
}`}
|
||||
>
|
||||
Accepted
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setStatusFilter("rejected")}
|
||||
className={`px-6 py-2 rounded-full font-medium transition-all ${
|
||||
statusFilter === "rejected"
|
||||
? "bg-red-500 text-white"
|
||||
: "bg-card border border-accent/30 text-foreground hover:border-accent"
|
||||
}`}
|
||||
>
|
||||
Rejected
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Applications Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
||||
{/* Application List */}
|
||||
<div className="lg:col-span-2">
|
||||
<div className="space-y-4">
|
||||
{filteredApplications.length === 0 ? (
|
||||
<div className="bg-card border border-accent/20 rounded-2xl p-8 text-center">
|
||||
<Briefcase className="w-12 h-12 text-foreground/30 mx-auto mb-4" />
|
||||
<p className="text-foreground/60">No applications found with this status.</p>
|
||||
</div>
|
||||
) : (
|
||||
filteredApplications.map((app) => (
|
||||
<div
|
||||
key={app.id}
|
||||
onClick={() => setSelectedApplication(app)}
|
||||
className={`bg-card border border-accent/20 rounded-2xl p-6 cursor-pointer transition-all hover:border-accent/50 hover:shadow-lg ${
|
||||
selectedApplication?.id === app.id ? "border-primary-cta" : ""
|
||||
}`}
|
||||
>
|
||||
<div className="flex gap-4">
|
||||
{/* Company Logo */}
|
||||
<div className="flex-shrink-0">
|
||||
<div className="w-16 h-16 bg-gradient-to-br from-primary-cta/20 to-accent/20 rounded-xl flex items-center justify-center">
|
||||
<Building2 className="w-8 h-8 text-primary-cta" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Application Info */}
|
||||
<div className="flex-grow">
|
||||
<div className="flex items-start justify-between mb-2">
|
||||
<div>
|
||||
<h3 className="text-lg font-bold text-foreground">{app.jobTitle}</h3>
|
||||
<p className="text-sm text-foreground/60">{app.company}</p>
|
||||
</div>
|
||||
<span
|
||||
className={`px-3 py-1 rounded-full text-xs font-medium flex items-center gap-1 ${
|
||||
getStatusColor(app.status)
|
||||
}`}
|
||||
>
|
||||
{getStatusIcon(app.status)}
|
||||
{getStatusLabel(app.status)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap gap-4 text-sm text-foreground/60 mt-3">
|
||||
<div className="flex items-center gap-1">
|
||||
<MapPin className="w-4 h-4" />
|
||||
{app.location}
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<DollarSign className="w-4 h-4" />
|
||||
{app.salary}
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<Calendar className="w-4 h-4" />
|
||||
{new Date(app.appliedDate).toLocaleDateString()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Arrow Icon */}
|
||||
<div className="flex-shrink-0 flex items-center">
|
||||
<ArrowRight className="w-5 h-5 text-foreground/30" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Application Details Panel */}
|
||||
<div className="lg:col-span-1">
|
||||
{selectedApplication ? (
|
||||
<div className="bg-card border border-accent/20 rounded-2xl p-6 sticky top-24">
|
||||
<div className="mb-6">
|
||||
<h2 className="text-2xl font-bold text-foreground mb-2">{selectedApplication.jobTitle}</h2>
|
||||
<p className="text-foreground/60 mb-4">{selectedApplication.company}</p>
|
||||
<span
|
||||
className={`inline-flex items-center gap-2 px-4 py-2 rounded-full text-sm font-medium ${
|
||||
getStatusColor(selectedApplication.status)
|
||||
}`}
|
||||
>
|
||||
{getStatusIcon(selectedApplication.status)}
|
||||
{getStatusLabel(selectedApplication.status)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4 border-t border-accent/10 pt-6">
|
||||
<div>
|
||||
<p className="text-xs font-semibold text-foreground/50 uppercase tracking-wide mb-2">Location</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<MapPin className="w-4 h-4 text-primary-cta" />
|
||||
<p className="text-foreground">{selectedApplication.location}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="text-xs font-semibold text-foreground/50 uppercase tracking-wide mb-2">Salary Range</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<DollarSign className="w-4 h-4 text-primary-cta" />
|
||||
<p className="text-foreground">{selectedApplication.salary}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="text-xs font-semibold text-foreground/50 uppercase tracking-wide mb-2">Applied Date</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<Calendar className="w-4 h-4 text-primary-cta" />
|
||||
<p className="text-foreground">{new Date(selectedApplication.appliedDate).toLocaleDateString()}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 space-y-2">
|
||||
<button className="w-full bg-primary-cta text-white py-3 rounded-lg font-medium hover:opacity-90 transition-opacity">
|
||||
View Application
|
||||
</button>
|
||||
<button className="w-full bg-card border border-accent/30 text-foreground py-3 rounded-lg font-medium hover:border-accent transition-colors">
|
||||
Contact Company
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="bg-card border border-accent/20 rounded-2xl p-6 text-center">
|
||||
<Briefcase className="w-12 h-12 text-foreground/30 mx-auto mb-4" />
|
||||
<p className="text-foreground/60">Select an application to view details</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div id="footer" data-section="footer">
|
||||
<FooterBase
|
||||
logoText="Jobee Admin"
|
||||
copyrightText="© 2025 Jobee Admin Portal"
|
||||
logoText="Jobee"
|
||||
copyrightText="© 2025 Jobee | Dutch Job Listing Platform"
|
||||
columns={footerColumns}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user