A
Anonymous

Styled Header - Copy this React, Mui Component to your project

Vetting Page (app_vetting_page.jsx) Purpose: The main page for managing service providers through the vetting process. Components: Header: Displays the title "Vetting Applicants" and a search bar. View Mode Toggle: Allows users to switch between a Kanban board view and a table view. Vetting Process Selector: Allows users to choose between different vetting processes (e.g., Process 1, Process 2). Filter Section: Category Filter Status Filter Step Filter Date Filter Action Buttons: Move: Opens the MoveDialog. Onboard: Opens the OnboardDialog. Reject: Opens the RejectDialog. Send Email: Opens the SendEmailDialog. Kanban Board or Table: Displays the service providers in either a Kanban board or a table format. UI Details: The page should have a clear layout with the header, filters, and action buttons at the top. The Kanban board or table should be the main content area, taking up most of the screen. The filters should be collapsible and expandable. The action buttons should be clearly labeled with icons."use client"; import { useState, useMemo, useCallback } from "react"; import { ChevronDown, MoveRight, Loader2, UserCheck, UserX, Mail, Search, LayoutGrid, TableIcon } from 'lucide react'; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Checkbox } from "@/components/ui/checkbox"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import DashboardLayout from "@/components/layout/dashboard layout"; import { KanbanBoard } from "@/components/vetting/kanban board"; import { MoveDialog } from "@/components/vetting/move dialog"; import { OnboardDialog } from "@/components/vetting/onboard dialog"; import { RejectDialog } from "@/components/vetting/reject dialog"; import { SendEmailDialog } from "@/components/vetting/send email dialog"; import { ServiceProviderDetailsDialog } from "@/components/vetting/service provider details dialog"; import { dummyProviders } from "@/data/dummy providers"; import { ServiceProviderCard } from "@/components/vetting/service provider card"; const vettingProcesses = { "process1": [ "Application Submitted", "Document Verification", "Guarantee and Medical", "Interview", "Get Exam", "Re examination", ], "process2": [ "New Entry", "Course One", "Course Two", "Final Course", "Training", "Get Exam", "Re examination", ] }; export default function VettingPage() { const [viewMode, setViewMode] = useState("board"); const [isFilterVisible, setIsFilterVisible] = useState(false); const [selectedProviders, setSelectedProviders] = useState([]); const [isMoveDialogOpen, setIsMoveDialogOpen] = useState(false); const [isOnboardDialogOpen, setIsOnboardDialogOpen] = useState(false); const [isRejectDialogOpen, setIsRejectDialogOpen] = useState(false); const [isSendEmailDialogOpen, setIsSendEmailDialogOpen] = useState(false); const [isDetailsDialogOpen, setIsDetailsDialogOpen] = useState(false); const [selectedProvider, setSelectedProvider] = useState(null); const [searchTerm, setSearchTerm] = useState(""); const [selectedVettingProcess, setSelectedVettingProcess] = useState("process1"); const [selectedCategory, setSelectedCategory] = useState("all"); const [selectedStatus, setSelectedStatus] = useState("all"); const [selectedStep, setSelectedStep] = useState("all"); const [selectedDate, setSelectedDate] = useState(""); const handleProviderSelection = useCallback((id) => { setSelectedProviders((prev) => prev.includes(id) ? prev.filter((providerId) => providerId !== id) : [...prev, id] ); }, []); const filteredProviders = useMemo(() => { return dummyProviders.filter((provider) => { const matchesSearch = provider.name.toLowerCase().includes(searchTerm.toLowerCase()) || provider.email.toLowerCase().includes(searchTerm.toLowerCase()) || (provider.phoneNumber && provider.phoneNumber.includes(searchTerm)); const matchesCategory = selectedCategory === "all" || provider.category === selectedCategory; const matchesStatus = selectedStatus === "all" || provider.status === selectedStatus; const matchesStep = selectedStep === "all" || provider.step === selectedStep; const matchesDate = !selectedDate || provider.registrationDate === selectedDate; return matchesSearch && matchesCategory && matchesStatus && matchesStep && matchesDate; }); }, [searchTerm, selectedCategory, selectedStatus, selectedStep, selectedDate]); const initialColumns = useMemo(() => { const stages = vettingProcesses[selectedVettingProcess]; return stages.map((stage) => ({ id: stage.toLowerCase().replace(/\s+/g, " "), title: stage, items: stage === stages[0] ? filteredProviders.map((provider) => ({ id: provider.id, content: ( <ServiceProviderCard key={provider.id} provider={provider} isSelected={selectedProviders.includes(provider.id)} onSelect={handleProviderSelection} /> ), })) : [], })); }, [selectedVettingProcess, filteredProviders, selectedProviders, handleProviderSelection]); const handleDragEnd = (result) => { console.log("Drag ended:", result); // Implement the logic to update the backend or state here }; const handleMove = () => { if (selectedProviders.length === 0) { alert("Please select at least one service provider to proceed."); return; } setIsMoveDialogOpen(true); }; const handleOnboard = () => { if (selectedProviders.length === 0) { alert("Please select at least one service provider to proceed."); return; } setIsOnboardDialogOpen(true); }; const handleReject = () => { if (selectedProviders.length === 0) { alert("Please select at least one service provider to proceed."); return; } setIsRejectDialogOpen(true); }; const handleSendEmail = () => { if (selectedProviders.length === 0) { alert("Please select at least one service provider to proceed."); return; } setIsSendEmailDialogOpen(true); }; const handleCardDoubleClick = (provider) => { setSelectedProvider(provider); setIsDetailsDialogOpen(true); }; return ( <DashboardLayout> <div className="space y 4"> <div className="flex items center justify between"> <h1 className="text 2xl font bold">Vetting Applicants</h1> </div> <div className="flex items center justify between"> <div className="flex items center space x 2"> <span className="text sm font medium">Select Vetting process</span> <Select value={selectedVettingProcess} onValueChange={(value) => setSelectedVettingProcess(value)}> <SelectTrigger className="w [180px]"> <SelectValue placeholder="Select process" /> </SelectTrigger> <SelectContent> <SelectItem value="process1">Vetting Process 1</SelectItem> <SelectItem value="process2">Vetting Process 2</SelectItem> </SelectContent> </Select> </div> <div className="flex items center space x 2"> <Input placeholder="Search candidates" className="w 64" value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} /> <Button variant="outline" size="icon"> <Search className="h 4 w 4" /> </Button> <div className="border rounded md p 1"> <Button variant={viewMode === "table" ? "secondary" : "ghost"} size="sm" className="px 2" onClick={() => setViewMode("table")} > <TableIcon className="h 4 w 4" /> </Button> <Button variant={viewMode === "board" ? "secondary" : "ghost"} size="sm" className="px 2" onClick={() => setViewMode("board")} > <LayoutGrid className="h 4 w 4" /> </Button> </div> </div> </div> <div className="space y 2"> <div className="flex items center space x 2"> <h2 className="text lg font semibold">Categories included in this process (1)</h2> <ChevronDown className="h 4 w 4" /> </div> <div className="inline block bg purple 100 text purple 800 px 3 py 1 rounded full text sm"> Default Category for Vetting Process {selectedVettingProcess === "process1" ? "1" : "2"} </div> </div> <div className="flex items center space x 2"> <Button variant="outline" className="space x 2" onClick={handleMove}> <MoveRight className="h 4 w 4" /> <span>Move</span> </Button> <Button variant="outline" className="space x 2" onClick={handleOnboard}> <UserCheck className="h 4 w 4" /> <span>Onboard</span> </Button> <Button variant="outline" className="space x 2" onClick={handleReject}> <UserX className="h 4 w 4" /> <span>Reject</span> </Button> <Button variant="outline" className="space x 2" onClick={handleSendEmail}> <Mail className="h 4 w 4" /> <span>Send email</span> </Button> <div className="ml auto"> <Button variant="outline" onClick={() => setIsFilterVisible(!isFilterVisible)}> {isFilterVisible ? "Hide Filters" : "Show Filters"} </Button> </div> </div> {isFilterVisible && ( <Card> <CardContent className="p 4"> <div className="grid grid cols 4 gap 4"> <Select value={selectedCategory} onValueChange={setSelectedCategory}> <SelectTrigger> <SelectValue placeholder="All Categories" /> </SelectTrigger> <SelectContent> <SelectItem value="all">All Categories</SelectItem> <SelectItem value="category1">Category 1</SelectItem> <SelectItem value="category2">Category 2</SelectItem> </SelectContent> </Select> <Select value={selectedStatus} onValueChange={setSelectedStatus}> <SelectTrigger> <SelectValue placeholder="All Statuses" /> </SelectTrigger> <SelectContent> <SelectItem value="all">All Statuses</SelectItem> <SelectItem value="active">Active</SelectItem> <SelectItem value="inactive">Inactive</SelectItem> </SelectContent> </Select> <Select value={selectedStep} onValueChange={setSelectedStep}> <SelectTrigger> <SelectValue placeholder="All Steps" /> </SelectTrigger> <SelectContent> <SelectItem value="all">All Steps</SelectItem> {vettingProcesses[selectedVettingProcess].map((step) => ( <SelectItem key={step} value={step.toLowerCase().replace(/\s+/g, " ")}>{step}</SelectItem> ))} </SelectContent> </Select> <div className="flex items center space x 2"> <Input type="date" className="flex grow" value={selectedDate} onChange={(e) => setSelectedDate(e.target.value)} /> <Button variant="outline" size="icon" onClick={() => setSelectedDate("")}> <Loader2 className="h 4 w 4" /> </Button> </div> </div> <div className="flex justify end space x 2 mt 4"> <Button variant="default">Apply</Button> <Button variant="outline" onClick={() => { setSelectedCategory("all"); setSelectedStatus("all"); setSelectedStep("all"); setSelectedDate(""); }}>Reset</Button> <Button variant="outline" onClick={() => setIsFilterVisible(false)}> Hide </Button> </div> </CardContent> </Card> )} {viewMode === "board" ? ( <KanbanBoard columns={initialColumns} onDragEnd={handleDragEnd} onCardDoubleClick={handleCardDoubleClick} selectedProviders={selectedProviders} setSelectedProviders={setSelectedProviders} /> ) : ( <div className="grid grid cols 3 lg:grid cols 6 gap 4"> {vettingProcesses[selectedVettingProcess].map((stage) => ( <Card key={stage}> <CardHeader className="p 4"> <CardTitle className="text sm font medium flex items center space x 2"> <Checkbox id={stage} /> <label htmlFor={stage}>{stage}</label> </CardTitle> </CardHeader> <CardContent className="p 4"> <p className="text sm text gray 500">There are no applicants here</p> </CardContent> </Card> ))} </div> )} </div> <MoveDialog isOpen={isMoveDialogOpen} onClose={() => setIsMoveDialogOpen(false)} selectedProviders={selectedProviders} /> <OnboardDialog isOpen={isOnboardDialogOpen} onClose={() => setIsOnboardDialogOpen(false)} selectedProviders={selectedProviders} /> <RejectDialog isOpen={isRejectDialogOpen} onClose={() => setIsRejectDialogOpen(false)} selectedProviders={selectedProviders} /> <SendEmailDialog isOpen={isSendEmailDialogOpen} onClose={() => setIsSendEmailDialogOpen(false)} selectedProviders={selectedProviders} /> <ServiceProviderDetailsDialog isOpen={isDetailsDialogOpen} onClose={() => setIsDetailsDialogOpen(false)} provider={selectedProvider} /> </DashboardLayout> ); }

Prompt
Component Preview

About

StyledHeader - Manage service providers with a search bar, view mode toggle, filters, and action buttons. Built with React and MUI. Copy component code!

Share

Last updated 1 month ago