dev1/src/components/MilestoneTracker.js

212 lines
9.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
import { CheckCircle, Clock, Target, PlusCircle, Search } from "lucide-react";
import { Input } from "@/components/ui/input";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
const careerClusters = [
"Software Development",
"Healthcare",
"Engineering",
"Finance",
"Education",
"Marketing",
"Cybersecurity",
"Construction",
"Legal",
"Data Science",
"Sales",
"Human Resources",
"Manufacturing",
"Aviation",
"Social Work",
"Design & UX",
"Hospitality",
"Retail Management",
"Real Estate",
"Transportation",
"Agriculture",
"Public Administration",
"Energy & Environment"
];
const universalPrerequisites = {
"Software Development": ["Learn a Programming Language", "Build and Deploy a Small Project", "Understand Data Structures & Algorithms"],
"Healthcare": ["Complete Required Certifications", "Pass Licensing Exam", "Gain Clinical Experience"],
"Engineering": ["Earn a Relevant Engineering Degree", "Obtain Engineering Certification (PE/EIT)", "Gain Hands-on Experience"],
"Finance": ["Earn a Bachelor's in Finance or Related Field", "Gain Experience with Financial Modeling", "Obtain CFA or CPA Certification"],
"Education": ["Complete a Teaching Credential", "Pass State Licensing Exam", "Gain Classroom Experience"],
"Marketing": ["Learn Digital Marketing Basics", "Build a Portfolio of Campaigns", "Gain Experience in Market Research"],
"Cybersecurity": ["Learn Network Security Fundamentals", "Obtain CompTIA Security+ or CISSP", "Gain Hands-on Security Experience"],
"Construction": ["Complete an Apprenticeship Program", "Earn a Safety Certification (OSHA)", "Gain On-Site Experience"],
"Legal": ["Earn a Law Degree (JD)", "Pass the Bar Exam", "Gain Internship Experience at a Law Firm"],
"Data Science": ["Learn Python & SQL", "Complete a Machine Learning Course", "Build a Data Science Portfolio"],
"Sales": ["Develop Strong Communication Skills", "Understand CRM Tools", "Gain Sales Experience"],
"Human Resources": ["Earn a Bachelor's in HR or Business", "Obtain PHR or SHRM Certification", "Gain HR Generalist Experience"],
"Manufacturing": ["Learn Manufacturing Processes", "Complete a Safety Training Course", "Gain Hands-on Experience in Production"],
"Aviation": ["Earn a Pilots License", "Pass FAA Certification Exams", "Gain Flight Hours"],
"Social Work": ["Earn a Social Work Degree", "Obtain State Licensing", "Gain Casework Experience"],
"Design & UX": ["Learn UI/UX Design Principles", "Build a Portfolio of Designs", "Gain Experience with Design Tools (Figma, Adobe XD)"],
"Hospitality": ["Gain Customer Service Experience", "Complete Hospitality Management Courses", "Develop Event Planning Skills"],
"Retail Management": ["Gain Experience in Retail Operations", "Learn Inventory & Budget Management", "Develop Leadership Skills"],
"Real Estate": ["Earn a Real Estate License", "Develop Sales & Negotiation Skills", "Understand Market Trends"],
"Transportation": ["Obtain a Commercial Driver's License (CDL)", "Complete Logistics Training", "Gain Hands-on Experience in Transportation"],
"Agriculture": ["Learn Crop & Soil Science Basics", "Understand Farm Equipment Operation", "Gain Hands-on Farming Experience"],
"Public Administration": ["Earn a Public Administration Degree", "Understand Government Policies & Regulations", "Gain Leadership Experience"],
"Energy & Environment": ["Learn Renewable Energy Technologies", "Understand Environmental Regulations", "Gain Fieldwork Experience"]
};
const MilestoneTracker = () => {
const [activeTab, setActiveTab] = useState("career");
const [customMilestones, setCustomMilestones] = useState({ career: [], financial: [], retirement: [] });
const [isDialogOpen, setIsDialogOpen] = useState(false);
const [newMilestone, setNewMilestone] = useState("");
const [careerSearch, setCareerSearch] = useState("");
const [filteredCareers, setFilteredCareers] = useState(careerClusters);
useEffect(() => {
const fetchUserProfile = async () => {
try {
const response = await fetch("/api/user/profile", {
method: "GET",
credentials: "include", // Ensure cookies/session are sent
});
if (response.ok) {
const data = await response.json();
setIsPremiumUser(data.is_premium === 1); // Expecting { is_premium: 0 or 1 }
} else {
setIsPremiumUser(false); // Default to false if there's an error
}
} catch (error) {
console.error("Error fetching user profile:", error);
setIsPremiumUser(false);
}
};
fetchUserProfile();
}, []);
if (isPremiumUser === null) {
return <div className="p-6 text-center">Loading...</div>; // Show loading state while fetching
}
if (!isPremiumUser) {
return (
<div className="p-6 text-center">
<Lock className="mx-auto text-gray-400 w-16 h-16 mb-4" />
<h2 className="text-xl font-bold">Access Restricted</h2>
<p className="text-gray-600">Upgrade to Aptiva Premium to access the Milestone Tracker.</p>
<Button className="mt-4">Upgrade Now</Button>
</div>
);
}
const handleAddMilestone = () => {
if (newMilestone.trim() !== "") {
setCustomMilestones((prev) => ({
...prev,
[activeTab]: [...prev[activeTab], { title: newMilestone, status: "upcoming", progress: 0 }],
}));
setNewMilestone("");
setIsDialogOpen(false);
}
};
const handleCareerSearch = (e) => {
const query = e.target.value.toLowerCase();
setCareerSearch(query);
setFilteredCareers(
careerClusters.filter((career) => career.toLowerCase().includes(query))
);
};
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4">Milestone Tracker</h1>
{/* Career Search Section */}
<div className="mb-6 p-4 border rounded-lg shadow-md bg-white">
<h2 className="text-xl font-semibold mb-2">Search for a Career Path</h2>
<Input
value={careerSearch}
onChange={handleCareerSearch}
placeholder="Search for a career cluster"
className="mb-2"
/>
<div className="max-h-40 overflow-y-auto border rounded p-2">
{filteredCareers.map((career, index) => (
<div key={index} className="p-2 hover:bg-gray-200 cursor-pointer rounded">
<strong>{career}</strong>
</div>
))}
</div>
</div>
{/* Milestone Tracker Section */}
<Tabs value={activeTab} onValueChange={setActiveTab} className="mb-6">
<TabsList>
<TabsTrigger value="career">Career</TabsTrigger>
<TabsTrigger value="financial">Financial</TabsTrigger>
<TabsTrigger value="retirement">Retirement</TabsTrigger>
</TabsList>
</Tabs>
{/* Add Milestone Section */}
<Button onClick={() => setIsDialogOpen(true)} className="mb-4 flex items-center gap-2">
<PlusCircle /> Add Milestone
</Button>
<Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>Add a New Milestone</DialogTitle>
</DialogHeader>
<Input value={newMilestone} onChange={(e) => setNewMilestone(e.target.value)} placeholder="Enter milestone title" />
<DialogFooter>
<Button onClick={handleAddMilestone}>Save</Button>
</DialogFooter>
</DialogContent>
</Dialog>
{/* Display User-Added Milestones */}
<TabsContent value={activeTab}>
{customMilestones[activeTab].map((milestone, index) => (
<Card key={index} className="mb-4 p-4">
<CardContent className="flex justify-between items-center">
<div className="flex items-center gap-4">
{milestone.status === "completed" && <CheckCircle className="text-green-500" />}
{milestone.status === "in-progress" && <Clock className="text-yellow-500" />}
{milestone.status === "upcoming" && <Target className="text-gray-500" />}
<h2 className="text-lg font-semibold">{milestone.title}</h2>
</div>
<Progress value={milestone.progress} className="w-40" />
</CardContent>
</Card>
))}
</TabsContent>
<Button onClick={() => setIsDialogOpen(true)} className="mb-4 flex items-center gap-2">
<PlusCircle /> Add Milestone
</Button>
<Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>Add a New Milestone</DialogTitle>
</DialogHeader>
<Input value={newMilestone} onChange={(e) => setNewMilestone(e.target.value)} placeholder="Enter milestone title" />
<DialogFooter>
<Button onClick={handleAddMilestone}>Save</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
);
};
export default MilestoneTracker;