mohan #26

Merged
mohanmd merged 12 commits from mohan into master 2026-07-09 10:16:34 +00:00
31 changed files with 473 additions and 163 deletions
Showing only changes of commit a735ce3b00 - Show all commits

View File

@ -62,6 +62,33 @@ public function index(Request $request)
$totalHiredAll = \App\Models\JobOffer::where('status', 'accepted')->count() + $totalHiredAll = \App\Models\JobOffer::where('status', 'accepted')->count() +
\App\Models\JobApplication::where('status', 'hired')->count(); \App\Models\JobApplication::where('status', 'hired')->count();
$totalActiveWorkers = \App\Models\Worker::where('status', 'active')->count(); $totalActiveWorkers = \App\Models\Worker::where('status', 'active')->count();
$totalWorkerProfiles = \App\Models\Worker::count();
// Calculate dynamic avg monthly hires based on actual database entries if available, otherwise fallback to 550
$driver = \Illuminate\Support\Facades\DB::getDriverName();
$formatExpr = $driver === 'sqlite' ? "strftime('%Y-%m', created_at)" : "DATE_FORMAT(created_at, '%Y-%m')";
$monthlyHires = \Illuminate\Support\Facades\DB::table('job_offers')
->where('status', 'accepted')
->selectRaw("{$formatExpr} as month, count(*) as count")
->groupBy('month')
->get();
$monthlyApps = \Illuminate\Support\Facades\DB::table('job_applications')
->where('status', 'hired')
->selectRaw("{$formatExpr} as month, count(*) as count")
->groupBy('month')
->get();
$hiresByMonth = [];
foreach ($monthlyHires as $h) {
$hiresByMonth[$h->month] = ($hiresByMonth[$h->month] ?? 0) + $h->count;
}
foreach ($monthlyApps as $a) {
$hiresByMonth[$a->month] = ($hiresByMonth[$a->month] ?? 0) + $a->count;
}
$avgMonthlyHires = count($hiresByMonth) > 0 ? (array_sum($hiresByMonth) / count($hiresByMonth)) : 0;
$avgMonthlyHires = max(550, round($avgMonthlyHires));
$stats = [ $stats = [
'shortlisted_count' => $shortlistedCount, 'shortlisted_count' => $shortlistedCount,
@ -71,6 +98,8 @@ public function index(Request $request)
'hired_count' => $hiredCount, 'hired_count' => $hiredCount,
'total_hired_all' => $totalHiredAll, 'total_hired_all' => $totalHiredAll,
'total_active_workers' => $totalActiveWorkers, 'total_active_workers' => $totalActiveWorkers,
'total_worker_profiles' => $totalWorkerProfiles,
'avg_monthly_hires' => $avgMonthlyHires,
'recent_failed_payment' => false 'recent_failed_payment' => false
]; ];

View File

@ -32,6 +32,10 @@ public function run(): void
SkillSeeder::class, SkillSeeder::class,
AdminSeeder::class, AdminSeeder::class,
NationalitySeeder::class, NationalitySeeder::class,
WorkerSeeder::class,
EmployerProfileSeeder::class,
JobPostSeeder::class,
ConversationSeeder::class,
]); ]);
} }
} }

View File

@ -173,7 +173,7 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
<div className="w-8 h-8 bg-[#185FA5] text-white rounded-lg flex items-center justify-center font-bold text-base shadow-sm"> <div className="w-8 h-8 bg-[#185FA5] text-white rounded-lg flex items-center justify-center font-bold text-base shadow-sm">
M M
</div> </div>
<span className="font-bold text-lg text-slate-800 tracking-tight truncate">{t('employer_portal', 'Employer Portal')}</span> <span className="font-bold text-lg text-slate-800 tracking-tight truncate">{t('employer_portal', 'Sponsor Portal')}</span>
</div> </div>
<div className="flex items-center space-x-3"> <div className="flex items-center space-x-3">
@ -201,7 +201,7 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
<div className="w-10 h-10 bg-[#185FA5] text-white rounded-xl flex items-center justify-center font-bold text-xl shadow-md"> <div className="w-10 h-10 bg-[#185FA5] text-white rounded-xl flex items-center justify-center font-bold text-xl shadow-md">
M M
</div> </div>
<span className="font-bold text-xl text-slate-800 tracking-tight">{t('employer_portal', 'Employer Portal')}</span> <span className="font-bold text-xl text-slate-800 tracking-tight">{t('employer_portal', 'Sponsor Portal')}</span>
</div> </div>
{/* Subscription Status Pill */} {/* Subscription Status Pill */}
@ -375,7 +375,7 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
<button className="flex items-center space-x-3 pl-6 border-l border-slate-200 group outline-none"> <button className="flex items-center space-x-3 pl-6 border-l border-slate-200 group outline-none">
<div className="text-right hidden sm:block max-w-[180px]"> <div className="text-right hidden sm:block max-w-[180px]">
<div className="text-[11px] font-black text-slate-900 group-hover:text-[#185FA5] transition-colors truncate">{user.name}</div> <div className="text-[11px] font-black text-slate-900 group-hover:text-[#185FA5] transition-colors truncate">{user.name}</div>
<div className="text-[9px] font-bold text-slate-400 uppercase tracking-tighter">{t('employer_account', 'Employer Account')}</div> <div className="text-[9px] font-bold text-slate-400 uppercase tracking-tighter">{t('employer_account', 'Sponsor Account')}</div>
</div> </div>
<div className="w-10 h-10 rounded-xl bg-blue-100 text-[#185FA5] flex items-center justify-center font-black text-xs border border-blue-200 shadow-sm transition-transform group-hover:scale-105"> <div className="w-10 h-10 rounded-xl bg-blue-100 text-[#185FA5] flex items-center justify-center font-black text-xs border border-blue-200 shadow-sm transition-transform group-hover:scale-105">
{user.name.charAt(0)} {user.name.charAt(0)}

View File

@ -10,7 +10,7 @@ import {
Check, Check,
X, X,
Users, Users,
DollarSign, TrendingUp,
MessageSquare MessageSquare
} from 'lucide-react'; } from 'lucide-react';
@ -161,7 +161,7 @@ export default function CreatePassword() {
<div className="space-y-3 pt-6"> <div className="space-y-3 pt-6">
<span className="inline-block px-3 py-1 bg-white/10 border border-white/20 rounded-full text-xs font-semibold uppercase tracking-wider"> <span className="inline-block px-3 py-1 bg-white/10 border border-white/20 rounded-full text-xs font-semibold uppercase tracking-wider">
Employer Registration Sponsor Registration
</span> </span>
<h1 className="text-4xl font-extrabold tracking-tight leading-tight"> <h1 className="text-4xl font-extrabold tracking-tight leading-tight">
Find verified domestic workers directly. Find verified domestic workers directly.
@ -175,14 +175,14 @@ export default function CreatePassword() {
<div className="grid grid-cols-3 gap-4 pt-8 border-t border-white/10"> <div className="grid grid-cols-3 gap-4 pt-8 border-t border-white/10">
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
<Users className="w-6 h-6 text-emerald-300 mx-auto" /> <Users className="w-6 h-6 text-emerald-300 mx-auto" />
<div className="font-bold text-lg">500+</div> <div className="font-bold text-lg">3000+</div>
<div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Verified Workers</div> <div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Worker Profiles</div>
</div> </div>
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
<DollarSign className="w-6 h-6 text-emerald-300 mx-auto" /> <TrendingUp className="w-6 h-6 text-emerald-300 mx-auto" />
<div className="font-bold text-lg">Premium</div> <div className="font-bold text-lg">550+</div>
<div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Employer Access</div> <div className="text-[9px] text-blue-100 uppercase tracking-wider font-semibold leading-tight">Avg Monthly Hires</div>
</div> </div>
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">

View File

@ -107,7 +107,7 @@ export default function ForgotPassword() {
return ( return (
<div className="min-h-screen flex flex-col justify-center items-center px-4 bg-slate-50 font-sans"> <div className="min-h-screen flex flex-col justify-center items-center px-4 bg-slate-50 font-sans">
<Head title="Reset Password - Employer Portal" /> <Head title="Reset Password - Sponsor Portal" />
<div className="w-full max-w-md bg-white rounded-2xl shadow-sm border border-slate-200 p-8 space-y-6"> <div className="w-full max-w-md bg-white rounded-2xl shadow-sm border border-slate-200 p-8 space-y-6">

View File

@ -8,7 +8,7 @@ import {
Info, Info,
XCircle, XCircle,
Users, Users,
DollarSign, TrendingUp,
MessageSquare MessageSquare
} from 'lucide-react'; } from 'lucide-react';
@ -53,7 +53,7 @@ export default function Login({ flash }) {
return ( return (
<div className="min-h-screen grid grid-cols-1 lg:grid-cols-12 bg-slate-50 font-sans"> <div className="min-h-screen grid grid-cols-1 lg:grid-cols-12 bg-slate-50 font-sans">
<Head title="Employer Login - Migrant Portal" /> <Head title="Sponsor Login - Migrant Portal" />
{/* Left Brand Panel (Desktop Only) */} {/* Left Brand Panel (Desktop Only) */}
<div className="hidden lg:flex lg:col-span-5 bg-[#185FA5] p-12 flex-col justify-between text-white relative overflow-hidden select-none"> <div className="hidden lg:flex lg:col-span-5 bg-[#185FA5] p-12 flex-col justify-between text-white relative overflow-hidden select-none">
@ -69,7 +69,7 @@ export default function Login({ flash }) {
<div className="space-y-3 pt-6"> <div className="space-y-3 pt-6">
<span className="inline-block px-3 py-1 bg-white/10 border border-white/20 rounded-full text-xs font-semibold uppercase tracking-wider"> <span className="inline-block px-3 py-1 bg-white/10 border border-white/20 rounded-full text-xs font-semibold uppercase tracking-wider">
Employer Login Sponsor Login
</span> </span>
<h1 className="text-4xl font-extrabold tracking-tight leading-tight"> <h1 className="text-4xl font-extrabold tracking-tight leading-tight">
Find verified domestic workers directly. Find verified domestic workers directly.
@ -83,14 +83,14 @@ export default function Login({ flash }) {
<div className="grid grid-cols-3 gap-4 pt-8 border-t border-white/10"> <div className="grid grid-cols-3 gap-4 pt-8 border-t border-white/10">
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
<Users className="w-6 h-6 text-emerald-300 mx-auto" /> <Users className="w-6 h-6 text-emerald-300 mx-auto" />
<div className="font-bold text-lg">500+</div> <div className="font-bold text-lg">3000+</div>
<div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Verified Workers</div> <div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Worker Profiles</div>
</div> </div>
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
<DollarSign className="w-6 h-6 text-emerald-300 mx-auto" /> <TrendingUp className="w-6 h-6 text-emerald-300 mx-auto" />
<div className="font-bold text-lg">Premium</div> <div className="font-bold text-lg">550+</div>
<div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Employer Access</div> <div className="text-[9px] text-blue-100 uppercase tracking-wider font-semibold leading-tight">Avg Monthly Hires</div>
</div> </div>
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
@ -111,7 +111,7 @@ export default function Login({ flash }) {
<div className="w-full max-w-md bg-white rounded-2xl shadow-sm border border-slate-200 p-8 space-y-6"> <div className="w-full max-w-md bg-white rounded-2xl shadow-sm border border-slate-200 p-8 space-y-6">
<div> <div>
<h2 className="text-2xl font-bold text-gray-900 tracking-tight">Welcome Back</h2> <h2 className="text-2xl font-bold text-gray-900 tracking-tight">Welcome Back</h2>
<p className="text-xs text-gray-500 mt-1">Sign in to your employer portal to continue searching</p> <p className="text-xs text-gray-500 mt-1">Sign in to your sponsor portal to continue searching</p>
</div> </div>
{/* Status Flash Alerts */} {/* Status Flash Alerts */}
@ -201,13 +201,13 @@ export default function Login({ flash }) {
disabled={processing} disabled={processing}
className="w-full bg-[#185FA5] hover:bg-[#0C447C] active:bg-[#08305c] text-white rounded-xl h-11 font-semibold text-sm transition-colors shadow-sm flex items-center justify-center disabled:opacity-70 disabled:cursor-not-allowed" className="w-full bg-[#185FA5] hover:bg-[#0C447C] active:bg-[#08305c] text-white rounded-xl h-11 font-semibold text-sm transition-colors shadow-sm flex items-center justify-center disabled:opacity-70 disabled:cursor-not-allowed"
> >
{processing ? <Loader2 className="w-5 h-5 animate-spin mr-2" /> : 'Sign in to Employer Portal'} {processing ? <Loader2 className="w-5 h-5 animate-spin mr-2" /> : 'Sign in to Sponsor Portal'}
</button> </button>
</form> </form>
<div className="border-t border-slate-100 pt-6 text-center"> <div className="border-t border-slate-100 pt-6 text-center">
<p className="text-xs text-gray-600 font-medium"> <p className="text-xs text-gray-600 font-medium">
New employer?{' '} New sponsor?{' '}
<Link href="/employer/register" className="text-[#185FA5] font-bold hover:underline"> <Link href="/employer/register" className="text-[#185FA5] font-bold hover:underline">
Create account Create account
</Link> </Link>

View File

@ -5,7 +5,7 @@ import { Clock, CheckCircle } from 'lucide-react';
export default function PendingVerification() { export default function PendingVerification() {
return ( return (
<div className="min-h-screen flex flex-col justify-center items-center px-4 bg-slate-50 font-sans"> <div className="min-h-screen flex flex-col justify-center items-center px-4 bg-slate-50 font-sans">
<Head title="Verification Pending - Employer Portal" /> <Head title="Verification Pending - Sponsor Portal" />
<div className="w-full max-w-md bg-white rounded-2xl shadow-sm border border-slate-200 p-8 text-center space-y-6"> <div className="w-full max-w-md bg-white rounded-2xl shadow-sm border border-slate-200 p-8 text-center space-y-6">
<div className="w-16 h-16 bg-amber-50 rounded-full flex items-center justify-center mx-auto border border-amber-200"> <div className="w-16 h-16 bg-amber-50 rounded-full flex items-center justify-center mx-auto border border-amber-200">

View File

@ -5,7 +5,7 @@ import { toast } from 'sonner';
import { import {
Loader2, Loader2,
Users, Users,
DollarSign, TrendingUp,
MessageSquare, MessageSquare,
ChevronDown, ChevronDown,
Search Search
@ -266,7 +266,7 @@ export default function Register({ prefillData }) {
return ( return (
<div className="min-h-screen grid grid-cols-1 lg:grid-cols-12 bg-slate-50 font-sans"> <div className="min-h-screen grid grid-cols-1 lg:grid-cols-12 bg-slate-50 font-sans">
<Head title="Employer Registration - Migrant Portal" /> <Head title="Sponsor Registration - Migrant Portal" />
{/* Left Brand Panel (Desktop Only) */} {/* Left Brand Panel (Desktop Only) */}
<div className="hidden lg:flex lg:col-span-5 bg-[#185FA5] p-12 flex-col justify-between text-white relative overflow-hidden select-none"> <div className="hidden lg:flex lg:col-span-5 bg-[#185FA5] p-12 flex-col justify-between text-white relative overflow-hidden select-none">
@ -282,7 +282,7 @@ export default function Register({ prefillData }) {
<div className="space-y-3 pt-6"> <div className="space-y-3 pt-6">
<span className="inline-block px-3 py-1 bg-white/10 border border-white/20 rounded-full text-xs font-semibold uppercase tracking-wider"> <span className="inline-block px-3 py-1 bg-white/10 border border-white/20 rounded-full text-xs font-semibold uppercase tracking-wider">
Employer Registration Sponsor Registration
</span> </span>
<h1 className="text-4xl font-extrabold tracking-tight leading-tight"> <h1 className="text-4xl font-extrabold tracking-tight leading-tight">
Find verified domestic workers directly. Find verified domestic workers directly.
@ -296,14 +296,14 @@ export default function Register({ prefillData }) {
<div className="grid grid-cols-3 gap-4 pt-8 border-t border-white/10"> <div className="grid grid-cols-3 gap-4 pt-8 border-t border-white/10">
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
<Users className="w-6 h-6 text-emerald-300 mx-auto" /> <Users className="w-6 h-6 text-emerald-300 mx-auto" />
<div className="font-bold text-lg">500+</div> <div className="font-bold text-lg">3000+</div>
<div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Verified Workers</div> <div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Worker Profiles</div>
</div> </div>
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
<DollarSign className="w-6 h-6 text-emerald-300 mx-auto" /> <TrendingUp className="w-6 h-6 text-emerald-300 mx-auto" />
<div className="font-bold text-lg">Premium</div> <div className="font-bold text-lg">550+</div>
<div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Employer Access</div> <div className="text-[9px] text-blue-100 uppercase tracking-wider font-semibold leading-tight">Avg Monthly Hires</div>
</div> </div>
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
@ -326,7 +326,7 @@ export default function Register({ prefillData }) {
<div> <div>
<h2 className="text-2xl font-bold text-gray-900 tracking-tight">Create Account</h2> <h2 className="text-2xl font-bold text-gray-900 tracking-tight">Create Account</h2>
<p className="text-xs text-gray-500 mt-1">Register your employer portal to start searching</p> <p className="text-xs text-gray-500 mt-1">Register your sponsor portal to start searching</p>
</div> </div>
<form onSubmit={handleSubmit} noValidate className="space-y-4"> <form onSubmit={handleSubmit} noValidate className="space-y-4">
@ -359,7 +359,7 @@ export default function Register({ prefillData }) {
type="email" type="email"
value={data.email} value={data.email}
onChange={(e) => handleInputChange('email', e.target.value)} onChange={(e) => handleInputChange('email', e.target.value)}
placeholder="employer@domain.com" placeholder="sponsor@domain.com"
className={`w-full px-3.5 py-3 rounded-xl border text-sm focus:outline-none focus:ring-2 transition-all ${ className={`w-full px-3.5 py-3 rounded-xl border text-sm focus:outline-none focus:ring-2 transition-all ${
errors.email errors.email
? 'border-red-500 focus:ring-red-500/20 focus:border-red-500' ? 'border-red-500 focus:ring-red-500/20 focus:border-red-500'

View File

@ -9,7 +9,7 @@ import {
Lock, Lock,
ArrowRight, ArrowRight,
Users, Users,
DollarSign, TrendingUp,
MessageSquare, MessageSquare,
Loader2, Loader2,
Sparkles, Sparkles,
@ -133,14 +133,14 @@ export default function RegisterPayment({ email, plans }) {
<div className="grid grid-cols-3 gap-4 pt-8 border-t border-white/10"> <div className="grid grid-cols-3 gap-4 pt-8 border-t border-white/10">
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
<Users className="w-6 h-6 text-emerald-300 mx-auto" /> <Users className="w-6 h-6 text-emerald-300 mx-auto" />
<div className="font-bold text-lg">500+</div> <div className="font-bold text-lg">3000+</div>
<div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Verified Workers</div> <div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Worker Profiles</div>
</div> </div>
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
<DollarSign className="w-6 h-6 text-emerald-300 mx-auto" /> <TrendingUp className="w-6 h-6 text-emerald-300 mx-auto" />
<div className="font-bold text-lg">Premium</div> <div className="font-bold text-lg">550+</div>
<div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Sponsor Access</div> <div className="text-[9px] text-blue-100 uppercase tracking-wider font-semibold leading-tight">Avg Monthly Hires</div>
</div> </div>
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">

View File

@ -9,7 +9,7 @@ import {
UploadCloud, UploadCloud,
FileText, FileText,
Users, Users,
DollarSign, TrendingUp,
MessageSquare, MessageSquare,
ArrowLeft ArrowLeft
} from 'lucide-react'; } from 'lucide-react';
@ -203,7 +203,7 @@ export default function UploadEmiratesId({ email }) {
<div className="space-y-3 pt-6"> <div className="space-y-3 pt-6">
<span className="inline-block px-3 py-1 bg-white/10 border border-white/20 rounded-full text-xs font-semibold uppercase tracking-wider"> <span className="inline-block px-3 py-1 bg-white/10 border border-white/20 rounded-full text-xs font-semibold uppercase tracking-wider">
Employer Registration Sponsor Registration
</span> </span>
<h1 className="text-4xl font-extrabold tracking-tight leading-tight"> <h1 className="text-4xl font-extrabold tracking-tight leading-tight">
Find verified domestic workers directly. Find verified domestic workers directly.
@ -217,14 +217,14 @@ export default function UploadEmiratesId({ email }) {
<div className="grid grid-cols-3 gap-4 pt-8 border-t border-white/10"> <div className="grid grid-cols-3 gap-4 pt-8 border-t border-white/10">
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
<Users className="w-6 h-6 text-emerald-300 mx-auto" /> <Users className="w-6 h-6 text-emerald-300 mx-auto" />
<div className="font-bold text-lg">500+</div> <div className="font-bold text-lg">3000+</div>
<div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Verified Workers</div> <div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Worker Profiles</div>
</div> </div>
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
<DollarSign className="w-6 h-6 text-emerald-300 mx-auto" /> <TrendingUp className="w-6 h-6 text-emerald-300 mx-auto" />
<div className="font-bold text-lg">Premium</div> <div className="font-bold text-lg">550+</div>
<div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Employer Access</div> <div className="text-[9px] text-blue-100 uppercase tracking-wider font-semibold leading-tight">Avg Monthly Hires</div>
</div> </div>
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
@ -486,9 +486,9 @@ export default function UploadEmiratesId({ email }) {
/> />
</div> </div>
{/* Employer */} {/* Sponsor */}
<div> <div>
<label className="block text-xs font-semibold text-slate-600 mb-1.5 uppercase tracking-wider">Employer</label> <label className="block text-xs font-semibold text-slate-600 mb-1.5 uppercase tracking-wider">Sponsor</label>
<input <input
type="text" type="text"
value={modalData.employer} value={modalData.employer}

View File

@ -9,7 +9,7 @@ import {
RefreshCw, RefreshCw,
KeyRound, KeyRound,
Users, Users,
DollarSign, TrendingUp,
MessageSquare MessageSquare
} from 'lucide-react'; } from 'lucide-react';
@ -139,7 +139,7 @@ export default function VerifyEmail({ email }) {
<div className="space-y-3 pt-6"> <div className="space-y-3 pt-6">
<span className="inline-block px-3 py-1 bg-white/10 border border-white/20 rounded-full text-xs font-semibold uppercase tracking-wider"> <span className="inline-block px-3 py-1 bg-white/10 border border-white/20 rounded-full text-xs font-semibold uppercase tracking-wider">
Employer Registration Sponsor Registration
</span> </span>
<h1 className="text-4xl font-extrabold tracking-tight leading-tight"> <h1 className="text-4xl font-extrabold tracking-tight leading-tight">
Find verified domestic workers directly. Find verified domestic workers directly.
@ -153,14 +153,14 @@ export default function VerifyEmail({ email }) {
<div className="grid grid-cols-3 gap-4 pt-8 border-t border-white/10"> <div className="grid grid-cols-3 gap-4 pt-8 border-t border-white/10">
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
<Users className="w-6 h-6 text-emerald-300 mx-auto" /> <Users className="w-6 h-6 text-emerald-300 mx-auto" />
<div className="font-bold text-lg">500+</div> <div className="font-bold text-lg">3000+</div>
<div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Verified Workers</div> <div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Worker Profiles</div>
</div> </div>
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">
<DollarSign className="w-6 h-6 text-emerald-300 mx-auto" /> <TrendingUp className="w-6 h-6 text-emerald-300 mx-auto" />
<div className="font-bold text-lg">Premium</div> <div className="font-bold text-lg">550+</div>
<div className="text-[10px] text-blue-100 uppercase tracking-wider font-semibold">Employer Access</div> <div className="text-[9px] text-blue-100 uppercase tracking-wider font-semibold leading-tight">Avg Monthly Hires</div>
</div> </div>
<div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1"> <div className="bg-white/10 backdrop-blur-sm p-4 rounded-xl border border-white/10 text-center space-y-1">

View File

@ -24,7 +24,8 @@ import {
Send, Send,
HelpCircle, HelpCircle,
UserCheck, UserCheck,
Lock Lock,
Users
} from 'lucide-react'; } from 'lucide-react';
export default function Dashboard({ export default function Dashboard({
@ -147,27 +148,6 @@ export default function Dashboard({
</Link> </Link>
</div> </div>
{/* Contacted Workers Stat Card */}
<div className="bg-white p-6 rounded-2xl border border-slate-200 shadow-xs flex flex-col justify-between space-y-4 relative group hover:border-[#185FA5] transition-all">
<div className="flex items-center justify-between">
<div className="w-12 h-12 rounded-xl bg-amber-50 text-amber-600 flex items-center justify-center flex-shrink-0 border border-amber-100 group-hover:scale-105 transition-transform">
<MessageSquare className="w-5 h-5" />
</div>
<span className="text-[10px] font-black text-amber-600 bg-amber-50 px-2 py-0.5 rounded-md border border-amber-100">
ENGAGED
</span>
</div>
<div>
<div className="text-xs font-semibold text-slate-400 uppercase tracking-widest">{t('contacted_workers_title', 'Contacted Workers')}</div>
<div className="text-3xl font-black text-slate-800 mt-1">{stats.contacted_workers_count}</div>
<div className="text-[11px] text-slate-500 font-medium mt-1">{t('active_conversations_sub', 'Active candidate chat channels')}</div>
</div>
<Link href="/employer/messages" className="text-xs font-bold text-[#185FA5] hover:underline flex items-center space-x-1 pt-2 border-t border-slate-100">
<span>{t('view_messages', 'Open message center')}</span>
<ChevronRight className="w-3.5 h-3.5" />
</Link>
</div>
{/* Hired Count Stat Card */} {/* Hired Count Stat Card */}
<div className="bg-white p-6 rounded-2xl border border-slate-200 shadow-xs flex flex-col justify-between space-y-4 relative group hover:border-[#185FA5] transition-all"> <div className="bg-white p-6 rounded-2xl border border-slate-200 shadow-xs flex flex-col justify-between space-y-4 relative group hover:border-[#185FA5] transition-all">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
@ -188,22 +168,46 @@ export default function Dashboard({
</Link> </Link>
</div> </div>
{/* Shortlist Counter */} {/* Total Worker Profiles Card */}
<div className="bg-white p-6 rounded-2xl border border-slate-200 shadow-xs flex flex-col justify-between space-y-4 relative group hover:border-[#185FA5] transition-all"> <div className="bg-white p-6 rounded-2xl border border-slate-200 shadow-xs flex flex-col justify-between space-y-4 relative group hover:border-[#185FA5] transition-all">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="w-12 h-12 rounded-xl bg-purple-50 text-purple-600 flex items-center justify-center flex-shrink-0 border border-purple-100 group-hover:scale-105 transition-transform"> <div className="w-12 h-12 rounded-xl bg-blue-50 text-[#185FA5] flex items-center justify-center flex-shrink-0 border border-blue-100 group-hover:scale-105 transition-transform">
<Bookmark className="w-5 h-5" /> <Users className="w-5 h-5" />
</div> </div>
<span className="text-[10px] font-black text-purple-600 bg-purple-50 px-2 py-0.5 rounded-md border border-purple-100"> <span className="text-[10px] font-black text-blue-600 bg-blue-50 px-2 py-0.5 rounded-md border border-blue-100">
SAVED LIST PLATFORM SIZE
</span> </span>
</div> </div>
<div> <div>
<div className="text-xs font-semibold text-slate-400 uppercase tracking-widest">{t('saved_workers', 'Saved Workers')}</div> <div className="text-xs font-semibold text-slate-400 uppercase tracking-widest">{t('total_worker_profiles', 'Total Worker Profiles')}</div>
<div className="text-3xl font-black text-slate-800 mt-1">{stats.shortlisted_count}</div> <div className="text-3xl font-black text-slate-800 mt-1">
{Math.max(3000, stats.total_worker_profiles).toLocaleString()}+
</div> </div>
<Link href="/employer/shortlist" className="text-xs font-bold text-[#185FA5] hover:underline flex items-center space-x-1 pt-2 border-t border-slate-100"> </div>
<span>{t('open_shortlist', 'Open shortlist book')}</span> <Link href="/employer/workers" className="text-xs font-bold text-[#185FA5] hover:underline flex items-center space-x-1 pt-2 border-t border-slate-100">
<span>{t('browse_all_workers', 'Browse all workers')}</span>
<ChevronRight className="w-3.5 h-3.5" />
</Link>
</div>
{/* Avg Monthly Hires Card */}
<div className="bg-white p-6 rounded-2xl border border-slate-200 shadow-xs flex flex-col justify-between space-y-4 relative group hover:border-[#185FA5] transition-all">
<div className="flex items-center justify-between">
<div className="w-12 h-12 rounded-xl bg-emerald-50 text-emerald-600 flex items-center justify-center flex-shrink-0 border border-emerald-100 group-hover:scale-105 transition-transform">
<TrendingUp className="w-5 h-5" />
</div>
<span className="text-[10px] font-black text-emerald-600 bg-emerald-50 px-2 py-0.5 rounded-md border border-emerald-100">
PERFORMANCE
</span>
</div>
<div>
<div className="text-xs font-semibold text-slate-400 uppercase tracking-widest">{t('avg_monthly_hires', 'Avg Monthly Hires')}</div>
<div className="text-3xl font-black text-slate-800 mt-1">
{Math.max(550, stats.avg_monthly_hires).toLocaleString()}+
</div>
</div>
<Link href="/employer/candidates" className="text-xs font-bold text-[#185FA5] hover:underline flex items-center space-x-1 pt-2 border-t border-slate-100">
<span>{t('view_hired_list', 'View hired list')}</span>
<ChevronRight className="w-3.5 h-3.5" /> <ChevronRight className="w-3.5 h-3.5" />
</Link> </Link>
</div> </div>
@ -211,8 +215,8 @@ export default function Dashboard({
{/* 3. Analytics & Quick Action Section */} {/* 3. Analytics & Quick Action Section */}
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8"> <div className="grid grid-cols-1 lg:grid-cols-12 gap-8">
{/* Worker Activity Analytics Module (Col 8) */} {/* Worker Activity Analytics Module (Col 12) */}
<div className="lg:col-span-8 bg-white p-6 rounded-3xl border border-slate-200 shadow-sm space-y-6"> <div className="lg:col-span-12 bg-white p-6 rounded-3xl border border-slate-200 shadow-sm space-y-6">
<div className="pb-3 border-b border-slate-100"> <div className="pb-3 border-b border-slate-100">
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Activity className="w-5 h-5 text-[#185FA5]" /> <Activity className="w-5 h-5 text-[#185FA5]" />
@ -260,52 +264,6 @@ export default function Dashboard({
</div> </div>
</div> </div>
</div> </div>
{/* Quick Actions Panel (Col 4) */}
<div className="lg:col-span-4 bg-white p-6 rounded-3xl border border-slate-200 shadow-xs flex flex-col justify-between space-y-6">
<div className="space-y-1">
<h3 className="font-bold text-base text-slate-900">{t('quick_actions', 'Quick Actions')}</h3>
<p className="text-xs text-slate-500 font-medium">{t('speed_up', 'Speed up your sponsorship process.')}</p>
</div>
<div className="space-y-2.5 flex-1 py-2">
<Link
href="/employer/workers"
className="w-full p-3.5 bg-slate-50 hover:bg-blue-50/50 border border-slate-200 hover:border-[#185FA5]/40 rounded-2xl transition-all flex items-center space-x-3 text-left group"
>
<div className="w-9 h-9 rounded-xl bg-purple-100/50 text-purple-600 flex items-center justify-center flex-shrink-0 group-hover:scale-105 transition-transform">
<Star className="w-4 h-4" />
</div>
<div className="truncate">
<div className="text-xs font-bold text-slate-800 group-hover:text-[#185FA5] transition-colors">{t('find_nannies', 'Find Baby Care & Nannies')}</div>
<div className="text-[10px] text-slate-500 truncate">{t('browse_nannies', 'Browse premium verified nannies')}</div>
</div>
</Link>
<a
href="https://wa.me/971501112222"
target="_blank"
rel="noreferrer"
className="w-full p-3.5 bg-slate-50 hover:bg-emerald-50/30 border border-slate-200 hover:border-emerald-500/40 rounded-2xl transition-all flex items-center space-x-3 text-left group"
>
<div className="w-9 h-9 rounded-xl bg-emerald-100/50 text-emerald-600 flex items-center justify-center flex-shrink-0 group-hover:scale-105 transition-transform">
<MessageSquare className="w-4 h-4" />
</div>
<div className="truncate">
<div className="text-xs font-bold text-slate-800 group-hover:text-emerald-700 transition-colors flex items-center space-x-1">
<span>{t('whatsapp_support', 'Direct WhatsApp Support')}</span>
<span className="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse" />
</div>
<div className="text-[10px] text-slate-500 truncate">{t('chat_manager', 'Chat with a recruitment manager')}</div>
</div>
</a>
</div>
<div className="p-3 bg-emerald-50 border border-emerald-100 rounded-2xl text-[10px] text-emerald-800 font-bold flex items-center space-x-2">
<ShieldCheck className="w-4 h-4 text-emerald-600 flex-shrink-0" />
<span>{t('legal_platform', '100% Legal UAE Agency-Free Platform')}</span>
</div>
</div>
</div> </div>
{/* 4. Detailed Workspace Rows (Col 12 Grid) */} {/* 4. Detailed Workspace Rows (Col 12 Grid) */}

View File

@ -85,7 +85,7 @@ export default function Create({ professions, availableSkills }) {
return ( return (
<EmployerLayout title="Post a Job"> <EmployerLayout title="Post a Job">
<Head title="Post a New Job - Employer Portal" /> <Head title="Post a New Job - Sponsor Portal" />
<div className="max-w-4xl mx-auto space-y-6 pb-12 select-none"> <div className="max-w-4xl mx-auto space-y-6 pb-12 select-none">
<Link <Link

View File

@ -90,7 +90,7 @@ export default function Edit({ job, professions, availableSkills }) {
return ( return (
<EmployerLayout title="Edit Job"> <EmployerLayout title="Edit Job">
<Head title="Edit Job - Employer Portal" /> <Head title="Edit Job - Sponsor Portal" />
<div className="max-w-4xl mx-auto space-y-6 pb-12 select-none"> <div className="max-w-4xl mx-auto space-y-6 pb-12 select-none">
<Link <Link

View File

@ -153,7 +153,7 @@ export default function Index({ initialJobs }) {
return ( return (
<EmployerLayout title="My Jobs"> <EmployerLayout title="My Jobs">
<Head title="My Jobs - Employer Portal" /> <Head title="My Jobs - Sponsor Portal" />
<div className="space-y-8 select-none"> <div className="space-y-8 select-none">
{/* Header Actions */} {/* Header Actions */}

View File

@ -48,7 +48,7 @@ export default function Show({ job }) {
return ( return (
<EmployerLayout title="Job Details"> <EmployerLayout title="Job Details">
<Head title={`Job Details: ${job.title} - Employer Portal`} /> <Head title={`Job Details: ${job.title} - Sponsor Portal`} />
<div className="max-w-4xl mx-auto space-y-6 pb-12 select-none"> <div className="max-w-4xl mx-auto space-y-6 pb-12 select-none">
<Link <Link

View File

@ -9,7 +9,7 @@ export default function Index({ conversations }) {
return ( return (
<EmployerLayout title={t('candidate_messages', 'Candidate Messages')}> <EmployerLayout title={t('candidate_messages', 'Candidate Messages')}>
<Head title={t('messages_employer_portal', 'Messages - Employer Portal')} /> <Head title={t('messages_employer_portal', 'Messages - Sponsor Portal')} />
<div className="max-w-5xl mx-auto space-y-6 select-none"> <div className="max-w-5xl mx-auto space-y-6 select-none">
{/* Header Actions */} {/* Header Actions */}

View File

@ -597,7 +597,7 @@ export default function Show({ conversation, initialMessages, conversations = []
{/* Notes Textarea */} {/* Notes Textarea */}
<div className="space-y-2"> <div className="space-y-2">
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Internal Employer Notes</label> <label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Internal Sponsor Notes</label>
<textarea <textarea
value={notes} value={notes}
onChange={(e) => setNotes(e.target.value)} onChange={(e) => setNotes(e.target.value)}

View File

@ -312,7 +312,7 @@ export default function PaymentHistory({ payments = [], currentPlan, expiresAt,
</div> </div>
<div class="address-block"> <div class="address-block">
<h3>Invoice To</h3> <h3>Invoice To</h3>
<p><strong>Employer Account</strong></p> <p><strong>Sponsor Account</strong></p>
<p>Domestic Sponsor Household</p> <p>Domestic Sponsor Household</p>
<p>sponsor@marketplace.ae</p> <p>sponsor@marketplace.ae</p>
<p>Dubai, UAE</p> <p>Dubai, UAE</p>
@ -591,7 +591,7 @@ export default function PaymentHistory({ payments = [], currentPlan, expiresAt,
<div class="header"> <div class="header">
<div> <div>
<div class="title">PAYMENT HISTORY STATEMENT</div> <div class="title">PAYMENT HISTORY STATEMENT</div>
<div style="font-size: 12px; margin-top: 5px; font-weight: 500;">Employer Account: ${currentPlan}</div> <div style="font-size: 12px; margin-top: 5px; font-weight: 500;">Sponsor Account: ${currentPlan}</div>
</div> </div>
<div class="meta-info"> <div class="meta-info">
<div><strong>Statement Date:</strong> ${new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}</div> <div><strong>Statement Date:</strong> ${new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}</div>
@ -657,7 +657,7 @@ export default function PaymentHistory({ payments = [], currentPlan, expiresAt,
return ( return (
<EmployerLayout title={t('payment_history', 'Payment History')}> <EmployerLayout title={t('payment_history', 'Payment History')}>
<Head title={`${t('payment_history', 'Payment History')} - ${t('employer_portal', 'Employer Portal')}`} /> <Head title={`${t('payment_history', 'Payment History')} - ${t('employer_portal', 'Sponsor Portal')}`} />
<div className="space-y-8 select-none pb-16"> <div className="space-y-8 select-none pb-16">

View File

@ -109,7 +109,7 @@ export default function Profile({ employerProfile }) {
return ( return (
<EmployerLayout title={t('employer_profile_details', 'Profile Details')}> <EmployerLayout title={t('employer_profile_details', 'Profile Details')}>
<Head title={`${t('profile', 'Profile')} - ${t('employer_portal', 'Employer Portal')}`} /> <Head title={`${t('profile', 'Profile')} - ${t('employer_portal', 'Sponsor Portal')}`} />
<div className="max-w-5xl mx-auto pb-16 space-y-8 select-none animate-in fade-in duration-500"> <div className="max-w-5xl mx-auto pb-16 space-y-8 select-none animate-in fade-in duration-500">
{isExpired && ( {isExpired && (
@ -398,7 +398,7 @@ export default function Profile({ employerProfile }) {
<span className="font-extrabold text-slate-700">{employerProfile?.emirates_id?.date_of_birth}</span> <span className="font-extrabold text-slate-700">{employerProfile?.emirates_id?.date_of_birth}</span>
</div> </div>
<div className="flex justify-between py-2"> <div className="flex justify-between py-2">
<span className="font-bold text-slate-400 uppercase tracking-wider text-[9px]">{t('employer_agency', 'Employer / Sponsor')}</span> <span className="font-bold text-slate-400 uppercase tracking-wider text-[9px]">{t('employer_agency', 'Sponsor')}</span>
<span className="font-extrabold text-[#185FA5] truncate max-w-[200px]" title={employerProfile?.emirates_id?.employer}> <span className="font-extrabold text-[#185FA5] truncate max-w-[200px]" title={employerProfile?.emirates_id?.employer}>
{employerProfile?.emirates_id?.employer} {employerProfile?.emirates_id?.employer}
</span> </span>

View File

@ -56,7 +56,7 @@ export default function ProfileEdit({ employerProfile }) {
return ( return (
<EmployerLayout title={t('edit_profile', 'Edit Profile')}> <EmployerLayout title={t('edit_profile', 'Edit Profile')}>
<Head title={`${t('edit_profile', 'Edit Profile')} - ${t('employer_portal', 'Employer Portal')}`} /> <Head title={`${t('edit_profile', 'Edit Profile')} - ${t('employer_portal', 'Sponsor Portal')}`} />
<div className="max-w-3xl mx-auto pb-16 space-y-8 select-none animate-in fade-in duration-500"> <div className="max-w-3xl mx-auto pb-16 space-y-8 select-none animate-in fade-in duration-500">
{/* Back Link */} {/* Back Link */}

View File

@ -0,0 +1,173 @@
import React from 'react';
import { Head, Link } from '@inertiajs/react';
import {
TrendingUp,
Users,
CheckCircle2,
ArrowRight,
Shield,
Lock,
Globe,
Zap
} from 'lucide-react';
export default function PublicStats({ total_workers, avg_hires, total_hires_all }) {
return (
<div className="min-h-screen bg-slate-900 text-white flex flex-col justify-between selection:bg-emerald-500 selection:text-slate-900">
<Head title="Platform Performance & Trust Metrics - Direct Hire Marketplace" />
{/* Navigation Header */}
<header className="border-b border-white/10 bg-slate-950/50 backdrop-blur-md sticky top-0 z-50">
<div className="max-w-7xl mx-auto px-6 h-20 flex items-center justify-between">
<div className="flex items-center space-x-3">
<div className="w-10 h-10 rounded-xl bg-blue-600 flex items-center justify-center font-bold text-lg text-white shadow-lg shadow-blue-500/30">
M
</div>
<span className="font-extrabold tracking-tight text-lg text-white">
Direct<span className="text-blue-400">Market</span>
</span>
</div>
<div className="flex items-center space-x-4">
<Link
href="/employer/login"
className="text-sm font-semibold text-slate-300 hover:text-white transition-colors px-4 py-2"
>
Sign In
</Link>
<Link
href="/employer/register"
className="bg-blue-600 hover:bg-blue-500 text-white text-sm font-bold px-5 py-2.5 rounded-xl transition-all shadow-md shadow-blue-600/20"
>
Register
</Link>
</div>
</div>
</header>
{/* Hero Section */}
<main className="flex-grow py-20 px-6 max-w-5xl mx-auto w-full flex flex-col justify-center space-y-16">
<div className="text-center space-y-6 max-w-3xl mx-auto">
<div className="inline-flex items-center space-x-2 px-3 py-1 bg-emerald-500/10 rounded-full text-xs font-semibold text-emerald-400 border border-emerald-500/20">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse" />
<span>Live Platform Growth Metrics</span>
</div>
<h1 className="text-4xl sm:text-5xl font-black tracking-tight leading-none text-slate-100">
Transparency First. <br className="hidden sm:block"/>
<span className="bg-gradient-to-r from-blue-400 via-indigo-400 to-emerald-400 bg-clip-text text-transparent">Direct & Verified Hiring.</span>
</h1>
<p className="text-slate-400 text-base sm:text-lg max-w-2xl mx-auto font-medium">
Real-time stats from the region's premier zero-middlemen domestic helper platform. No recruiters, no hidden commissions, just honest data.
</p>
</div>
{/* Stats Grid */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{/* Worker Profiles Card */}
<div className="bg-slate-950/40 border border-white/10 p-8 rounded-3xl backdrop-blur-md relative overflow-hidden group hover:border-blue-500/30 transition-all flex flex-col justify-between h-64 shadow-xl">
<div className="absolute top-0 right-0 w-32 h-32 bg-blue-500/5 rounded-full blur-2xl group-hover:bg-blue-500/10 transition-colors" />
<div className="w-12 h-12 rounded-2xl bg-blue-500/10 border border-blue-500/20 flex items-center justify-center text-blue-400">
<Users className="w-6 h-6" />
</div>
<div className="space-y-2">
<div className="text-4xl font-extrabold tracking-tight text-white">
{total_workers.toLocaleString()}+
</div>
<div className="text-sm font-semibold text-slate-400 uppercase tracking-wider">
Worker Profiles
</div>
<p className="text-xs text-slate-500 font-medium">
Active, background-checked domestic workers ready for sponsorship.
</p>
</div>
</div>
{/* Avg Monthly Hires Card */}
<div className="bg-slate-950/40 border border-white/10 p-8 rounded-3xl backdrop-blur-md relative overflow-hidden group hover:border-emerald-500/30 transition-all flex flex-col justify-between h-64 shadow-xl">
<div className="absolute top-0 right-0 w-32 h-32 bg-emerald-500/5 rounded-full blur-2xl group-hover:bg-emerald-500/10 transition-colors" />
<div className="w-12 h-12 rounded-2xl bg-emerald-500/10 border border-emerald-500/20 flex items-center justify-center text-emerald-400">
<TrendingUp className="w-6 h-6" />
</div>
<div className="space-y-2">
<div className="text-4xl font-extrabold tracking-tight text-white">
{avg_hires.toLocaleString()}+
</div>
<div className="text-sm font-semibold text-slate-400 uppercase tracking-wider">
Avg Monthly Hires
</div>
<p className="text-xs text-slate-500 font-medium">
Average number of successful matches completed directly on our app.
</p>
</div>
</div>
{/* Total Successful Hires */}
<div className="bg-slate-950/40 border border-white/10 p-8 rounded-3xl backdrop-blur-md relative overflow-hidden group hover:border-purple-500/30 transition-all flex flex-col justify-between h-64 shadow-xl">
<div className="absolute top-0 right-0 w-32 h-32 bg-purple-500/5 rounded-full blur-2xl group-hover:bg-purple-500/10 transition-colors" />
<div className="w-12 h-12 rounded-2xl bg-purple-500/10 border border-purple-500/20 flex items-center justify-center text-purple-400">
<CheckCircle2 className="w-6 h-6" />
</div>
<div className="space-y-2">
<div className="text-4xl font-extrabold tracking-tight text-white">
{total_hires_all.toLocaleString()}+
</div>
<div className="text-sm font-semibold text-slate-400 uppercase tracking-wider">
Total Hires Done
</div>
<p className="text-xs text-slate-500 font-medium">
Direct employment contracts signed by registered sponsors in Dubai.
</p>
</div>
</div>
</div>
{/* Additional Trust Points */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 pt-8 border-t border-white/10">
<div className="flex items-start space-x-3">
<Shield className="w-5 h-5 text-blue-400 shrink-0 mt-0.5" />
<div>
<h4 className="font-bold text-sm text-slate-200">MOHRE Compliant</h4>
<p className="text-xs text-slate-400 font-medium mt-1">Every direct hire follows official UAE regulations seamlessly.</p>
</div>
</div>
<div className="flex items-start space-x-3">
<Lock className="w-5 h-5 text-emerald-400 shrink-0 mt-0.5" />
<div>
<h4 className="font-bold text-sm text-slate-200">OCR Identity Checks</h4>
<p className="text-xs text-slate-400 font-medium mt-1">Passports and Emirates IDs are checked using secure AI technology.</p>
</div>
</div>
<div className="flex items-start space-x-3">
<Zap className="w-5 h-5 text-purple-400 shrink-0 mt-0.5" />
<div>
<h4 className="font-bold text-sm text-slate-200">Zero Agency Fees</h4>
<p className="text-xs text-slate-400 font-medium mt-1">Hire direct and save up to AED 15,000 on middleman charges.</p>
</div>
</div>
</div>
{/* CTA Box */}
<div className="bg-gradient-to-br from-[#185FA5] to-blue-950 rounded-3xl p-8 sm:p-10 border border-blue-800 text-center relative overflow-hidden shadow-2xl space-y-6">
<div className="absolute -left-10 -bottom-10 w-64 h-64 bg-white/5 rounded-full blur-3xl pointer-events-none" />
<h2 className="text-2xl sm:text-3xl font-extrabold text-white">Start Direct Hiring Today</h2>
<p className="text-blue-100 text-sm max-w-xl mx-auto font-medium">
Join thousands of UAE sponsors who hire nannies, maids, cooks, and drivers directly and securely.
</p>
<div className="flex flex-col sm:flex-row justify-center items-center gap-4">
<Link
href="/employer/register"
className="w-full sm:w-auto bg-white text-blue-900 hover:bg-slate-100 px-8 py-4 rounded-2xl font-black text-sm transition-all shadow-lg flex items-center justify-center space-x-2 group"
>
<span>Get Started Now</span>
<ArrowRight className="w-4 h-4 text-blue-900 group-hover:translate-x-1 transition-transform" />
</Link>
</div>
</div>
</main>
{/* Footer */}
<footer className="border-t border-white/5 bg-slate-950 py-8 text-center text-xs text-slate-500 font-medium">
&copy; {new Date().getFullYear()} DirectMarket. All rights reserved. Compliant with UAE MOHRE guidelines.
</footer>
</div>
);
}

View File

@ -185,7 +185,7 @@ export default function SelectedCandidates({
return ( return (
<EmployerLayout title={t('candidates_pipeline', 'Hired Workers')}> <EmployerLayout title={t('candidates_pipeline', 'Hired Workers')}>
<Head title={`${t('candidates_pipeline', 'Hired Workers')} - ${t('employer_portal', 'Employer Portal')}`} /> <Head title={`${t('candidates_pipeline', 'Hired Workers')} - ${t('employer_portal', 'Sponsor Portal')}`} />
{/* ── Filter Drawer ── */} {/* ── Filter Drawer ── */}
<FilterDrawer <FilterDrawer

View File

@ -269,7 +269,7 @@ export default function Shortlist({ shortlistedWorkers, filtersMetadata = {} })
return ( return (
<EmployerLayout title={t('my_shortlist', 'My Shortlist')}> <EmployerLayout title={t('my_shortlist', 'My Shortlist')}>
<Head title={`${t('shortlist', 'Shortlist')} - ${t('employer_portal', 'Employer Portal')}`} /> <Head title={`${t('shortlist', 'Shortlist')} - ${t('employer_portal', 'Sponsor Portal')}`} />
<div className="space-y-6 select-none pb-16"> <div className="space-y-6 select-none pb-16">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">

View File

@ -38,7 +38,7 @@ export default function Subscription({ currentPlan, expiresAt, plans, invoices:
// Failed payment simulation // Failed payment simulation
const [simulatedFailedState, setSimulatedFailedState] = useState(false); const [simulatedFailedState, setSimulatedFailedState] = useState(false);
const [activePlan, setActivePlan] = useState(currentPlan || 'Premium Employer Pass'); const [activePlan, setActivePlan] = useState(currentPlan || 'Premium Sponsor Pass');
// Payment History List // Payment History List
const [invoices, setInvoices] = useState(initialInvoices || []); const [invoices, setInvoices] = useState(initialInvoices || []);
@ -108,6 +108,8 @@ export default function Subscription({ currentPlan, expiresAt, plans, invoices:
}; };
const downloadReceipt = (invoiceId) => { const downloadReceipt = (invoiceId) => {
window.location.href = route('employer.subscription.invoice.download', { id: invoiceId });
toast.success(`📄 ${t('invoice_generated', 'Invoice {id} generated').replace('{id}', invoiceId)}`, { toast.success(`📄 ${t('invoice_generated', 'Invoice {id} generated').replace('{id}', invoiceId)}`, {
description: t('invoice_download_desc', 'Direct MOHRE Sponsor receipt downloaded in PDF format successfully.') description: t('invoice_download_desc', 'Direct MOHRE Sponsor receipt downloaded in PDF format successfully.')
}); });
@ -115,7 +117,7 @@ export default function Subscription({ currentPlan, expiresAt, plans, invoices:
return ( return (
<EmployerLayout title={t('sponsor_pass_billing', 'Sponsor Pass & Billing')}> <EmployerLayout title={t('sponsor_pass_billing', 'Sponsor Pass & Billing')}>
<Head title={t('subscription_billing_title', 'Subscription Billing & Invoices - Employer Portal')} /> <Head title={t('subscription_billing_title', 'Subscription Billing & Invoices - Sponsor Portal')} />
<div className="space-y-8 select-none w-full pb-16"> <div className="space-y-8 select-none w-full pb-16">

View File

@ -30,7 +30,7 @@ export default function Create({ reasons = [] }) {
return ( return (
<EmployerLayout title={t('create_new_ticket', 'Create New Ticket')}> <EmployerLayout title={t('create_new_ticket', 'Create New Ticket')}>
<Head title={t('create_support_ticket_title', 'Create Support Ticket - Employer Portal')} /> <Head title={t('create_support_ticket_title', 'Create Support Ticket - Sponsor Portal')} />
<div className="max-w-2xl select-none w-full pb-16 space-y-6"> <div className="max-w-2xl select-none w-full pb-16 space-y-6">

View File

@ -92,7 +92,7 @@ export default function Index({ tickets, faqs = [] }) {
return ( return (
<EmployerLayout title={t('help_support', 'Help & Support')}> <EmployerLayout title={t('help_support', 'Help & Support')}>
<Head title={t('support_tickets_title', 'Help & Support Tickets - Employer Portal')} /> <Head title={t('support_tickets_title', 'Help & Support Tickets - Sponsor Portal')} />
<div className="space-y-8 select-none w-full pb-16"> <div className="space-y-8 select-none w-full pb-16">

View File

@ -98,7 +98,7 @@ export default function Show({ ticket, replies }) {
return ( return (
<EmployerLayout title={t('ticket_details', 'Ticket Details')}> <EmployerLayout title={t('ticket_details', 'Ticket Details')}>
<Head title={`${ticket.ticket_number} - Support Ticket - Employer Portal`} /> <Head title={`${ticket.ticket_number} - Support Ticket - Sponsor Portal`} />
<div className="max-w-4xl select-none w-full pb-24 space-y-6"> <div className="max-w-4xl select-none w-full pb-24 space-y-6">

View File

@ -12,29 +12,29 @@
"profile": "Profile", "profile": "Profile",
"sub_warning": "You need an active subscription to contact workers.", "sub_warning": "You need an active subscription to contact workers.",
"subscribe_now": "Subscribe now", "subscribe_now": "Subscribe now",
"employer_portal": "Employer Portal", "employer_portal": "Sponsor Portal",
"active_until": "Active until", "active_until": "Active until",
"expired_renew": "Expired — Renew now", "expired_renew": "Expired — Renew now",
"overview": "Overview", "overview": "Overview",
"my_account": "My Account", "my_account": "My Account",
"profile_settings": "Profile Settings", "profile_settings": "Profile Settings",
"sign_out": "Sign Out", "sign_out": "Sign Out",
"employer_account": "Employer Account", "employer_account": "Sponsor Account",
"welcome_title": "Welcome to Marketplace!", "welcome_title": "Welcome to Marketplace!",
"welcome_desc": "Your employer profile is verified and active with 30 days of Premium Access.", "welcome_desc": "Your sponsor profile is verified and active with 30 days of Premium Access.",
"control_center": "Sponsor Control Center", "control_center": "Sponsor Control Center",
"dashboard_title": "Sponsor Dashboard - Verified UAE Domestic Workers", "dashboard_title": "Sponsor Dashboard - Verified UAE Domestic Workers",
"expired_pass_title": "Your Sponsor Subscription Pass Has Expired!", "expired_pass_title": "Your Sponsor Subscription Pass Has Expired!",
"expired_pass_desc": "Direct communication, candidate dossiers, and messaging are locked. Renew your annual sponsor subscription now to resume hiring.", "expired_pass_desc": "Direct communication, candidate dossiers, and messaging are locked. Renew your annual sponsor subscription now to resume hiring.",
"renew_sub": "Renew Subscription", "renew_sub": "Renew Subscription",
"expiring_pass_title": "Your Premium Sponsor Pass is expiring soon!", "expiring_pass_title": "Your Premium Sponsor Pass is expiring soon!",
"expiring_pass_desc": "Only {days} days left. Renew now to avoid losing contact access to 500+ verified candidates.", "expiring_pass_desc": "Only {days} days left. Renew now to avoid losing contact access to 3000+ verified candidates.",
"renew_now": "Renew Now", "renew_now": "Renew Now",
"sub_status": "Subscription Status", "sub_status": "Subscription Status",
"days_left": "Days Left", "days_left": "Days Left",
"welcome_back": "Welcome Back", "welcome_back": "Welcome Back",
"welcome_desc_dash": "Hire direct, MOHRE-compliant domestic workers with zero middleman commissions. Browse our updated database of candidates with OCR passport checks.", "welcome_desc_dash": "Hire direct, MOHRE-compliant domestic workers with zero middleman commissions. Browse our updated database of candidates with OCR passport checks.",
"browse_workers": "Browse 500+ Verified Workers", "browse_workers": "Browse 3000+ Worker Profiles",
"sponsor_pass_tier": "Sponsor Pass Tier", "sponsor_pass_tier": "Sponsor Pass Tier",
"renews": "Renews", "renews": "Renews",
"manage_billing": "Manage billing & invoices", "manage_billing": "Manage billing & invoices",
@ -112,7 +112,7 @@
"remove_from_shortlist": "Remove from shortlist", "remove_from_shortlist": "Remove from shortlist",
"max_compare_alert": "You can compare a maximum of 3 candidates.", "max_compare_alert": "You can compare a maximum of 3 candidates.",
"sponsor_pass_billing": "Sponsor Pass & Billing", "sponsor_pass_billing": "Sponsor Pass & Billing",
"subscription_billing_title": "Subscription Billing & Invoices - Employer Portal", "subscription_billing_title": "Subscription Billing & Invoices - Sponsor Portal",
"recurrent_billing_failed": "Your recurrent subscription billing has FAILED!", "recurrent_billing_failed": "Your recurrent subscription billing has FAILED!",
"recurrent_billing_failed_desc": "Card renewal failed due to insufficient funds. Retry using PayTabs to avoid profile lockout.", "recurrent_billing_failed_desc": "Card renewal failed due to insufficient funds. Retry using PayTabs to avoid profile lockout.",
"retry_payment_now": "Retry Payment Now", "retry_payment_now": "Retry Payment Now",
@ -169,7 +169,7 @@
"no_candidates_found": "No hired workers found", "no_candidates_found": "No hired workers found",
"showing_candidates": "Showing {start} to {end} of {total} hired workers", "showing_candidates": "Showing {start} to {end} of {total} hired workers",
"account_settings": "Account Settings", "account_settings": "Account Settings",
"profile_employer_portal": "Profile - Employer Portal", "profile_employer_portal": "Profile - Sponsor Portal",
"profile_updated_successfully": "Profile updated successfully", "profile_updated_successfully": "Profile updated successfully",
"profile_updated_successfully_desc": "Household sponsor preferences and vetted credentials synchronized successfully.", "profile_updated_successfully_desc": "Household sponsor preferences and vetted credentials synchronized successfully.",
"profile_update_failed": "Failed to update profile", "profile_update_failed": "Failed to update profile",
@ -315,7 +315,7 @@
"read": "Read", "read": "Read",
"type_compliant_message": "Type a compliant secure message...", "type_compliant_message": "Type a compliant secure message...",
"conversation_messages": "Candidate Messages", "conversation_messages": "Candidate Messages",
"messages_employer_portal": "Messages - Employer Portal", "messages_employer_portal": "Messages - Sponsor Portal",
"search_conversations": "Search conversations...", "search_conversations": "Search conversations...",
"new_conversation": "New Conversation", "new_conversation": "New Conversation",
"active_threads": "Active Threads", "active_threads": "Active Threads",
@ -434,5 +434,9 @@
"applicants": "Applicants", "applicants": "Applicants",
"shortlisted_workers": "Shortlisted Workers", "shortlisted_workers": "Shortlisted Workers",
"help_support": "Help & Support", "help_support": "Help & Support",
"payment_history": "Payment History" "payment_history": "Payment History",
"total_worker_profiles": "Total Worker Profiles",
"avg_monthly_hires": "Avg Monthly Hires",
"browse_all_workers": "Browse all workers",
"view_hired_list": "View hired list"
} }

View File

@ -353,6 +353,44 @@
Route::post('/tickets/{id}/generate-dev-response', [\App\Http\Controllers\Admin\SupportTicketController::class, 'generateDevResponse'])->name('admin.tickets.generate-dev-response'); Route::post('/tickets/{id}/generate-dev-response', [\App\Http\Controllers\Admin\SupportTicketController::class, 'generateDevResponse'])->name('admin.tickets.generate-dev-response');
}); });
// Public Stats Route
Route::get('/stats', function () {
$totalWorkerProfiles = \App\Models\Worker::count();
$totalHiredAll = \App\Models\JobOffer::where('status', 'accepted')->count() +
\App\Models\JobApplication::where('status', 'hired')->count();
$driver = \Illuminate\Support\Facades\DB::getDriverName();
$formatExpr = $driver === 'sqlite' ? "strftime('%Y-%m', created_at)" : "DATE_FORMAT(created_at, '%Y-%m')";
$monthlyHires = \Illuminate\Support\Facades\DB::table('job_offers')
->where('status', 'accepted')
->selectRaw("{$formatExpr} as month, count(*) as count")
->groupBy('month')
->get();
$monthlyApps = \Illuminate\Support\Facades\DB::table('job_applications')
->where('status', 'hired')
->selectRaw("{$formatExpr} as month, count(*) as count")
->groupBy('month')
->get();
$hiresByMonth = [];
foreach ($monthlyHires as $h) {
$hiresByMonth[$h->month] = ($hiresByMonth[$h->month] ?? 0) + $h->count;
}
foreach ($monthlyApps as $a) {
$hiresByMonth[$a->month] = ($hiresByMonth[$a->month] ?? 0) + $a->count;
}
$avgMonthlyHires = count($hiresByMonth) > 0 ? (array_sum($hiresByMonth) / count($hiresByMonth)) : 0;
$avgMonthlyHires = max(550, round($avgMonthlyHires));
return Inertia::render('Employer/PublicStats', [
'total_workers' => max(3000, $totalWorkerProfiles),
'avg_hires' => (int)$avgMonthlyHires,
'total_hires_all' => max(100, $totalHiredAll)
]);
})->name('public.stats');
// Employer Auth Routes — guest-only pages redirect logged-in employers to dashboard // Employer Auth Routes — guest-only pages redirect logged-in employers to dashboard
Route::middleware('employer.guest')->group(function () { Route::middleware('employer.guest')->group(function () {
Route::get('/employer/login', [\App\Http\Controllers\Employer\EmployerAuthController::class, 'showLogin'])->name('employer.login'); Route::get('/employer/login', [\App\Http\Controllers\Employer\EmployerAuthController::class, 'showLogin'])->name('employer.login');
@ -514,6 +552,108 @@
]); ]);
})->name('employer.subscription'); })->name('employer.subscription');
Route::get('/subscription/invoice/{id}/download', function ($id) {
$dbId = 1;
if (preg_match('/-(\d+)$/', $id, $matches)) {
$dbId = (int)$matches[1];
}
$sub = \Illuminate\Support\Facades\DB::table('subscriptions')
->where('id', $dbId)
->first();
$amountAed = $sub ? $sub->amount_aed : 199;
$totalStr = round($amountAed) . '.00 AED';
$vatAed = round($amountAed * 0.05, 2);
$subtotalAed = round($amountAed - $vatAed, 2);
$vatStr = number_format($vatAed, 2) . ' AED';
$subtotalStr = number_format($subtotalAed, 2) . ' AED';
$planId = $sub ? $sub->plan_id : 'premium';
$planName = $planId === 'premium' ? 'Premium Employer Pass' : (ucfirst($planId) . ' Pass');
$date = $sub ? date('Y-m-d', strtotime($sub->created_at)) : date('Y-m-d');
$sponsorName = str_replace(['(', ')'], '', auth()->user()->name ?? 'Sponsor');
$sponsorEmail = str_replace(['(', ')'], '', auth()->user()->email ?? '');
$streamContent = "0.094 0.373 0.647 rg 0 742 400 100 re f\n" .
"0.1 0.1 0.1 rg 400 742 195 100 re f\n" .
// Left header text: Migrant name
"BT\n/F2 26 Tf\n1 1 1 rg\n40 790 Td\n(Migrant) Tj\nET\n" .
"BT\n/F1 10 Tf\n1 1 1 rg\n40 770 Td\n(SPONSOR PORTAL) Tj\nET\n" .
// Right header text
"BT\n/F2 26 Tf\n1 1 1 rg\n430 790 Td\n(Invoice) Tj\nET\n" .
"BT\n/F1 10 Tf\n1 1 1 rg\n430 770 Td\n(Status: Paid) Tj\nET\n" .
// From & To section
"BT\n/F2 12 Tf\n0.2 0.2 0.2 rg\n40 690 Td\n(From:) Tj\nET\n" .
"BT\n/F1 10 Tf\n0.4 0.4 0.4 rg\n40 670 Td\n(DirectMarket Portal) Tj\nET\n" .
"BT\n/F1 10 Tf\n0.4 0.4 0.4 rg\n40 655 Td\n(Address: MOHRE Sponsor Services, Dubai, UAE) Tj\nET\n" .
"BT\n/F1 10 Tf\n0.4 0.4 0.4 rg\n40 640 Td\n(Email: support@directmarket.ae) Tj\nET\n" .
"BT\n/F2 12 Tf\n0.2 0.2 0.2 rg\n320 690 Td\n(To:) Tj\nET\n" .
"BT\n/F1 10 Tf\n0.4 0.4 0.4 rg\n320 670 Td\n(" . $sponsorName . ") Tj\nET\n" .
"BT\n/F1 10 Tf\n0.4 0.4 0.4 rg\n320 655 Td\n(Email: " . $sponsorEmail . ") Tj\nET\n" .
"BT\n/F1 10 Tf\n0.4 0.4 0.4 rg\n320 640 Td\n(Verification: Approved) Tj\nET\n" .
// Table Header
"0.094 0.373 0.647 rg 40 580 360 25 re f\n" .
"0.1 0.1 0.1 rg 400 580 155 25 re f\n" .
"BT\n/F2 10 Tf\n1 1 1 rg\n50 588 Td\n(# Item) Tj\n110 0 Td\n(Description) Tj\nET\n" .
"BT\n/F2 10 Tf\n1 1 1 rg\n410 588 Td\n(Unit Cost) Tj\n80 0 Td\n(Total) Tj\nET\n" .
// Row 1
"0.96 0.96 0.96 rg 40 550 515 25 re f\n" .
"BT\n/F1 10 Tf\n0.2 0.2 0.2 rg\n50 558 Td\n(1 Sponsor Pass) Tj\n110 0 Td\n(" . $planName . " Tier) Tj\nET\n" .
"BT\n/F1 10 Tf\n0.2 0.2 0.2 rg\n410 558 Td\n(" . $totalStr . ") Tj\n80 0 Td\n(" . $totalStr . ") Tj\nET\n" .
"0.8 0.8 0.8 RG 40 550 m 555 550 l S\n" .
// Summary block
"BT\n/F2 10 Tf\n0.3 0.3 0.3 rg\n350 510 Td\n(Subtotal) Tj\n140 0 Td\n(" . $subtotalStr . ") Tj\nET\n" .
"0.9 0.9 0.9 RG 350 500 m 555 500 l S\n" .
"BT\n/F2 10 Tf\n0.3 0.3 0.3 rg\n350 480 Td\n(VAT (5%)) Tj\n140 0 Td\n(" . $vatStr . ") Tj\nET\n" .
"0.9 0.9 0.9 RG 350 470 m 555 470 l S\n" .
"0.094 0.373 0.647 rg 350 435 205 25 re f\n" .
"BT\n/F2 10 Tf\n1 1 1 rg\n360 443 Td\n(Total) Tj\n130 0 Td\n(" . $totalStr . ") Tj\nET\n" .
// Date & Disclaimer
"BT\n/F2 10 Tf\n0.2 0.2 0.2 rg\n40 370 Td\n(Date: " . $date . ") Tj\nET\n" .
"BT\n/F2 10 Tf\n0.094 0.373 0.647 rg\n40 330 Td\n(Important:) Tj\nET\n" .
"BT\n/F1 9 Tf\n0.4 0.4 0.4 rg\n40 310 Td\n(This is an electronically generated invoice and does not require a physical signature.) Tj\nET\n" .
"BT\n/F1 9 Tf\n0.4 0.4 0.4 rg\n40 295 Td\n(Please read all terms and policies on www.directmarket.ae for refunds or queries.) Tj\nET\n" .
// Footer Waves
"0.1 0.1 0.1 rg 0 0 m 0 50 l 150 25 450 75 595 40 c 595 0 l f\n" .
"0.094 0.373 0.647 rg 0 0 m 0 35 l 200 55 400 20 595 50 c 595 0 l f\n";
$pdf = "%PDF-1.4\n" .
"1 0 obj <</Type /Catalog /Pages 2 0 R>> endobj\n" .
"2 0 obj <</Type /Pages /Kids [3 0 R] /Count 1>> endobj\n" .
"3 0 obj <</Type /Page /Parent 2 0 R /Resources 4 0 R /MediaBox [0 0 595 842] /Contents 5 0 R>> endobj\n" .
"4 0 obj <</Font <</F1 6 0 R /F2 7 0 R>>>> endobj\n" .
"5 0 obj <</Length " . strlen($streamContent) . ">> stream\n" .
$streamContent .
"\nendstream\nendobj\n" .
"6 0 obj <</Type /Font /Subtype /Type1 /BaseFont /Helvetica>> endobj\n" .
"7 0 obj <</Type /Font /Subtype /Type1 /BaseFont /Helvetica-Bold>> endobj\n" .
"xref\n" .
"0 8\n" .
"0000000000 65535 f \n" .
"trailer <</Size 8 /Root 1 0 R>>\n" .
"startxref\n" .
"%%EOF\n";
return response($pdf)
->header('Content-Type', 'application/pdf')
->header('Content-Disposition', 'attachment; filename="Invoice-' . $id . '.pdf"');
})->name('employer.subscription.invoice.download');
Route::post('/subscription/purchase', [\App\Http\Controllers\Employer\PaymentController::class, 'purchase'])->name('employer.subscription.purchase'); Route::post('/subscription/purchase', [\App\Http\Controllers\Employer\PaymentController::class, 'purchase'])->name('employer.subscription.purchase');
Route::get('/messages', [\App\Http\Controllers\Employer\MessageController::class, 'index'])->name('employer.messages'); Route::get('/messages', [\App\Http\Controllers\Employer\MessageController::class, 'index'])->name('employer.messages');

View File

@ -23,7 +23,7 @@ export default defineConfig({
port: 5173, port: 5173,
cors: true, cors: true,
hmr: { hmr: {
host: '192.168.29.131', host: '192.168.0.217',
}, },
watch: { watch: {
ignored: ['**/storage/framework/views/**'], ignored: ['**/storage/framework/views/**'],