Compare commits

...

2 Commits

Author SHA1 Message Date
147efa6f0e workers list api 2026-05-29 17:24:00 +05:30
27fa7f9cb3 translation file added 2026-05-28 19:14:40 +05:30
25 changed files with 3196 additions and 604 deletions

View File

@ -0,0 +1,362 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Worker;
use App\Models\WorkerCategory;
use App\Models\Shortlist;
use App\Models\JobOffer;
use App\Models\JobApplication;
use App\Models\JobPost;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
class EmployerWorkerController extends Controller
{
/**
* Helper to map worker DB models to API presentation format.
*/
private function formatWorker(Worker $w)
{
// Map languages with country names
$langs = ($w->id % 2 === 0) ? ['English', 'Arabic'] : (($w->id % 3 === 0) ? ['English', 'Tagalog'] : ['English', 'Hindi', 'Arabic']);
// Preferred job types: full-time / part-time / live-in / live-out
$jobTypes = ['full-time', 'part-time', 'live-in', 'live-out'];
$preferredJobType = $jobTypes[$w->id % 4];
// Availability status: Active / Hidden / Hired
$availabilityStatus = ucfirst($w->status === 'active' ? 'Active' : ($w->status === 'hidden' ? 'Hidden' : ($w->status === 'Hired' ? 'Hired' : 'Active')));
// Emirates ID verification status
$emiratesIdStatus = $w->verified ? 'Emirates ID Verified' : 'EID Vetting Pending';
// Exact Skills mapping: cooking, driving, childcare, cleaning, elderly care, gardening
$skillsList = ['cooking', 'driving', 'childcare', 'cleaning', 'elderly care', 'gardening'];
$mappedSkills = [
$skillsList[$w->id % 6],
$skillsList[($w->id + 2) % 6]
];
// Visa status
$visaStatusesList = ['Residence Visa', 'Tourist Visa', 'Employment Visa', 'Cancelled Visa', 'Own Visa'];
$visaStatus = $visaStatusesList[$w->id % 5];
// Optional profile photos
$photos = [
'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?auto=format&fit=crop&q=80&w=200',
'https://images.unsplash.com/photo-1534528741775-53994a69daeb?auto=format&fit=crop&q=80&w=200',
'https://images.unsplash.com/photo-1544005313-94ddf0286df2?auto=format&fit=crop&q=80&w=200',
null
];
$photo = $photos[$w->id % 4];
$rating = 4.0 + (($w->id * 3) % 10) / 10.0;
$reviewsCount = ($w->id * 4) % 20 + 2;
return [
'id' => $w->id,
'name' => $w->name,
'nationality' => $w->nationality,
'photo' => $photo,
'emirates_id_status' => $emiratesIdStatus,
'category' => $w->category ? $w->category->name : 'Domestic Worker',
'skills' => $mappedSkills,
'availability_status' => $availabilityStatus,
'visa_status' => $visaStatus,
'experience' => $w->experience,
'salary' => (int)$w->salary,
'religion' => $w->religion,
'languages' => $langs,
'age' => $w->age,
'verified' => (bool)$w->verified,
'preferred_job_type' => $preferredJobType,
'bio' => $w->bio,
'rating' => $rating,
'reviews_count' => $reviewsCount,
];
}
/**
* 1. GET /api/employers/workers
* List of workers available for hiring.
*/
public function getWorkers(Request $request)
{
try {
$query = Worker::with(['category', 'skills'])
->where('status', '!=', 'Hired')
->where('status', '!=', 'hidden');
// Apply search filter if provided
if ($request->filled('search')) {
$search = $request->search;
$query->where(function($q) use ($search) {
$q->where('name', 'like', "%{$search}%")
->orWhere('nationality', 'like', "%{$search}%")
->orWhere('religion', 'like', "%{$search}%");
});
}
// Apply category filter if provided
if ($request->filled('category_id')) {
$query->where('category_id', $request->category_id);
}
// Apply nationality filter if provided
if ($request->filled('nationality')) {
$query->where('nationality', $request->nationality);
}
// Apply salary filters
if ($request->filled('min_salary')) {
$query->where('salary', '>=', $request->min_salary);
}
if ($request->filled('max_salary')) {
$query->where('salary', '<=', $request->max_salary);
}
$dbWorkers = $query->latest()->get();
$formattedWorkers = $dbWorkers->map(function ($w) {
return $this->formatWorker($w);
});
return response()->json([
'success' => true,
'data' => [
'workers' => $formattedWorkers
]
], 200);
} catch (\Exception $e) {
logger()->error('Mobile API Employer Get Workers Failure: ' . $e->getMessage());
return response()->json([
'success' => false,
'message' => 'An error occurred while fetching the worker list.',
'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
], 500);
}
}
/**
* 2. GET /api/employers/candidates
* List of candidates representing standard job applications and direct hiring offers.
*/
public function getCandidates(Request $request)
{
/** @var User $employer */
$employer = $request->attributes->get('employer');
try {
$employerId = $employer->id;
// Fetch Job Applications
$jobIds = JobPost::where('employer_id', $employerId)->pluck('id');
$applications = JobApplication::whereIn('job_id', $jobIds)
->with(['worker.category', 'jobPost'])
->get();
$selectedWorkers = $applications->map(function ($app) {
$w = $app->worker;
if (!$w) return null;
$status = 'Reviewing';
if ($app->status === 'hired') $status = 'Hired';
elseif ($app->status === 'rejected') $status = 'Rejected';
elseif ($app->status === 'shortlisted' || $app->status === 'offer_sent') $status = 'Offer Sent';
elseif ($app->status === 'applied') $status = 'Reviewing';
else $status = ucfirst($app->status);
return [
'id' => $app->id,
'worker_id' => $w->id,
'name' => $w->name,
'nationality' => $w->nationality,
'category' => $w->category ? $w->category->name : 'General Helper',
'salary' => (int)$w->salary,
'status' => $status,
'applied_at' => $app->created_at->format('Y-m-d H:i:s'),
'type' => 'application',
];
})->filter()->values()->toArray();
// Fetch Direct Hiring Offers
$directOffers = JobOffer::where('employer_id', $employerId)
->with('worker.category')
->get();
$directWorkers = $directOffers->map(function ($offer) {
$w = $offer->worker;
if (!$w) return null;
$status = 'Offer Sent';
if ($offer->status === 'accepted') $status = 'Hired';
elseif ($offer->status === 'rejected') $status = 'Rejected';
elseif ($offer->status === 'pending') $status = 'Offer Sent';
return [
'id' => 'offer_' . $offer->id,
'worker_id' => $w->id,
'name' => $w->name,
'nationality' => $w->nationality,
'category' => $w->category ? $w->category->name : 'General Helper',
'salary' => (int)$offer->salary,
'status' => $status,
'applied_at' => $offer->created_at->format('Y-m-d H:i:s'),
'type' => 'direct_offer',
];
})->filter()->values()->toArray();
// Merge and sort
$mergedCandidates = array_merge($selectedWorkers, $directWorkers);
// Optional status filtering
if ($request->filled('status')) {
$filterStatus = $request->status;
$mergedCandidates = array_values(array_filter($mergedCandidates, function ($c) use ($filterStatus) {
return strcasecmp($c['status'], $filterStatus) === 0;
}));
}
return response()->json([
'success' => true,
'data' => [
'candidates' => $mergedCandidates
]
], 200);
} catch (\Exception $e) {
logger()->error('Mobile API Employer Get Candidates Failure: ' . $e->getMessage());
return response()->json([
'success' => false,
'message' => 'An error occurred while fetching the candidate list.',
'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
], 500);
}
}
/**
* 3. POST /api/employers/candidates/hire or POST /api/employers/candidates/{id}/hire
* Update status from active (or reviewing/pending) to hired.
*/
public function hireCandidate(Request $request, $id = null)
{
/** @var User $employer */
$employer = $request->attributes->get('employer');
// Let the client pass either route parameter id OR body parameter identifier
$targetId = $id ?: $request->input('id') ?: $request->input('worker_id') ?: $request->input('application_id') ?: $request->input('offer_id');
if (!$targetId) {
return response()->json([
'success' => false,
'message' => 'Candidate or Worker identifier is required.'
], 422);
}
try {
$employerId = $employer->id;
$worker = null;
$updatedApplication = null;
$updatedOffer = null;
// Direct Offer check
if (is_string($targetId) && str_starts_with($targetId, 'offer_')) {
$offerId = substr($targetId, 6);
$offer = JobOffer::where('id', $offerId)->where('employer_id', $employerId)->firstOrFail();
$offer->update(['status' => 'accepted']);
if ($offer->worker) {
$offer->worker->update(['status' => 'Hired']);
$worker = $offer->worker;
}
$updatedOffer = $offer;
} else {
// Check if targetId is an application
$application = JobApplication::where('id', $targetId)
->whereHas('jobPost', function($q) use ($employerId) {
$q->where('employer_id', $employerId);
})->first();
if ($application) {
$application->update(['status' => 'hired']);
if ($application->worker) {
$application->worker->update(['status' => 'Hired']);
$worker = $application->worker;
}
$updatedApplication = $application;
} else {
// Try targeting by Worker ID directly
$worker = Worker::find($targetId);
if (!$worker) {
return response()->json([
'success' => false,
'message' => 'Worker, application, or job offer not found with the provided identifier.'
], 404);
}
$worker->update(['status' => 'Hired']);
// Find existing direct offer
$offer = JobOffer::where('employer_id', $employerId)
->where('worker_id', $worker->id)
->first();
if ($offer) {
$offer->update(['status' => 'accepted']);
$updatedOffer = $offer;
} else {
// Find existing application
$jobIds = JobPost::where('employer_id', $employerId)->pluck('id');
$application = JobApplication::whereIn('job_id', $jobIds)
->where('worker_id', $worker->id)
->first();
if ($application) {
$application->update(['status' => 'hired']);
$updatedApplication = $application;
} else {
// Create a new direct job offer and accept it
$updatedOffer = JobOffer::create([
'employer_id' => $employerId,
'worker_id' => $worker->id,
'work_date' => now()->format('Y-m-d'),
'location' => 'Dubai',
'salary' => $worker->salary,
'notes' => 'Direct sponsoring matching finalized via mobile API.',
'status' => 'accepted',
]);
}
}
}
}
return response()->json([
'success' => true,
'message' => 'Candidate successfully marked as Hired!',
'data' => [
'worker_id' => $worker ? $worker->id : null,
'worker_status' => $worker ? $worker->status : 'Hired',
'application' => $updatedApplication,
'offer' => $updatedOffer,
]
], 200);
} catch (\Exception $e) {
logger()->error('Mobile API Employer Hire Candidate Failure: ' . $e->getMessage());
return response()->json([
'success' => false,
'message' => 'An error occurred while marking the candidate as hired.',
'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
], 500);
}
}
}

View File

@ -103,6 +103,11 @@ public function index(Request $request)
// Merge standard job applications with direct hiring offers for unified tracking
$mergedCandidates = array_merge($selectedWorkers, $directWorkers);
// Only display Hired candidates in the candidates pipeline
$mergedCandidates = array_values(array_filter($mergedCandidates, function ($w) {
return $w && $w['status'] === 'Hired';
}));
return Inertia::render('Employer/SelectedCandidates', [
'selectedWorkers' => $mergedCandidates,
]);

View File

@ -42,7 +42,10 @@ public function index(Request $request)
$user = $this->resolveCurrentUser();
$employerId = $user ? $user->id : 2;
$dbWorkers = Worker::with(['category', 'skills'])->get();
$dbWorkers = Worker::with(['category', 'skills'])
->where('status', '!=', 'Hired')
->where('status', '!=', 'hidden')
->get();
$workers = $dbWorkers->map(function ($w) {
// Map languages with country names
@ -177,6 +180,8 @@ public function show($id)
$simDb = Worker::with('category')
->where('id', '!=', $w->id)
->where('status', '!=', 'Hired')
->where('status', '!=', 'hidden')
->limit(3)
->get();
$similarWorkers = $simDb->map(function($sw) {
@ -254,4 +259,47 @@ public function sendOffer(Request $request, $id)
return redirect()->route('employer.hiring.success', ['id' => $id])
->with('success', 'Hiring offer has been successfully dispatched to the worker!');
}
public function markHired(Request $request, $id)
{
$user = $this->resolveCurrentUser();
$employerId = $user ? $user->id : 2;
$worker = Worker::findOrFail($id);
$worker->update([
'status' => 'Hired',
]);
// Check if there is an existing job offer for this employer and worker
$offer = JobOffer::where('employer_id', $employerId)
->where('worker_id', $worker->id)
->first();
if ($offer) {
$offer->update(['status' => 'accepted']);
} else {
// Also check if there's an existing job application
$jobIds = \App\Models\JobPost::where('employer_id', $employerId)->pluck('id');
$application = \App\Models\JobApplication::whereIn('job_id', $jobIds)
->where('worker_id', $worker->id)
->first();
if ($application) {
$application->update(['status' => 'hired']);
} else {
// Create a new direct job offer with status accepted
JobOffer::create([
'employer_id' => $employerId,
'worker_id' => $worker->id,
'work_date' => now()->format('Y-m-d'),
'location' => 'Dubai',
'salary' => $worker->salary,
'notes' => 'Direct sponsoring matching finalized.',
'status' => 'accepted',
]);
}
}
return back()->with('success', 'Worker successfully marked as Hired!');
}
}

View File

@ -49,8 +49,8 @@ public function run(): void
'sender_id' => 2,
'text' => 'Hello, are you available for an interview?',
'created_at' => now(),
'updated_at' => now(),
],
'updated_at' => now(),
[
'conversation_id' => $conversationId,
'sender_type' => 'worker',

View File

@ -26,10 +26,12 @@ import {
DropdownMenuLabel,
DropdownMenuSeparator
} from '@/components/ui/dropdown-menu';
import { useTranslation, languages } from '../lib/LanguageContext';
export default function EmployerLayout({ children, title, fullPage = false }) {
const { url, props } = usePage();
const { auth, unread_messages_count, flash } = props;
const { locale, setLocale, t } = useTranslation();
useEffect(() => {
if (flash?.success) {
@ -40,12 +42,12 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
}
if (flash?.first_login) {
// Elegant first login celebratory alert
toast.success('🎉 Welcome to Marketplace!', {
description: 'Your employer profile is verified and active with 30 days of Premium Access.',
toast.success(`🎉 ${t('welcome_title', 'Welcome to Marketplace!')}`, {
description: t('welcome_desc', 'Your employer profile is verified and active with 30 days of Premium Access.'),
duration: 6000,
});
}
}, [flash]);
}, [flash, t]);
const user = auth?.user || {
name: 'Guest',
@ -58,22 +60,22 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
const isSubActive = user.subscription_status === 'active';
const navItems = [
{ name: 'Dashboard', href: '/employer/dashboard', icon: LayoutDashboard },
{ name: 'Find Workers', href: '/employer/workers', icon: Search },
{ name: 'Shortlist', href: '/employer/shortlist', icon: Bookmark },
{ name: 'Candidates', href: '/employer/candidates', icon: UserCheck },
{ name: 'Messages', href: '/employer/messages', icon: MessageSquare, badge: unread_messages_count },
{ name: 'Charity Events', href: '/employer/announcements', icon: Heart },
{ name: 'Subscription', href: '/employer/subscription', icon: CreditCard },
{ name: 'My Profile', href: '/employer/profile', icon: User },
{ name: 'Dashboard', translationKey: 'dashboard', href: '/employer/dashboard', icon: LayoutDashboard },
{ name: 'Find Workers', translationKey: 'find_workers', href: '/employer/workers', icon: Search },
{ name: 'Shortlist', translationKey: 'shortlist', href: '/employer/shortlist', icon: Bookmark },
{ name: 'Candidates', translationKey: 'candidates', href: '/employer/candidates', icon: UserCheck },
{ name: 'Messages', translationKey: 'messages', href: '/employer/messages', icon: MessageSquare, badge: unread_messages_count },
{ name: 'Charity Events', translationKey: 'charity_events', href: '/employer/announcements', icon: Heart },
{ name: 'Subscription', translationKey: 'subscription', href: '/employer/subscription', icon: CreditCard },
{ name: 'My Profile', translationKey: 'my_profile', href: '/employer/profile', icon: User },
];
const mobileTabs = [
{ name: 'Search', href: '/employer/workers', icon: Search },
{ name: 'Shortlist', href: '/employer/shortlist', icon: Bookmark },
{ name: 'Candidates', href: '/employer/candidates', icon: UserCheck },
{ name: 'Messages', href: '/employer/messages', icon: MessageSquare, badge: unread_messages_count },
{ name: 'Profile', href: '/employer/profile', icon: User },
{ name: 'Search', translationKey: 'search', href: '/employer/workers', icon: Search },
{ name: 'Shortlist', translationKey: 'shortlist', href: '/employer/shortlist', icon: Bookmark },
{ name: 'Candidates', translationKey: 'candidates', href: '/employer/candidates', icon: UserCheck },
{ name: 'Messages', translationKey: 'messages', href: '/employer/messages', icon: MessageSquare, badge: unread_messages_count },
{ name: 'Profile', translationKey: 'profile', href: '/employer/profile', icon: User },
];
return (
@ -83,13 +85,13 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
<div className="bg-[#185FA5] text-white px-4 py-2.5 text-xs sm:text-sm font-medium flex items-center justify-between shadow-sm z-50">
<div className="flex items-center space-x-2 truncate">
<AlertCircle className="w-4 h-4 text-amber-300 flex-shrink-0 animate-bounce" />
<span className="truncate">You need an active subscription to contact workers.</span>
<span className="truncate">{t('sub_warning', 'You need an active subscription to contact workers.')}</span>
</div>
<Link
href="/employer/subscription"
className="bg-white text-[#185FA5] hover:bg-slate-100 px-3 py-1 rounded-lg text-xs font-bold transition-colors inline-flex items-center space-x-1 flex-shrink-0 shadow-sm"
>
<span>Subscribe now</span>
<span>{t('subscribe_now', 'Subscribe now')}</span>
<ArrowRight className="w-3 h-3" />
</Link>
</div>
@ -102,7 +104,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">
M
</div>
<span className="font-bold text-lg text-slate-800 tracking-tight truncate">Employer Portal</span>
<span className="font-bold text-lg text-slate-800 tracking-tight truncate">{t('employer_portal', 'Employer Portal')}</span>
</div>
<div className="flex items-center space-x-3">
@ -130,7 +132,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">
M
</div>
<span className="font-bold text-xl text-slate-800 tracking-tight">Employer Portal</span>
<span className="font-bold text-xl text-slate-800 tracking-tight">{t('employer_portal', 'Employer Portal')}</span>
</div>
{/* Subscription Status Pill */}
@ -139,14 +141,14 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
<div className="flex items-center justify-between px-3 py-1.5 bg-emerald-50 border border-emerald-200 rounded-lg text-xs font-semibold text-emerald-700 hover:bg-emerald-100 transition-colors">
<div className="flex items-center space-x-1.5 truncate">
<CheckCircle className="w-3.5 h-3.5 text-emerald-600 flex-shrink-0" />
<span className="truncate">Active until {user.subscription_expires_at || 'Dec 31'}</span>
<span className="truncate">{t('active_until', 'Active until')} {user.subscription_expires_at || 'Dec 31'}</span>
</div>
</div>
) : (
<div className="flex items-center justify-between px-3 py-1.5 bg-red-50 border border-red-200 rounded-lg text-xs font-semibold text-red-700 hover:bg-red-100 transition-colors">
<div className="flex items-center space-x-1.5 truncate">
<AlertCircle className="w-3.5 h-3.5 text-red-600 flex-shrink-0" />
<span className="truncate">Expired Renew now</span>
<span className="truncate">{t('expired_renew', 'Expired — Renew now')}</span>
</div>
</div>
)}
@ -171,7 +173,7 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
>
<div className="flex items-center space-x-3">
<Icon className={`w-5 h-5 transition-colors ${isActive ? 'text-white' : 'text-slate-400 group-hover:text-slate-900'}`} />
<span className="tracking-tight">{item.name}</span>
<span className="tracking-tight">{t(item.translationKey, item.name)}</span>
</div>
{item.badge > 0 && (
@ -193,16 +195,48 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
<header className="hidden lg:flex h-16 bg-white border-b border-slate-200 items-center justify-between px-8 shrink-0 sticky top-0 z-30 shadow-sm">
<div className="flex items-center space-x-4">
<div className="text-xs font-bold text-slate-400 uppercase tracking-widest">
{title || 'Overview'}
{title ? t(title.toLowerCase().replace(/\s+/g, '_'), title) : t('overview', 'Overview')}
</div>
</div>
<div className="flex items-center space-x-6">
{/* Language Switcher */}
<div className="flex items-center bg-slate-50 border border-slate-200 rounded-xl p-1">
<button className="px-3 py-1 text-[10px] font-black bg-white text-[#185FA5] rounded-lg shadow-sm border border-slate-100">EN</button>
<button className="px-3 py-1 text-[10px] font-black text-slate-400 hover:text-slate-600">AR</button>
{/* Language Switcher Dropdown */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button className="flex items-center space-x-2 px-3 py-1.5 bg-slate-50 hover:bg-slate-100 border border-slate-200 rounded-xl transition-all cursor-pointer outline-none select-none">
<span className="text-xs font-bold text-slate-700 flex items-center gap-1.5">
<span>{languages.find(l => l.code === locale)?.flag}</span>
<span className="uppercase text-[10px] font-black tracking-wider">{locale}</span>
</span>
<svg className="w-2.5 h-2.5 text-slate-500 transition-transform duration-200 group-data-[state=open]:rotate-180" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
</svg>
</button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-48 mt-2 p-1 rounded-xl border border-slate-200 bg-white/95 backdrop-blur-md shadow-xl z-50">
<DropdownMenuLabel className="text-[9px] font-black text-slate-400 uppercase tracking-widest px-2.5 py-2">Select Language</DropdownMenuLabel>
<DropdownMenuSeparator className="bg-slate-100" />
{languages.map((lang) => (
<DropdownMenuItem
key={lang.code}
onClick={() => setLocale(lang.code)}
className={`flex items-center justify-between px-2.5 py-2 text-xs font-bold rounded-lg cursor-pointer transition-all ${
locale === lang.code
? 'bg-[#185FA5]/10 text-[#185FA5] font-black'
: 'text-slate-600 hover:bg-slate-50 hover:text-slate-900'
}`}
>
<div className="flex items-center space-x-2">
<span className="text-base">{lang.flag}</span>
<span>{lang.nativeName}</span>
</div>
{locale === lang.code && (
<div className="w-1.5 h-1.5 rounded-full bg-[#185FA5]" />
)}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
{/* Chat/Notifications */}
<Link href="/employer/messages" className="relative p-2.5 text-slate-500 hover:text-[#185FA5] hover:bg-blue-50 rounded-xl transition-all group">
@ -216,7 +250,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">
<div className="text-right hidden sm:block">
<div className="text-xs font-black text-slate-900 group-hover:text-[#185FA5] transition-colors">{user.name}</div>
<div className="text-[10px] font-bold text-slate-400 uppercase tracking-tighter">Employer Account</div>
<div className="text-[10px] font-bold text-slate-400 uppercase tracking-tighter">{t('employer_account', 'Employer Account')}</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">
{user.name.charAt(0)}
@ -224,18 +258,18 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
</button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-56 mt-2">
<DropdownMenuLabel className="text-[10px] font-black text-slate-400 uppercase tracking-widest px-2 py-1.5">My Account</DropdownMenuLabel>
<DropdownMenuLabel className="text-[10px] font-black text-slate-400 uppercase tracking-widest px-2 py-1.5">{t('my_account', 'My Account')}</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<Link href="/employer/profile" className="flex items-center space-x-2 text-xs font-bold text-slate-600 cursor-pointer">
<User className="w-4 h-4" />
<span>Profile Settings</span>
<span>{t('profile_settings', 'Profile Settings')}</span>
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link href="/employer/subscription" className="flex items-center space-x-2 text-xs font-bold text-slate-600 cursor-pointer">
<CreditCard className="w-4 h-4" />
<span>Subscription</span>
<span>{t('subscription', 'Subscription')}</span>
</Link>
</DropdownMenuItem>
<DropdownMenuSeparator />
@ -247,7 +281,7 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
className="w-full flex items-center space-x-2 text-xs font-bold text-rose-600 cursor-pointer"
>
<LogOut className="w-4 h-4" />
<span>Sign Out</span>
<span>{t('sign_out', 'Sign Out')}</span>
</Link>
</DropdownMenuItem>
</DropdownMenuContent>
@ -258,7 +292,9 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
<div className={`flex-1 overflow-y-auto ${fullPage ? 'p-0' : 'p-4 sm:p-8 pb-24 lg:pb-8'}`}>
{title && !fullPage && (
<h1 className="text-2xl font-black text-slate-900 mb-6 tracking-tight lg:hidden">{title}</h1>
<h1 className="text-2xl font-black text-slate-900 mb-6 tracking-tight lg:hidden">
{title ? t(title.toLowerCase().replace(/\s+/g, '_'), title) : ''}
</h1>
)}
{children}
</div>
@ -288,7 +324,7 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
</span>
)}
</div>
<span className="text-[10px] font-bold">{tab.name}</span>
<span className="text-[10px] font-bold">{t(tab.translationKey, tab.name)}</span>
</Link>
);
})}

View File

@ -1,6 +1,7 @@
import React, { useState, useEffect } from 'react';
import { Head, useForm } from '@inertiajs/react';
import EmployerLayout from '../../Layouts/EmployerLayout';
import { useTranslation } from '../../lib/LanguageContext';
import {
Megaphone,
Send,
@ -30,6 +31,7 @@ import {
} from '@/components/ui/dialog';
export default function Announcements({ initialAnnouncements }) {
const { t } = useTranslation();
const [isDialogOpen, setIsDialogOpen] = useState(false);
const [searchTerm, setSearchTerm] = useState('');
const [toastMessage, setToastMessage] = useState(null);
@ -69,8 +71,8 @@ export default function Announcements({ initialAnnouncements }) {
reset();
setIsDialogOpen(false);
showToast(
'💖 COMMUNITY CHARITY EVENT POSTED!',
'🔔 Instant Push Notification sent to all workers in Dubai! Morning-of reminder notification scheduled successfully.'
t('community_charity_event_posted', 'COMMUNITY CHARITY EVENT POSTED!'),
t('community_charity_event_posted_desc', 'Instant Push Notification sent to all workers in Dubai! Morning-of reminder notification scheduled successfully.')
);
}
});
@ -82,8 +84,8 @@ export default function Announcements({ initialAnnouncements }) {
);
return (
<EmployerLayout title="Charity Events & Support Drives">
<Head title="Community Charity Events - Sponsor Hub" />
<EmployerLayout title={t('charity_events_support_drives', 'Charity Events & Support Drives')}>
<Head title={`${t('community_charity_events_sponsor_hub', 'Community Charity Events - Sponsor Hub')}`} />
{toastMessage && (
<div className="fixed bottom-8 right-8 bg-slate-900 text-white px-6 py-5 rounded-[24px] shadow-2xl border border-slate-800 flex items-start space-x-3.5 z-[100] max-w-md animate-in slide-in-from-bottom-5 duration-350">
@ -92,7 +94,7 @@ export default function Announcements({ initialAnnouncements }) {
</div>
<div className="space-y-1">
<div className="font-black text-xs uppercase tracking-widest text-emerald-400">{toastMessage}</div>
{toastSub && <p className="text-[11px] text-slate-350 leading-relaxed font-semibold">{toastSub}</p>}
{toastSub && <p className="text-[11px] text-slate-300 leading-relaxed font-semibold">{toastSub}</p>}
</div>
</div>
)}
@ -104,11 +106,11 @@ export default function Announcements({ initialAnnouncements }) {
<div className="space-y-2 max-w-2xl">
<div className="inline-flex items-center space-x-2 px-3 py-1 bg-rose-50 border border-rose-100 rounded-full text-[10px] font-black uppercase tracking-wider text-rose-700">
<Heart className="w-3.5 h-3.5 fill-rose-500 text-rose-500 animate-pulse" />
<span>Dubai Community Support Drives</span>
<span>{t('dubai_community_support_drives', 'Dubai Community Support Drives')}</span>
</div>
<h2 className="text-xl font-black text-slate-900 tracking-tight">Free Medical Checks, Food Drives & Support Services</h2>
<h2 className="text-xl font-black text-slate-900 tracking-tight">{t('free_medical_checks_title', 'Free Medical Checks, Food Drives & Support Services')}</h2>
<p className="text-xs text-slate-500 font-bold leading-relaxed">
Organizing a support program? Share community campaigns directly. The platform will automatically push an **instant pop-up notification** to workers, followed by a **morning-of event reminder** to keep attendance strong.
{t('free_medical_checks_desc', 'Organizing a support program? Share community campaigns directly. The platform will automatically push an instant pop-up notification to workers, followed by a morning-of event reminder to keep attendance strong.')}
</p>
</div>
</div>
@ -118,7 +120,7 @@ export default function Announcements({ initialAnnouncements }) {
<Search className="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400 group-focus-within:text-[#185FA5] transition-colors" />
<input
type="text"
placeholder="Search charity events & drives..."
placeholder={t('search_charity_events_placeholder', 'Search charity events & drives...')}
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="w-full pl-12 pr-4 py-3 bg-slate-50 border-none rounded-2xl text-sm font-bold focus:ring-2 focus:ring-blue-100 transition-all outline-none"
@ -129,15 +131,15 @@ export default function Announcements({ initialAnnouncements }) {
<DialogTrigger asChild>
<button className="bg-rose-600 hover:bg-rose-700 text-white px-8 py-3.5 rounded-2xl font-black text-xs uppercase tracking-widest flex items-center justify-center space-x-2 transition-all shadow-lg shadow-rose-200/50 hover:-translate-y-1 active:translate-y-0">
<Heart className="w-4 h-4 fill-white" />
<span>Post Charity Event</span>
<span>{t('post_charity_event', 'Post Charity Event')}</span>
</button>
</DialogTrigger>
<DialogContent className="sm:max-w-[550px] rounded-3xl p-0 overflow-hidden border-none shadow-2xl">
<div className="bg-gradient-to-r from-rose-500 to-pink-600 p-8 text-white relative">
<div className="absolute top-0 right-0 w-32 h-32 bg-white/10 rounded-full -mr-16 -mt-16 blur-2xl" />
<DialogTitle className="text-2xl font-black relative z-10">Post Charity Event</DialogTitle>
<DialogTitle className="text-2xl font-black relative z-10">{t('post_charity_event', 'Post Charity Event')}</DialogTitle>
<DialogDescription className="text-pink-100 font-semibold mt-2 relative z-10">
Broadcast a support program, medical camp, or distribution drive to the worker community.
{t('broadcast_support_program_desc', 'Broadcast a support program, medical camp, or distribution drive to the worker community.')}
</DialogDescription>
</div>
@ -146,12 +148,12 @@ export default function Announcements({ initialAnnouncements }) {
<div className="space-y-4 p-4 bg-rose-50/50 rounded-2xl border border-rose-100 animate-in fade-in duration-200">
<div className="text-[10px] font-black text-rose-800 uppercase tracking-widest flex items-center gap-1.5">
<Heart className="w-3.5 h-3.5 fill-rose-500 text-rose-500" />
<span>Charity Drive Metadata (Dubai Support)</span>
<span>{t('charity_drive_metadata', 'Charity Drive Metadata (Dubai Support)')}</span>
</div>
<div className="grid grid-cols-2 gap-3">
<div className="space-y-1">
<label className="text-[9px] font-black text-slate-500 uppercase tracking-widest ml-1">Event Date</label>
<label className="text-[9px] font-black text-slate-500 uppercase tracking-widest ml-1">{t('event_date', 'Event Date')}</label>
<input
type="date"
required
@ -161,11 +163,11 @@ export default function Announcements({ initialAnnouncements }) {
/>
</div>
<div className="space-y-1">
<label className="text-[9px] font-black text-slate-500 uppercase tracking-widest ml-1">Event Time</label>
<label className="text-[9px] font-black text-slate-500 uppercase tracking-widest ml-1">{t('event_time', 'Event Time')}</label>
<input
type="text"
required
placeholder="e.g. 9:00 AM - 4:00 PM"
placeholder={t('event_time_placeholder', 'e.g. 9:00 AM - 4:00 PM')}
value={newAnnouncement.event_time}
onChange={(e) => setNewAnnouncement({ ...newAnnouncement, event_time: e.target.value })}
className="w-full px-3 py-2 bg-white border border-slate-200 rounded-xl text-xs font-bold focus:ring-2 focus:ring-rose-100 outline-none"
@ -174,11 +176,11 @@ export default function Announcements({ initialAnnouncements }) {
</div>
<div className="space-y-1">
<label className="text-[9px] font-black text-slate-500 uppercase tracking-widest ml-1">What is Being Provided</label>
<label className="text-[9px] font-black text-slate-500 uppercase tracking-widest ml-1">{t('what_is_provided', 'What is Being Provided')}</label>
<input
type="text"
required
placeholder="e.g. Free Medical Check, Food Boxes, Supplies"
placeholder={t('provided_items_placeholder', 'e.g. Free Medical Check, Food Boxes, Supplies')}
value={newAnnouncement.provided_items}
onChange={(e) => setNewAnnouncement({ ...newAnnouncement, provided_items: e.target.value })}
className="w-full px-3.5 py-2.5 bg-white border border-slate-200 rounded-xl text-xs font-bold focus:ring-2 focus:ring-rose-100 outline-none"
@ -186,11 +188,11 @@ export default function Announcements({ initialAnnouncements }) {
</div>
<div className="space-y-1">
<label className="text-[9px] font-black text-slate-500 uppercase tracking-widest ml-1">Location Details & Pin URL</label>
<label className="text-[9px] font-black text-slate-500 uppercase tracking-widest ml-1">{t('location_details_pin', 'Location Details & Pin URL')}</label>
<input
type="text"
required
placeholder="e.g. Al Quoz Community Center, Dubai"
placeholder={t('location_details_placeholder', 'e.g. Al Quoz Community Center, Dubai')}
value={newAnnouncement.location_details}
onChange={(e) => setNewAnnouncement({ ...newAnnouncement, location_details: e.target.value })}
className="w-full px-3.5 py-2.5 bg-white border border-slate-200 rounded-xl text-xs font-bold focus:ring-2 focus:ring-rose-100 outline-none mb-2"
@ -198,7 +200,7 @@ export default function Announcements({ initialAnnouncements }) {
<input
type="url"
required
placeholder="Google Maps Pin Link (e.g. https://maps.app.goo.gl/xyz)"
placeholder={t('maps_pin_link_placeholder', 'Google Maps Pin Link (e.g. https://maps.app.goo.gl/xyz)')}
value={newAnnouncement.location_pin}
onChange={(e) => setNewAnnouncement({ ...newAnnouncement, location_pin: e.target.value })}
className="w-full px-3.5 py-2.5 bg-white border border-slate-200 rounded-xl text-xs font-bold focus:ring-2 focus:ring-rose-100 outline-none"
@ -207,26 +209,26 @@ export default function Announcements({ initialAnnouncements }) {
</div>
<div className="space-y-2">
<label className="text-[10px] font-black text-slate-500 uppercase tracking-widest ml-1">Title</label>
<label className="text-[10px] font-black text-slate-500 uppercase tracking-widest ml-1">{t('title_label', 'Title')}</label>
<input
type="text"
required
value={newAnnouncement.title}
onChange={(e) => setNewAnnouncement({ ...newAnnouncement, title: e.target.value })}
className="w-full px-5 py-3.5 bg-slate-50 border-none rounded-2xl text-sm font-bold focus:ring-2 focus:ring-blue-100 transition-all outline-none"
placeholder="e.g. Free Dental checkup by Emirates Charity"
placeholder={t('title_placeholder', 'e.g. Free Dental checkup by Emirates Charity')}
/>
</div>
<div className="space-y-2">
<label className="text-[10px] font-black text-slate-500 uppercase tracking-widest ml-1">Event Description & Instructions</label>
<label className="text-[10px] font-black text-slate-500 uppercase tracking-widest ml-1">{t('event_desc_instructions', 'Event Description & Instructions')}</label>
<textarea
required
rows="3"
value={newAnnouncement.content}
onChange={(e) => setNewAnnouncement({ ...newAnnouncement, content: e.target.value })}
className="w-full px-5 py-4 bg-slate-50 border-none rounded-2xl text-sm font-bold focus:ring-2 focus:ring-blue-100 transition-all outline-none resize-none"
placeholder="Enter details of the charity event here..."
placeholder={t('event_desc_placeholder', 'Enter details of the charity event here...')}
></textarea>
</div>
@ -237,7 +239,7 @@ export default function Announcements({ initialAnnouncements }) {
className="w-full bg-rose-600 hover:bg-rose-700 text-white py-4 rounded-2xl text-xs font-black uppercase tracking-widest flex items-center justify-center space-x-2 transition-all shadow-lg shadow-rose-200/50"
>
<Send className="w-4 h-4" />
<span>Publish Charity Event</span>
<span>{t('publish_charity_event', 'Publish Charity Event')}</span>
</button>
</DialogFooter>
</form>
@ -251,8 +253,8 @@ export default function Announcements({ initialAnnouncements }) {
<div className="w-20 h-20 bg-slate-50 rounded-full flex items-center justify-center mx-auto mb-6">
<Megaphone className="w-10 h-10 text-slate-200" />
</div>
<h3 className="font-black text-slate-900 text-lg uppercase tracking-tight">No announcements</h3>
<p className="font-bold text-xs text-slate-400 mt-1 uppercase tracking-widest">You haven't posted any announcements yet</p>
<h3 className="font-black text-slate-900 text-lg uppercase tracking-tight">{t('no_announcements_title', 'No Announcements')}</h3>
<p className="font-bold text-xs text-slate-400 mt-1 uppercase tracking-widest">{t('no_announcements_desc', "You haven't posted any announcements yet")}</p>
</div>
) : (
filteredAnnouncements.map((ann) => {
@ -269,7 +271,7 @@ export default function Announcements({ initialAnnouncements }) {
<div className="flex flex-wrap items-center gap-3">
<span className="px-3 py-1.5 rounded-xl text-[9px] font-black uppercase tracking-widest border bg-rose-50 border-rose-100 text-rose-700 flex items-center space-x-1">
<Heart className="w-3 h-3 fill-rose-500 text-rose-500" />
<span>COMMUNITY CHARITY DRIVE</span>
<span>{t('community_charity_drive', 'COMMUNITY CHARITY DRIVE')}</span>
</span>
<div className="flex items-center text-slate-400 text-[10px] font-black uppercase tracking-widest">
@ -279,7 +281,7 @@ export default function Announcements({ initialAnnouncements }) {
<div className="inline-flex items-center space-x-1 px-2.5 py-1 bg-emerald-50 rounded-lg text-[9px] font-bold text-emerald-800 border border-emerald-100">
<BellRing className="w-3 h-3 text-emerald-600 animate-bounce" />
<span>Push & Reminder Scheduled</span>
<span>{t('push_reminder_scheduled', 'Push & Reminder Scheduled')}</span>
</div>
</div>
@ -298,7 +300,7 @@ export default function Announcements({ initialAnnouncements }) {
<Heart className="w-4 h-4 fill-rose-500 text-rose-500" />
</div>
<div>
<div className="text-[9px] text-slate-400 uppercase font-black tracking-widest">Provided Packages</div>
<div className="text-[9px] text-slate-400 uppercase font-black tracking-widest">{t('provided_packages', 'Provided Packages')}</div>
<div className="text-slate-800 text-[11px] font-extrabold mt-0.5">{details.provided_items}</div>
</div>
</div>
@ -308,7 +310,7 @@ export default function Announcements({ initialAnnouncements }) {
<Clock className="w-4 h-4" />
</div>
<div>
<div className="text-[9px] text-slate-400 uppercase font-black tracking-widest">Event Timing</div>
<div className="text-[9px] text-slate-400 uppercase font-black tracking-widest">{t('event_timing', 'Event Timing')}</div>
<div className="text-slate-800 text-[11px] font-extrabold mt-0.5">
{details.event_date} {details.event_time}
</div>
@ -321,7 +323,7 @@ export default function Announcements({ initialAnnouncements }) {
</div>
<div className="flex-1 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2">
<div>
<div className="text-[9px] text-slate-400 uppercase font-black tracking-widest">Event Location Address</div>
<div className="text-[9px] text-slate-400 uppercase font-black tracking-widest">{t('event_location_address', 'Event Location Address')}</div>
<div className="text-slate-800 text-[11px] font-extrabold mt-0.5">{details.location_details}</div>
</div>
{details.location_pin && (
@ -332,7 +334,7 @@ export default function Announcements({ initialAnnouncements }) {
className="px-3.5 py-2 bg-rose-600 hover:bg-rose-700 text-white rounded-xl text-[10px] font-black uppercase tracking-wider flex items-center space-x-1 w-fit transition-colors shrink-0 shadow-sm"
>
<MapPin className="w-3.5 h-3.5" />
<span>View Map Location Pin</span>
<span>{t('view_map_location_pin', 'View Map Location Pin')}</span>
</a>
)}
</div>

View File

@ -1,6 +1,7 @@
import React from 'react';
import { Head, Link } from '@inertiajs/react';
import EmployerLayout from '../../Layouts/EmployerLayout';
import { useTranslation } from '../../lib/LanguageContext';
import {
Bookmark,
MessageSquare,
@ -38,10 +39,11 @@ export default function Dashboard({
}) {
const isSubActive = employer.subscription_status === 'active';
const isExpiringSoon = stats.days_remaining <= 7;
const { t } = useTranslation();
return (
<EmployerLayout title="Sponsor Control Center">
<Head title="Sponsor Dashboard - Verified UAE Domestic Workers" />
<EmployerLayout title={t('control_center', 'Sponsor Control Center')}>
<Head title={t('dashboard_title', 'Sponsor Dashboard - Verified UAE Domestic Workers')} />
<div className="space-y-8 pb-12">
{/* 1. Alerts & Warning Banners */}
@ -52,15 +54,15 @@ export default function Dashboard({
<Lock className="w-6 h-6" />
</div>
<div>
<h4 className="font-black text-sm text-slate-900">Your Sponsor Subscription Pass Has Expired!</h4>
<p className="text-xs text-slate-500 font-bold mt-1">Direct communication, candidate dossiers, and messaging are locked. Renew your annual sponsor subscription now to resume hiring.</p>
<h4 className="font-black text-sm text-slate-900">{t('expired_pass_title', 'Your Sponsor Subscription Pass Has Expired!')}</h4>
<p className="text-xs text-slate-500 font-bold mt-1">{t('expired_pass_desc', 'Direct communication, candidate dossiers, and messaging are locked. Renew your annual sponsor subscription now to resume hiring.')}</p>
</div>
</div>
<Link
href="/employer/subscription"
className="bg-rose-600 hover:bg-rose-700 text-white px-5 py-3 rounded-xl text-xs font-black uppercase tracking-wider transition-all shadow-md shadow-rose-600/20 flex items-center space-x-1.5 shrink-0"
>
<span>Renew Subscription</span>
<span>{t('renew_sub', 'Renew Subscription')}</span>
<ArrowRight className="w-4 h-4" />
</Link>
</div>
@ -73,15 +75,17 @@ export default function Dashboard({
<AlertTriangle className="w-5 h-5 animate-pulse" />
</div>
<div>
<h4 className="font-bold text-sm text-slate-800">Your Premium Sponsor Pass is expiring soon!</h4>
<p className="text-xs text-slate-500 font-medium">Only {stats.days_remaining} days left. Renew now to avoid losing contact access to 500+ verified candidates.</p>
<h4 className="font-bold text-sm text-slate-800">{t('expiring_pass_title', 'Your Premium Sponsor Pass is expiring soon!')}</h4>
<p className="text-xs text-slate-500 font-medium">
{t('expiring_pass_desc', 'Only {days} days left. Renew now to avoid losing contact access to 500+ verified candidates.').replace('{days}', stats.days_remaining)}
</p>
</div>
</div>
<Link
href="/employer/subscription"
className="bg-amber-600 hover:bg-amber-700 text-white px-4 py-2 rounded-xl text-xs font-bold transition-all shadow-sm flex items-center space-x-1"
>
<span>Renew Now</span>
<span>{t('renew_now', 'Renew Now')}</span>
<ArrowRight className="w-3.5 h-3.5" />
</Link>
</div>
@ -95,17 +99,17 @@ export default function Dashboard({
<div className="space-y-4 z-10 max-w-2xl">
<div className="inline-flex items-center space-x-2 px-3 py-1 bg-white/10 rounded-full text-xs font-semibold backdrop-blur-md border border-white/10">
<span className="w-2 h-2 rounded-full bg-emerald-400 animate-pulse" />
<span>Subscription Status: <span className="text-emerald-300 font-bold uppercase">{employer.subscription_status}</span></span>
<span>{t('sub_status', 'Subscription Status')}: <span className="text-emerald-300 font-bold uppercase">{employer.subscription_status}</span></span>
<span className="text-blue-300">|</span>
<span>{stats.days_remaining} Days Left</span>
<span>{stats.days_remaining} {t('days_left', 'Days Left')}</span>
</div>
<h1 className="text-3xl sm:text-4xl font-black tracking-tight">
Welcome Back, {employer.name}
{t('welcome_back', 'Welcome Back')}, {employer.name}
</h1>
<p className="text-blue-100 text-sm leading-relaxed font-medium">
Hire direct, MOHRE-compliant domestic workers with zero middleman commissions. Browse our updated database of candidates with OCR passport checks.
{t('welcome_desc_dash', 'Hire direct, MOHRE-compliant domestic workers with zero middleman commissions. Browse our updated database of candidates with OCR passport checks.')}
</p>
</div>
@ -115,7 +119,7 @@ export default function Dashboard({
className="bg-white text-[#185FA5] hover:bg-slate-100 px-6 py-3.5 rounded-xl font-bold text-xs shadow-md transition-all flex items-center justify-center space-x-2 group"
>
<Search className="w-4 h-4 text-[#185FA5] group-hover:scale-110 transition-transform" />
<span>Browse 500+ Verified Workers</span>
<span>{t('browse_workers', 'Browse 500+ Verified Workers')}</span>
<ArrowRight className="w-4 h-4 group-hover:translate-x-1 transition-transform" />
</Link>
</div>
@ -134,12 +138,12 @@ export default function Dashboard({
</span>
</div>
<div>
<div className="text-xs font-semibold text-slate-400 uppercase tracking-widest">Sponsor Pass Tier</div>
<div className="text-xs font-semibold text-slate-400 uppercase tracking-widest">{t('sponsor_pass_tier', 'Sponsor Pass Tier')}</div>
<div className="text-lg font-bold text-slate-800 mt-1">{employer.plan_name}</div>
<div className="text-[11px] text-slate-500 font-medium mt-1">Renews: {employer.subscription_expires_at}</div>
<div className="text-[11px] text-slate-500 font-medium mt-1">{t('renews', 'Renews')}: {employer.subscription_expires_at}</div>
</div>
<Link href="/employer/subscription" className="text-xs font-bold text-[#185FA5] hover:underline flex items-center space-x-1 pt-2 border-t border-slate-100">
<span>Manage billing & invoices</span>
<span>{t('manage_billing', 'Manage billing & invoices')}</span>
<ChevronRight className="w-3.5 h-3.5" />
</Link>
</div>
@ -155,12 +159,12 @@ export default function Dashboard({
</span>
</div>
<div>
<div className="text-xs font-semibold text-slate-400 uppercase tracking-widest">Pending Job Offers</div>
<div className="text-xs font-semibold text-slate-400 uppercase tracking-widest">{t('pending_job_offers', 'Pending Job Offers')}</div>
<div className="text-3xl font-black text-slate-800 mt-1">{stats.pending_offers}</div>
<div className="text-[11px] text-slate-500 font-medium mt-1">Direct recruitment proposals</div>
<div className="text-[11px] text-slate-500 font-medium mt-1">{t('direct_recruitment', 'Direct recruitment proposals')}</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>View hiring workflow</span>
<span>{t('view_hiring', 'View hiring workflow')}</span>
<ChevronRight className="w-3.5 h-3.5" />
</Link>
</div>
@ -176,12 +180,12 @@ export default function Dashboard({
</span>
</div>
<div>
<div className="text-xs font-semibold text-slate-400 uppercase tracking-widest">Total Hired Workers</div>
<div className="text-xs font-semibold text-slate-400 uppercase tracking-widest">{t('total_hired_workers', 'Total Hired Workers')}</div>
<div className="text-3xl font-black text-slate-800 mt-1">{stats.hired_count}</div>
<div className="text-[11px] text-slate-500 font-medium mt-1">Direct contracts initiated</div>
<div className="text-[11px] text-slate-500 font-medium mt-1">{t('direct_contracts', 'Direct contracts initiated')}</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>Track active staff</span>
<span>{t('track_active_staff', 'Track active staff')}</span>
<ChevronRight className="w-3.5 h-3.5" />
</Link>
</div>
@ -197,12 +201,12 @@ export default function Dashboard({
</span>
</div>
<div>
<div className="text-xs font-semibold text-slate-400 uppercase tracking-widest">Shortlisted Candidates</div>
<div className="text-xs font-semibold text-slate-400 uppercase tracking-widest">{t('shortlisted_candidates', 'Shortlisted Candidates')}</div>
<div className="text-3xl font-black text-slate-800 mt-1">{stats.shortlisted_count}</div>
<div className="text-[11px] text-slate-500 font-medium mt-1">Bookmark list for interviews</div>
<div className="text-[11px] text-slate-500 font-medium mt-1">{t('bookmark_list', 'Bookmark list for interviews')}</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">
<span>Open shortlist book</span>
<span>{t('open_shortlist', 'Open shortlist book')}</span>
<ChevronRight className="w-3.5 h-3.5" />
</Link>
</div>
@ -215,45 +219,45 @@ export default function Dashboard({
<div className="pb-3 border-b border-slate-100">
<div className="flex items-center space-x-2">
<Activity className="w-5 h-5 text-[#185FA5]" />
<h3 className="font-extrabold text-base text-slate-900">Discover Insights & Market Stats</h3>
<h3 className="font-extrabold text-base text-slate-900">{t('discover_insights', 'Discover Insights & Market Stats')}</h3>
</div>
</div>
<div className="space-y-6">
{/* Dubai General Market Stats */}
<div className="space-y-3">
<div className="text-[10px] font-black text-slate-400 uppercase tracking-widest pl-1">Dubai General Market Insights</div>
<div className="text-[10px] font-black text-slate-400 uppercase tracking-widest pl-1">{t('dubai_insights', 'Dubai General Market Insights')}</div>
<div className="grid grid-cols-3 gap-4 text-center">
<div className="p-4 bg-slate-50 rounded-2xl border border-slate-100 flex flex-col justify-between">
<div className="text-xl font-black text-slate-900">1,284</div>
<div className="text-[9px] text-slate-500 font-bold uppercase tracking-wider mt-1">Hired using app in Dubai</div>
<div className="text-[9px] text-slate-500 font-bold uppercase tracking-wider mt-1">{t('hired_dubai', 'Hired using app in Dubai')}</div>
</div>
<div className="p-4 bg-slate-50 rounded-2xl border border-slate-100 flex flex-col justify-between">
<div className="text-xs font-black text-[#185FA5] uppercase leading-snug">Cooking, Care, Driving</div>
<div className="text-[9px] text-slate-500 font-bold uppercase tracking-wider mt-1">Top Skills Hired</div>
<div className="text-xs font-black text-[#185FA5] uppercase leading-snug">{t('cooking_care', 'Cooking, Care, Driving')}</div>
<div className="text-[9px] text-slate-500 font-bold uppercase tracking-wider mt-1">{t('top_skills', 'Top Skills Hired')}</div>
</div>
<div className="p-4 bg-slate-50 rounded-2xl border border-slate-100 flex flex-col justify-between">
<div className="text-xl font-black text-emerald-600">1.4%</div>
<div className="text-[9px] text-slate-500 font-bold uppercase tracking-wider mt-1">Turnover rate</div>
<div className="text-[9px] text-slate-500 font-bold uppercase tracking-wider mt-1">{t('turnover_rate', 'Turnover rate')}</div>
</div>
</div>
</div>
{/* Your own activity */}
<div className="space-y-3">
<div className="text-[10px] font-black text-slate-400 uppercase tracking-widest pl-1">Your Sponsor Activity Stats</div>
<div className="text-[10px] font-black text-slate-400 uppercase tracking-widest pl-1">{t('sponsor_activity', 'Your Sponsor Activity Stats')}</div>
<div className="grid grid-cols-3 gap-4 text-center">
<div className="p-4 bg-blue-50/30 rounded-2xl border border-blue-100/50 flex flex-col justify-between">
<div className="text-2xl font-black text-slate-800">14</div>
<div className="text-[9px] text-slate-500 font-bold uppercase tracking-wider mt-1">Workers Contacted</div>
<div className="text-[9px] text-slate-500 font-bold uppercase tracking-wider mt-1">{t('workers_contacted', 'Workers Contacted')}</div>
</div>
<div className="p-4 bg-blue-50/30 rounded-2xl border border-blue-100/50 flex flex-col justify-between">
<div className="text-2xl font-black text-slate-800">{stats.shortlisted_count}</div>
<div className="text-[9px] text-slate-500 font-bold uppercase tracking-wider mt-1">Shortlisted</div>
<div className="text-[9px] text-slate-500 font-bold uppercase tracking-wider mt-1">{t('shortlist', 'Shortlist')}</div>
</div>
<div className="p-4 bg-blue-50/30 rounded-2xl border border-blue-100/50 flex flex-col justify-between">
<div className="text-2xl font-black text-emerald-600">{stats.hired_count}</div>
<div className="text-[9px] text-slate-500 font-bold uppercase tracking-wider mt-1">Secure Hires</div>
<div className="text-[9px] text-slate-500 font-bold uppercase tracking-wider mt-1">{t('secure_hires', 'Secure Hires')}</div>
</div>
</div>
</div>
@ -263,8 +267,8 @@ export default function Dashboard({
{/* 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">Quick Actions</h3>
<p className="text-xs text-slate-500 font-medium">Speed up your sponsorship process.</p>
<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">
@ -276,8 +280,8 @@ export default function Dashboard({
<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">Find Baby Care & Nannies</div>
<div className="text-[10px] text-slate-500 truncate">Browse premium verified nannies</div>
<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>
@ -292,17 +296,17 @@ export default function Dashboard({
</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>Direct WhatsApp Support</span>
<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">Chat with a recruitment manager</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>100% Legal UAE Agency-Free Platform</span>
<span>{t('legal_platform', '100% Legal UAE Agency-Free Platform')}</span>
</div>
</div>
</div>
@ -316,10 +320,10 @@ export default function Dashboard({
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<Sparkles className="w-5 h-5 text-amber-500 animate-pulse" />
<h3 className="font-bold text-base text-slate-900">Recommended for You</h3>
<h3 className="font-bold text-base text-slate-900">{t('recommended_for_you', 'Recommended for You')}</h3>
</div>
<Link href="/employer/workers" className="text-xs font-bold text-[#185FA5] hover:underline flex items-center space-x-0.5">
<span>Browse all</span>
<span>{t('browse_all', 'Browse all')}</span>
<ChevronRight className="w-4 h-4" />
</Link>
</div>
@ -364,14 +368,14 @@ export default function Dashboard({
href={`/employer/workers/${worker.id}`}
className="px-3 py-1.5 bg-[#185FA5] hover:bg-[#144f8a] text-white text-[10px] font-black rounded-lg transition-colors shadow-xs"
>
View Profile
{t('view_profile', 'View Profile')}
</Link>
</div>
</div>
))
) : (
<div className="col-span-3 text-center py-8 bg-slate-50 rounded-2xl border border-dashed border-slate-200 text-slate-400 text-xs">
No workers currently recommended. Update profile details.
{t('no_recommended', 'No workers currently recommended. Update profile details.')}
</div>
)}
</div>
@ -382,10 +386,10 @@ export default function Dashboard({
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<Bookmark className="w-5 h-5 text-[#185FA5]" />
<h3 className="font-bold text-base text-slate-900">Active Shortlist ({shortlisted_workers.length})</h3>
<h3 className="font-bold text-base text-slate-900">{t('active_shortlist', 'Active Shortlist')} ({shortlisted_workers.length})</h3>
</div>
<Link href="/employer/shortlist" className="text-xs font-bold text-[#185FA5] hover:underline flex items-center space-x-0.5">
<span>View book</span>
<span>{t('view_book', 'View book')}</span>
<ChevronRight className="w-4 h-4" />
</Link>
</div>
@ -408,14 +412,14 @@ export default function Dashboard({
</div>
<div className="space-y-1">
<div className="text-[10px] font-semibold text-slate-400 uppercase tracking-tighter">Category:</div>
<div className="text-[10px] font-semibold text-slate-400 uppercase tracking-tighter">{t('category', 'Category')}:</div>
<div className="inline-block px-2 py-0.5 bg-white border border-slate-200 rounded-md text-xs font-semibold text-slate-700">
{worker.category || 'General Helper'}
</div>
</div>
<div className="pt-2 border-t border-slate-200/80 flex items-center justify-between text-xs">
<span className="text-[10px] text-slate-400 font-bold uppercase">AVAILABILITY:</span>
<span className="text-[10px] text-slate-400 font-bold uppercase">{t('availability', 'Availability')}:</span>
<span className="font-bold text-[#185FA5] bg-blue-50 px-2 py-0.5 rounded text-[10px] border border-blue-100">
{worker.availability}
</span>
@ -425,7 +429,7 @@ export default function Dashboard({
href={`/employer/workers/${worker.id}`}
className="w-full mt-2 bg-white hover:bg-slate-50 text-[#185FA5] border border-slate-200 text-center rounded-lg py-1.5 text-[10px] font-black flex items-center justify-center transition-colors"
>
Open Profile
{t('open_profile', 'Open Profile')}
</Link>
</div>
))}
@ -433,7 +437,7 @@ export default function Dashboard({
) : (
<div className="text-center py-10 bg-slate-50 rounded-2xl border-2 border-dashed border-slate-200 space-y-2">
<Bookmark className="w-8 h-8 text-slate-300 mx-auto" />
<div className="text-xs font-bold text-slate-500">Shortlist candidates to compare their documents side-by-side</div>
<div className="text-xs font-bold text-slate-500">{t('shortlist_candidates_desc', 'Shortlist candidates to compare their documents side-by-side')}</div>
</div>
)}
</div>
@ -443,10 +447,10 @@ export default function Dashboard({
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<MessageSquare className="w-5 h-5 text-[#185FA5]" />
<h3 className="font-bold text-base text-slate-900">Recent Chats</h3>
<h3 className="font-bold text-base text-slate-900">{t('recent_chats', 'Recent Chats')}</h3>
</div>
<Link href="/employer/messages" className="text-xs font-bold text-[#185FA5] hover:underline flex items-center space-x-0.5">
<span>All channels</span>
<span>{t('all_channels', 'All channels')}</span>
<ChevronRight className="w-4 h-4" />
</Link>
</div>
@ -482,7 +486,7 @@ export default function Dashboard({
))
) : (
<div className="text-center py-8 text-xs text-slate-400">
No recent chat logs found. Find workers to start conversing.
{t('no_chats', 'No recent chat logs found. Find workers to start conversing.')}
</div>
)}
</div>
@ -496,10 +500,10 @@ export default function Dashboard({
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<Heart className="w-5 h-5 text-rose-500 fill-rose-500/20" />
<h3 className="font-extrabold text-base text-slate-900">Community Charity Drives</h3>
<h3 className="font-extrabold text-base text-slate-900">{t('charity_drives', 'Community Charity Drives')}</h3>
</div>
<span className="text-[9px] font-black bg-rose-50 text-rose-600 px-2 py-0.5 rounded-full uppercase tracking-wider">
Live Events
{t('live_events', 'Live Events')}
</span>
</div>
@ -507,7 +511,7 @@ export default function Dashboard({
{announcements?.map((ann) => (
<div key={ann.id} className="p-4 bg-rose-50/20 border border-rose-100/70 rounded-2xl space-y-3 relative group hover:border-rose-300 hover:bg-white transition-all">
<div className="flex items-center justify-between text-[9px] font-bold text-rose-600 uppercase tracking-wider">
<span> Charity Drive</span>
<span> {t('charity_drive', 'Charity Drive')}</span>
<span>{ann.created_at}</span>
</div>
<div>
@ -519,11 +523,11 @@ export default function Dashboard({
<div className="grid grid-cols-2 gap-2 text-[10px] bg-slate-50/60 p-2.5 rounded-xl border border-slate-100 font-bold text-slate-600">
<div className="flex items-center space-x-1 truncate">
<span>🎁</span>
<span className="truncate">{ann.provided_items}</span>
<span className="truncate">{t('provided_items', 'Provided Items')}: {ann.provided_items}</span>
</div>
<div className="flex items-center space-x-1 truncate">
<span>📅</span>
<span className="truncate">{ann.event_date}</span>
<span className="truncate">{t('event_date', 'Event Date')}: {ann.event_date}</span>
</div>
</div>
@ -534,7 +538,7 @@ export default function Dashboard({
rel="noopener noreferrer"
className="w-full bg-white hover:bg-rose-50 text-rose-600 border border-rose-200 text-center rounded-lg py-1.5 text-[10px] font-black flex items-center justify-center space-x-1 transition-colors"
>
<span>📍 Open Google Maps Location Pin</span>
<span>📍 {t('open_maps', 'Open Google Maps Location Pin')}</span>
</a>
)}
</div>
@ -549,9 +553,9 @@ export default function Dashboard({
<ShieldCheck className="w-6 h-6 text-emerald-400" />
</div>
<div className="space-y-2">
<h4 className="font-bold text-sm tracking-tight text-white">UAE Tadbeer & MOHRE Compliant</h4>
<h4 className="font-bold text-sm tracking-tight text-white">{t('mohre_compliant', 'UAE Tadbeer & MOHRE Compliant')}</h4>
<p className="text-[11px] text-blue-200 leading-relaxed font-medium">
Our direct contract system aligns automatically with the Ministry of Human Resources and Emiratisation guidelines. Fully legal, zero agent fees, complete transparency.
{t('mohre_desc', 'Our direct contract system aligns automatically with the Ministry of Human Resources and Emiratisation guidelines. Fully legal, zero agent fees, complete transparency.')}
</p>
</div>
<div className="pt-2">
@ -561,7 +565,7 @@ export default function Dashboard({
rel="noreferrer"
className="text-xs font-bold text-emerald-400 hover:text-emerald-300 flex items-center space-x-1"
>
<span>Visit MOHRE UAE website</span>
<span>{t('visit_mohre', 'Visit MOHRE UAE website')}</span>
<ArrowRight className="w-3.5 h-3.5" />
</a>
</div>

View File

@ -2,11 +2,14 @@ import React from 'react';
import { Head, Link } from '@inertiajs/react';
import EmployerLayout from '../../../Layouts/EmployerLayout';
import { MessageSquare, CheckCircle2, ChevronRight, Search, Plus } from 'lucide-react';
import { useTranslation } from '../../../lib/LanguageContext';
export default function Index({ conversations }) {
const { t } = useTranslation();
return (
<EmployerLayout title="Candidate Messages">
<Head title="Messages - Employer Portal" />
<EmployerLayout title={t('candidate_messages', 'Candidate Messages')}>
<Head title={t('messages_employer_portal', 'Messages - Employer Portal')} />
<div className="max-w-5xl mx-auto space-y-6 select-none">
{/* Header Actions */}
@ -15,7 +18,7 @@ export default function Index({ conversations }) {
<Search className="absolute left-3.5 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" />
<input
type="text"
placeholder="Search conversations..."
placeholder={t('search_conversations_placeholder', 'Search conversations...')}
className="w-full pl-10 pr-4 py-2.5 rounded-2xl border border-slate-200 text-sm focus:outline-none focus:ring-2 focus:ring-[#185FA5]/20 focus:border-[#185FA5] shadow-sm transition-all bg-white/80 backdrop-blur-sm"
/>
</div>
@ -24,7 +27,7 @@ export default function Index({ conversations }) {
className="bg-white hover:bg-slate-50 border border-slate-200 text-[#185FA5] px-4 py-2.5 rounded-2xl text-sm font-bold shadow-sm transition-all flex items-center justify-center space-x-2 whitespace-nowrap"
>
<Plus className="w-4 h-4" />
<span>New Conversation</span>
<span>{t('new_conversation', 'New Conversation')}</span>
</Link>
</div>
@ -32,10 +35,10 @@ export default function Index({ conversations }) {
<div className="p-6 border-b border-slate-100 flex items-center justify-between bg-slate-50/50">
<div className="flex items-center space-x-2">
<MessageSquare className="w-5 h-5 text-[#185FA5]" />
<h2 className="font-extrabold text-lg text-slate-800 tracking-tight">Active Threads</h2>
<h2 className="font-extrabold text-lg text-slate-800 tracking-tight">{t('active_threads', 'Active Threads')}</h2>
</div>
<span className="px-3 py-1 bg-white border border-slate-200 rounded-full text-xs text-slate-600 font-bold shadow-sm">
{conversations?.length || 0} Total
{t('total_count', '{count} Total').replace('{count}', conversations?.length || 0)}
</span>
</div>
@ -96,15 +99,15 @@ export default function Index({ conversations }) {
<div className="w-16 h-16 bg-white rounded-3xl shadow-sm border border-slate-100 flex items-center justify-center mx-auto mb-2">
<MessageSquare className="w-8 h-8 text-slate-300" />
</div>
<div className="text-lg font-extrabold text-slate-800">No active messages</div>
<div className="text-lg font-extrabold text-slate-800">{t('no_active_messages', 'No active messages')}</div>
<p className="text-sm text-slate-500 max-w-sm mx-auto leading-relaxed">
When you message workers or schedule interviews, your conversation threads will appear here.
{t('no_active_messages_desc', 'When you message workers or schedule interviews, your conversation threads will appear here.')}
</p>
<Link
href="/employer/workers"
className="inline-block mt-4 bg-[#185FA5] text-white px-6 py-2.5 rounded-xl text-sm font-bold shadow-md shadow-blue-900/20 hover:-translate-y-0.5 active:translate-y-0 transition-all"
>
Find Workers
{t('find_workers', 'Find Workers')}
</Link>
</div>
)}

View File

@ -1,6 +1,7 @@
import React, { useState, useEffect, useRef } from 'react';
import { Head, Link, router } from '@inertiajs/react';
import EmployerLayout from '../../../Layouts/EmployerLayout';
import { useTranslation } from '../../../lib/LanguageContext';
import {
Send,
ArrowLeft,
@ -29,6 +30,7 @@ import {
import { toast } from 'sonner';
export default function Show({ conversation, initialMessages, conversations = [] }) {
const { t } = useTranslation();
const [messages, setMessages] = useState(initialMessages || []);
const [input, setInput] = useState('');
const [isTyping, setIsTyping] = useState(false);
@ -69,7 +71,7 @@ export default function Show({ conversation, initialMessages, conversations = []
id: Date.now(),
sender: 'employer',
text: text,
time: 'Just Now',
time: t('just_now', 'Just Now'),
read: false
};
setMessages(prev => [...prev, newMsg]);
@ -81,8 +83,8 @@ export default function Show({ conversation, initialMessages, conversations = []
preserveScroll: true,
onSuccess: () => {
// Show immediate confirmation of the push alert popping up on worker mobile app
toast.success(`🔔 Direct Mobile Push Notification sent!`, {
description: `Popped up instantly on ${conversation.worker_name}'s mobile device.`,
toast.success(t('direct_push_sent', 'Direct Mobile Push Notification sent!'), {
description: t('popped_up_instantly_desc', "Popped up instantly on {name}'s mobile device.").replace('{name}', conversation.worker_name),
duration: 4500,
});
@ -94,13 +96,13 @@ export default function Show({ conversation, initialMessages, conversations = []
const autoReply = {
id: Date.now() + 1,
sender: 'worker',
text: "Thank you for your response! I have reviewed your offer proposal and am looking forward to our video interview.",
time: 'Just Now'
text: t('auto_reply_text', "Thank you for your response! I have reviewed your offer proposal and am looking forward to our video interview."),
time: t('just_now', 'Just Now')
};
setMessages(prev => [...prev, autoReply]);
// Pop up a clear message received notification for the sponsor
toast.info(`✉️ New message from ${conversation.worker_name}!`, {
toast.info(t('new_message_from', 'New message from {name}!').replace('{name}', conversation.worker_name), {
description: autoReply.text,
duration: 5000
});
@ -122,41 +124,41 @@ export default function Show({ conversation, initialMessages, conversations = []
const newFile = {
name: file.name,
size: (file.size / 1024).toFixed(1) + ' KB',
date: 'Today'
date: t('today', 'Today')
};
setUploadedFiles([...uploadedFiles, newFile]);
toast.success("📎 Document attached successfully!");
toast.success(t('document_attached', 'Document attached successfully!'));
setShowAttachmentModal(false);
// Optimistically insert attachment message
sendMsg(`[Document Attached: ${file.name}]`);
sendMsg(`[${t('document_attached_msg', 'Document Attached')}: ${file.name}]`);
};
const chips = [
"Are you available for a video interview today?",
"What is your final expected salary?",
"Can you transfer your visa immediately?"
t('chip_interview', "Are you available for a video interview today?"),
t('chip_salary', "What is your final expected salary?"),
t('chip_visa', "Can you transfer your visa immediately?")
];
return (
<EmployerLayout title={null} fullPage={true}>
<Head title={`Chat with ${conversation.worker_name} - Messages`} />
<Head title={`${t('chat_with', 'Chat with')} ${conversation.worker_name} - ${t('messages', 'Messages')}`} />
<div className="flex h-full bg-[#FAFBFF] overflow-hidden select-none w-full">
{/* Conversation List Sidebar (Desktop) */}
<aside className="hidden xl:flex w-90 border-r border-slate-200 flex-col flex-shrink-0 bg-white shadow-sm z-30">
<div className="p-6 border-b border-slate-100">
<div className="flex items-center justify-between mb-6">
<h2 className="font-black text-2xl text-slate-900 tracking-tight">Messages Hub</h2>
<h2 className="font-black text-2xl text-slate-900 tracking-tight">{t('messages_hub', 'Messages Hub')}</h2>
<span className="text-[9px] font-black bg-emerald-50 text-emerald-700 px-2 py-0.5 rounded uppercase tracking-wider">
SSL SECURE
{t('ssl_secure', 'SSL SECURE')}
</span>
</div>
<div className="relative">
<input
type="text"
placeholder="Search conversations..."
placeholder={t('search_conversations_placeholder', 'Search conversations...')}
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="w-full pl-5 pr-4 py-3 bg-slate-50 border-none rounded-2xl text-sm font-bold focus:ring-2 focus:ring-blue-100 transition-all placeholder:text-slate-400 outline-none"
@ -234,7 +236,7 @@ export default function Show({ conversation, initialMessages, conversations = []
</div>
<div className="flex items-center space-x-1.5 mt-0.5">
<span className="text-[9px] font-black text-slate-400 uppercase tracking-widest">
Active Now
{t('active_now', 'Active Now')}
</span>
</div>
</div>
@ -249,7 +251,7 @@ export default function Show({ conversation, initialMessages, conversations = []
className="px-3.5 py-2 bg-emerald-50 text-emerald-800 border border-emerald-200 hover:bg-emerald-100 rounded-xl transition-all shadow-xs flex items-center space-x-1.5 text-xs font-bold"
>
<MessageSquare className="w-4 h-4 text-emerald-600 fill-emerald-600" />
<span className="hidden sm:inline">WhatsApp Bridge</span>
<span className="hidden sm:inline">{t('whatsapp_bridge', 'WhatsApp Bridge')}</span>
</a>
<button
@ -270,7 +272,7 @@ export default function Show({ conversation, initialMessages, conversations = []
<div className="flex-1 px-6 py-6 overflow-y-auto bg-[#F8FAFC]/60 space-y-6 scroll-smooth">
<div className="flex flex-col items-center mb-6">
<div className="bg-white border border-slate-200 px-4 py-1.5 rounded-full shadow-xs">
<span className="text-[9px] font-black text-slate-400 uppercase tracking-widest">Today Realtime Chat Logs</span>
<span className="text-[9px] font-black text-slate-400 uppercase tracking-widest">{t('today_realtime_chat_logs', 'Today • Realtime Chat Logs')}</span>
</div>
</div>
@ -294,7 +296,7 @@ export default function Show({ conversation, initialMessages, conversations = []
{isEmp && (
<span className="flex items-center space-x-0.5 text-emerald-600">
<span></span>
<span>Read</span>
<span>{t('read', 'Read')}</span>
<CheckCircle2 className="w-2.5 h-2.5" />
</span>
)}
@ -345,7 +347,7 @@ export default function Show({ conversation, initialMessages, conversations = []
<input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Type a compliant secure message..."
placeholder={t('type_message_placeholder', 'Type a compliant secure message...')}
className="flex-1 px-5 py-3.5 bg-slate-50 rounded-xl text-xs font-semibold outline-none border border-transparent focus:border-slate-200 transition-all"
/>
<button
@ -381,23 +383,23 @@ export default function Show({ conversation, initialMessages, conversations = []
<div className="grid grid-cols-2 gap-2 text-center text-xs font-bold">
<div className="bg-slate-50/70 p-3 rounded-xl border border-slate-100">
<DollarSign className="w-3.5 h-3.5 text-emerald-600 mx-auto mb-1" />
<div className="text-[8px] font-black text-slate-400 uppercase tracking-widest">Expected</div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-widest">{t('expected', 'Expected')}</div>
<div className="text-slate-800 mt-0.5 truncate">{conversation.salary}</div>
</div>
<div className="bg-slate-50/70 p-3 rounded-xl border border-slate-100">
<MapPin className="w-3.5 h-3.5 text-blue-600 mx-auto mb-1" />
<div className="text-[8px] font-black text-slate-400 uppercase tracking-widest">Region</div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-widest">{t('region', 'Region')}</div>
<div className="text-slate-800 mt-0.5 truncate">{conversation.nationality}</div>
</div>
</div>
<div className="space-y-3">
<h5 className="text-[9px] font-black text-slate-400 uppercase tracking-widest pl-1">Compliance Profile</h5>
<h5 className="text-[9px] font-black text-slate-400 uppercase tracking-widest pl-1">{t('compliance_profile', 'Compliance Profile')}</h5>
<div className="space-y-2">
{[
{ label: 'Visa Transfer', value: 'Transferable', icon: Briefcase, color: 'text-blue-500' },
{ label: 'Medical Status', value: 'Cleared', icon: ShieldCheck, color: 'text-emerald-500' },
{ label: 'Passport OCR', value: 'Verified', icon: FileText, color: 'text-slate-500' }
{ label: t('visa_transfer', 'Visa Transfer'), value: t('transferable', 'Transferable'), icon: Briefcase, color: 'text-blue-500' },
{ label: t('medical_status', 'Medical Status'), value: t('cleared', 'Cleared'), icon: ShieldCheck, color: 'text-emerald-500' },
{ label: t('passport_ocr', 'Passport OCR'), value: t('verified', 'Verified'), icon: FileText, color: 'text-slate-500' }
].map((item, i) => (
<div key={i} className="flex items-center justify-between p-3 bg-slate-50/40 border border-slate-100 rounded-xl text-[10px] font-bold text-slate-600">
<div className="flex items-center space-x-2">
@ -416,7 +418,7 @@ export default function Show({ conversation, initialMessages, conversations = []
className="w-full bg-[#185FA5] hover:bg-[#144f8a] text-white py-3 rounded-xl text-xs font-black uppercase tracking-widest flex items-center justify-center space-x-1.5 shadow-xs"
>
<Eye className="w-4 h-4" />
<span>Open Worker Profile</span>
<span>{t('open_worker_profile', 'Open Worker Profile')}</span>
</Link>
</div>
</div>
@ -435,14 +437,14 @@ export default function Show({ conversation, initialMessages, conversations = []
<X className="w-5 h-5" />
</button>
<h4 className="font-extrabold text-sm text-slate-900">Attach Verified Sponsor Documents</h4>
<h4 className="font-extrabold text-sm text-slate-900">{t('attach_sponsor_documents', 'Attach Verified Sponsor Documents')}</h4>
<p className="text-xs text-slate-500 font-medium leading-relaxed">
Upload sponsor papers, employment agreements, or work descriptions to review securely.
{t('attach_documents_desc', 'Upload sponsor papers, employment agreements, or work descriptions to review securely.')}
</p>
<div className="border-2 border-dashed border-slate-200 rounded-2xl p-6 text-center space-y-2 relative hover:border-[#185FA5] transition-all bg-slate-50/50">
<UploadCloud className="w-10 h-10 text-slate-350 mx-auto" />
<div className="text-xs font-bold text-slate-600">Select files or drag here</div>
<UploadCloud className="w-10 h-10 text-slate-355 mx-auto" />
<div className="text-xs font-bold text-slate-600">{t('select_files_drag', 'Select files or drag here')}</div>
<div className="text-[9px] text-slate-400">PDF, JPG, PNG (Max 5MB)</div>
<input
type="file"
@ -457,7 +459,7 @@ export default function Show({ conversation, initialMessages, conversations = []
onClick={() => setShowAttachmentModal(false)}
className="px-4 py-2 border border-slate-200 hover:bg-slate-50 rounded-xl"
>
Close
{t('close', 'Close')}
</button>
</div>
</div>

View File

@ -1,6 +1,7 @@
import React, { useState } from 'react';
import { Head, useForm } from '@inertiajs/react';
import EmployerLayout from '../../Layouts/EmployerLayout';
import { useTranslation } from '../../lib/LanguageContext';
import {
User,
CheckCircle2,
@ -24,6 +25,7 @@ import {
import { toast } from 'sonner';
export default function Profile({ employerProfile }) {
const { t } = useTranslation();
const { data: profile, setData, post, processing, errors } = useForm({
name: employerProfile?.name || '',
company_name: employerProfile?.company_name || '',
@ -51,34 +53,29 @@ export default function Profile({ employerProfile }) {
preserveScroll: true,
onSuccess: () => {
setSaved(true);
toast.success("🛡️ Profile updated successfully", {
description: "Household sponsor preferences and vetted credentials synchronized successfully."
toast.success(`🛡️ ${t('profile_updated_successfully', 'Profile updated successfully')}`, {
description: t('profile_updated_successfully_desc', 'Household sponsor preferences and vetted credentials synchronized successfully.')
});
setTimeout(() => setSaved(false), 3000);
},
onError: (errs) => {
toast.error("Failed to update profile", {
description: Object.values(errs)[0] || "Please check the form fields."
toast.error(t('profile_update_failed', 'Failed to update profile'), {
description: Object.values(errs)[0] || t('check_form_fields', 'Please check the form fields.')
});
}
});
};
const tabs = [
{ id: 'personal', label: 'Personal', icon: User },
{ id: 'security', label: 'Security & Password', icon: Lock },
{ id: 'billing', label: 'Billing & Receipts', icon: CreditCard },
{ id: 'notifications', label: 'Notifications Hub', icon: Bell },
];
const pastHires = [
{ id: 1, name: 'Rhea Joy', category: 'Childcare / Nanny', nationality: 'Philippines', date: 'Jan 15, 2025', status: 'Active Contract' },
{ id: 2, name: 'Priya Sharma', category: 'Housekeeper', nationality: 'India', date: 'Jul 10, 2024', status: 'Completed / Expiry' }
{ id: 'personal', label: t('tab_personal', 'Personal'), icon: User },
{ id: 'security', label: t('tab_security', 'Security & Password'), icon: Lock },
{ id: 'billing', label: t('tab_billing', 'Billing & Receipts'), icon: CreditCard },
{ id: 'notifications', label: t('tab_notifications', 'Notifications Hub'), icon: Bell },
];
return (
<EmployerLayout title="Account Settings">
<Head title="Profile - Employer Portal" />
<EmployerLayout title={t('account_settings', 'Account Settings')}>
<Head title={`${t('profile', 'Profile')} - ${t('employer_portal', 'Employer Portal')}`} />
<div className="flex flex-col lg:flex-row gap-8 select-none w-full pb-16">
{/* Left Side: Navigation Tabs */}
@ -128,11 +125,11 @@ export default function Profile({ employerProfile }) {
<div className="flex flex-wrap justify-center md:justify-start gap-2.5 mt-4">
<span className="bg-emerald-50 text-emerald-700 px-3 py-1.5 rounded-xl text-[10px] font-black uppercase tracking-widest flex items-center space-x-1.5 border border-emerald-100">
<ShieldCheck className="w-3.5 h-3.5" />
<span>Emirates ID Vetted</span>
<span>{t('emirates_id_vetted', 'Emirates ID Vetted')}</span>
</span>
<span className="bg-blue-50 text-blue-700 px-3 py-1.5 rounded-xl text-[10px] font-black uppercase tracking-widest flex items-center space-x-1.5 border border-blue-100">
<CheckCircle2 className="w-3.5 h-3.5" />
<span>Direct Sponsor Portal</span>
<span>{t('direct_sponsor_portal', 'Direct Sponsor Portal')}</span>
</span>
</div>
</div>
@ -145,13 +142,13 @@ export default function Profile({ employerProfile }) {
{activeTab === 'personal' && (
<div className="space-y-6">
<div className="border-b border-slate-100 pb-4">
<h3 className="text-lg font-black text-slate-900">Personal details</h3>
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mt-1">Manage sponsor bio and credentials</p>
<h3 className="text-lg font-black text-slate-900">{t('personal_details_header', 'Personal details')}</h3>
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mt-1">{t('personal_details_desc', 'Manage sponsor bio and credentials')}</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">Full Sponsor Name</label>
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">{t('full_sponsor_name', 'Full Sponsor Name')}</label>
<div className="relative">
<User className="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-300" />
<input
@ -164,7 +161,7 @@ export default function Profile({ employerProfile }) {
</div>
<div className="space-y-2">
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">Invoicing Email</label>
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">{t('invoicing_email', 'Invoicing Email')}</label>
<div className="relative">
<Mail className="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-300" />
<input
@ -177,7 +174,7 @@ export default function Profile({ employerProfile }) {
</div>
<div className="space-y-2">
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">UAE Mobile Contact</label>
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">{t('uae_mobile_contact', 'UAE Mobile Contact')}</label>
<div className="relative">
<Phone className="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-300" />
<input
@ -190,7 +187,7 @@ export default function Profile({ employerProfile }) {
</div>
<div className="space-y-2">
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">Sponsor Nationality</label>
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">{t('sponsor_nationality', 'Sponsor Nationality')}</label>
<div className="relative">
<Globe className="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-300" />
<select
@ -198,17 +195,17 @@ export default function Profile({ employerProfile }) {
onChange={(e) => setData('nationality', e.target.value)}
className="w-full pl-12 pr-4 py-3 bg-slate-50 border-none rounded-2xl text-xs font-bold focus:ring-2 focus:ring-blue-100 transition-all outline-none cursor-pointer"
>
<option value="">Select Nationality</option>
<option value="UAE National">UAE National</option>
<option value="Expat (UK / Europe)">Expat (UK / Europe)</option>
<option value="Expat (USA / Canada)">Expat (USA / Canada)</option>
<option value="Expat (Asia / GCC)">Expat (Asia / GCC)</option>
<option value="">{t('select_nationality', 'Select Nationality')}</option>
<option value="UAE National">{t('uae_national', 'UAE National')}</option>
<option value="Expat (UK / Europe)">{t('expat_uk_europe', 'Expat (UK / Europe)')}</option>
<option value="Expat (USA / Canada)">{t('expat_usa_canada', 'Expat (USA / Canada)')}</option>
<option value="Expat (Asia / GCC)">{t('expat_asia_gcc', 'Expat (Asia / GCC)')}</option>
</select>
</div>
</div>
<div className="space-y-2">
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">Family Members Size</label>
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">{t('family_members_size', 'Family Members Size')}</label>
<div className="relative">
<Users className="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-300" />
<select
@ -216,16 +213,16 @@ export default function Profile({ employerProfile }) {
onChange={(e) => setData('family_size', e.target.value)}
className="w-full pl-12 pr-4 py-3 bg-slate-50 border-none rounded-2xl text-xs font-bold focus:ring-2 focus:ring-blue-100 transition-all outline-none cursor-pointer"
>
<option value="">Select Family Size</option>
<option value="1-2 Members">1-2 Members</option>
<option value="3-4 Members">3-4 Members</option>
<option value="5+ Members">5+ Members</option>
<option value="">{t('select_family_size', 'Select Family Size')}</option>
<option value="1-2 Members">{t('family_1_2', '1-2 Members')}</option>
<option value="3-4 Members">{t('family_3_4', '3-4 Members')}</option>
<option value="5+ Members">{t('family_5_plus', '5+ Members')}</option>
</select>
</div>
</div>
<div className="space-y-2">
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">Accommodation Residence</label>
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">{t('accommodation_residence', 'Accommodation Residence')}</label>
<div className="relative">
<Home className="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-300" />
<select
@ -233,16 +230,16 @@ export default function Profile({ employerProfile }) {
onChange={(e) => setData('accommodation', e.target.value)}
className="w-full pl-12 pr-4 py-3 bg-slate-50 border-none rounded-2xl text-xs font-bold focus:ring-2 focus:ring-blue-100 transition-all outline-none cursor-pointer"
>
<option value="">Select Accommodation</option>
<option value="Villa">Villa</option>
<option value="Apartment (Penthouse)">Apartment (Penthouse)</option>
<option value="Apartment (1-3 Bed)">Apartment (1-3 Bed)</option>
<option value="">{t('select_accommodation', 'Select Accommodation')}</option>
<option value="Villa">{t('villa', 'Villa')}</option>
<option value="Apartment (Penthouse)">{t('penthouse', 'Apartment (Penthouse)')}</option>
<option value="Apartment (1-3 Bed)">{t('apartment_1_3', 'Apartment (1-3 Bed)')}</option>
</select>
</div>
</div>
<div className="space-y-2 md:col-span-2">
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">City District / Area</label>
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">{t('city_district_area', 'City District / Area')}</label>
<div className="relative">
<MapPin className="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-300" />
<input
@ -258,8 +255,8 @@ export default function Profile({ employerProfile }) {
{/* Emirates ID Verification */}
<div className="space-y-6 pt-6 border-t border-slate-100">
<div className="border-b border-slate-100 pb-4">
<h3 className="text-lg font-black text-slate-900">Emirates ID Verification</h3>
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mt-1">Regulatory compliance credentials</p>
<h3 className="text-lg font-black text-slate-900">{t('emirates_id_verification_header', 'Emirates ID Verification')}</h3>
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mt-1">{t('emirates_id_verification_desc', 'Regulatory compliance credentials')}</p>
</div>
{employerProfile?.verification_status === 'approved' && employerProfile?.emirates_id_front && employerProfile?.emirates_id_back ? (
@ -268,10 +265,10 @@ export default function Profile({ employerProfile }) {
<ShieldCheck className="w-6 h-6" />
</div>
<div>
<h4 className="font-extrabold text-slate-900">Emirates ID Verified</h4>
<p className="text-[9px] font-black text-slate-400 uppercase tracking-widest mt-0.5">Vetted under MOHRE Guidelines</p>
<h4 className="font-extrabold text-slate-900">{t('emirates_id_verified_status', 'Emirates ID Verified')}</h4>
<p className="text-[9px] font-black text-slate-400 uppercase tracking-widest mt-0.5">{t('mohre_guidelines', 'Vetted under MOHRE Guidelines')}</p>
<p className="text-xs text-slate-600 mt-2 font-medium leading-relaxed">
Your Emirates ID has been verified successfully. Your account is active for direct hiring.
{t('emirates_id_verified_desc', 'Your Emirates ID has been verified successfully. Your account is active for direct hiring.')}
</p>
</div>
</div>
@ -281,10 +278,10 @@ export default function Profile({ employerProfile }) {
<ShieldCheck className="w-6 h-6" />
</div>
<div>
<h4 className="font-extrabold text-slate-900">Verification Pending Audit</h4>
<p className="text-[9px] font-black text-slate-400 uppercase tracking-widest mt-0.5">Audit Queue</p>
<h4 className="font-extrabold text-slate-900">{t('verification_pending_status', 'Verification Pending Audit')}</h4>
<p className="text-[9px] font-black text-slate-400 uppercase tracking-widest mt-0.5">{t('audit_queue', 'Audit Queue')}</p>
<p className="text-xs text-slate-600 mt-2 font-medium leading-relaxed">
Your Emirates ID document uploads are currently under review. Audits are typically completed within 24 hours.
{t('verification_pending_desc', 'Your Emirates ID document uploads are currently under review. Audits are typically completed within 24 hours.')}
</p>
</div>
</div>
@ -294,10 +291,10 @@ export default function Profile({ employerProfile }) {
<ShieldCheck className="w-6 h-6" />
</div>
<div>
<h4 className="font-extrabold text-slate-900">Emirates ID Verification Required</h4>
<p className="text-[9px] font-black text-slate-400 uppercase tracking-widest mt-0.5">Action Needed</p>
<h4 className="font-extrabold text-slate-900">{t('verification_required_status', 'Emirates ID Verification Required')}</h4>
<p className="text-[9px] font-black text-slate-400 uppercase tracking-widest mt-0.5">{t('action_needed', 'Action Needed')}</p>
<p className="text-xs text-slate-600 mt-2 font-medium leading-relaxed">
Please upload high-resolution color scans of your Emirates ID to verify your identity and activate full hiring features.
{t('verification_required_desc', 'Please upload high-resolution color scans of your Emirates ID to verify your identity and activate full hiring features.')}
</p>
</div>
</div>
@ -306,7 +303,7 @@ export default function Profile({ employerProfile }) {
{/* File Upload Fields */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 bg-slate-50 p-6 rounded-3xl border border-slate-200">
<div className="space-y-2">
<label className="text-xs font-black text-slate-600 uppercase tracking-tight ml-1">Emirates ID (Front Side)</label>
<label className="text-xs font-black text-slate-600 uppercase tracking-tight ml-1">{t('emirates_id_front_side', 'Emirates ID (Front Side)')}</label>
<input
type="file"
onChange={(e) => setData('emirates_id_front', e.target.files[0])}
@ -316,7 +313,7 @@ export default function Profile({ employerProfile }) {
</div>
<div className="space-y-2">
<label className="text-xs font-black text-slate-600 uppercase tracking-tight ml-1">Emirates ID (Back Side)</label>
<label className="text-xs font-black text-slate-600 uppercase tracking-tight ml-1">{t('emirates_id_back_side', 'Emirates ID (Back Side)')}</label>
<input
type="file"
onChange={(e) => setData('emirates_id_back', e.target.files[0])}
@ -329,7 +326,7 @@ export default function Profile({ employerProfile }) {
{/* Uploaded Documents Details */}
{(employerProfile?.emirates_id_front || employerProfile?.emirates_id_back) && (
<div className="space-y-4 pt-4 border-t border-slate-100">
<h4 className="text-xs font-black text-slate-600 uppercase tracking-wider ml-1">Uploaded Credentials Scans</h4>
<h4 className="text-xs font-black text-slate-600 uppercase tracking-wider ml-1">{t('uploaded_credentials_scans', 'Uploaded Credentials Scans')}</h4>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
{employerProfile?.emirates_id_front && (
<div className="p-4 bg-slate-50 border border-slate-200 rounded-2xl flex items-center justify-between">
@ -338,7 +335,7 @@ export default function Profile({ employerProfile }) {
ID
</div>
<div className="min-w-0">
<div className="text-xs font-black text-slate-800">Emirates ID (Front)</div>
<div className="text-xs font-black text-slate-800">{t('emirates_id_front_side', 'Emirates ID (Front Side)')}</div>
<div className="text-[10px] text-slate-400 font-bold truncate">{employerProfile.emirates_id_front.split('/').pop()}</div>
</div>
</div>
@ -348,7 +345,7 @@ export default function Profile({ employerProfile }) {
rel="noopener noreferrer"
className="px-3 py-1.5 bg-white border border-slate-200 text-xs font-bold text-slate-600 rounded-lg hover:text-[#185FA5] transition-colors shadow-sm flex-shrink-0"
>
View Scan
{t('view_scan', 'View Scan')}
</a>
</div>
)}
@ -359,7 +356,7 @@ export default function Profile({ employerProfile }) {
ID
</div>
<div className="min-w-0">
<div className="text-xs font-black text-slate-800">Emirates ID (Back)</div>
<div className="text-xs font-black text-slate-800">{t('emirates_id_back_side', 'Emirates ID (Back Side)')}</div>
<div className="text-[10px] text-slate-400 font-bold truncate">{employerProfile.emirates_id_back.split('/').pop()}</div>
</div>
</div>
@ -369,7 +366,7 @@ export default function Profile({ employerProfile }) {
rel="noopener noreferrer"
className="px-3 py-1.5 bg-white border border-slate-200 text-xs font-bold text-slate-600 rounded-lg hover:text-[#185FA5] transition-colors shadow-sm flex-shrink-0"
>
View Scan
{t('view_scan', 'View Scan')}
</a>
</div>
)}
@ -383,38 +380,38 @@ export default function Profile({ employerProfile }) {
{activeTab === 'security' && (
<div className="space-y-6">
<div className="border-b border-slate-100 pb-4">
<h3 className="text-lg font-black text-slate-900">Security & Password</h3>
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mt-1">Keep your sponsor account secure</p>
<h3 className="text-lg font-black text-slate-900">{t('security_password_header', 'Security & Password')}</h3>
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mt-1">{t('security_password_desc', 'Keep your sponsor account secure')}</p>
</div>
<div className="space-y-4 max-w-md">
<div className="space-y-2">
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">Current Password</label>
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">{t('current_password', 'Current Password')}</label>
<input
type="password"
placeholder="••••••••"
value={profile.current_password}
onChange={(e) => setProfile({ ...profile, current_password: e.target.value })}
onChange={(e) => setData('current_password', e.target.value)}
className="w-full px-4 py-3 bg-slate-50 border-none rounded-2xl text-xs font-bold focus:ring-2 focus:ring-blue-100 transition-all outline-none"
/>
</div>
<div className="space-y-2">
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">New Password</label>
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">{t('new_password', 'New Password')}</label>
<input
type="password"
placeholder="••••••••"
value={profile.new_password}
onChange={(e) => setProfile({ ...profile, new_password: e.target.value })}
onChange={(e) => setData('new_password', e.target.value)}
className="w-full px-4 py-3 bg-slate-50 border-none rounded-2xl text-xs font-bold focus:ring-2 focus:ring-blue-100 transition-all outline-none"
/>
</div>
<div className="space-y-2">
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">Confirm New Password</label>
<label className="text-xs font-black text-slate-500 uppercase tracking-tighter ml-1">{t('confirm_new_password', 'Confirm New Password')}</label>
<input
type="password"
placeholder="••••••••"
value={profile.new_password_confirmation}
onChange={(e) => setProfile({ ...profile, new_password_confirmation: e.target.value })}
onChange={(e) => setData('new_password_confirmation', e.target.value)}
className="w-full px-4 py-3 bg-slate-50 border-none rounded-2xl text-xs font-bold focus:ring-2 focus:ring-blue-100 transition-all outline-none"
/>
</div>
@ -425,8 +422,8 @@ export default function Profile({ employerProfile }) {
{activeTab === 'billing' && (
<div className="space-y-8">
<div className="border-b border-slate-100 pb-4">
<h3 className="text-lg font-black text-slate-900">Billing & Receipts</h3>
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mt-1">Manage active sponsorship access</p>
<h3 className="text-lg font-black text-slate-900">{t('tab_billing', 'Billing & Receipts')}</h3>
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mt-1">{t('available_subscription_tiers_desc', 'Upgrade or cancel anytime. All contracts compliant with UAE Tadbeer MOHRE guides.')}</p>
</div>
{/* Current Plan Card */}
@ -435,16 +432,16 @@ export default function Profile({ employerProfile }) {
<div className="relative z-10">
<div className="flex items-center justify-between">
<div>
<span className="text-[10px] font-black uppercase tracking-widest text-slate-400">Current Plan</span>
<span className="text-[10px] font-black uppercase tracking-widest text-slate-400">{t('current_plan', 'Current Plan')}</span>
<h4 className="text-2xl font-black mt-1">Premium Employer</h4>
</div>
<div className="bg-white/10 backdrop-blur-md px-4 py-2 rounded-xl border border-white/10">
<span className="text-sm font-black">Active</span>
<span className="text-sm font-black">{t('active_status', 'Active')}</span>
</div>
</div>
<div className="mt-8 flex items-end justify-between">
<div className="space-y-1">
<div className="text-[10px] font-bold text-slate-400 uppercase">Next Payment</div>
<div className="text-[10px] font-bold text-slate-400 uppercase">{t('next_payment', 'Next Payment')}</div>
<div className="text-sm font-bold italic">Jun 15, 2026</div>
</div>
<div className="text-3xl font-black tracking-tighter">
@ -456,26 +453,26 @@ export default function Profile({ employerProfile }) {
{/* Transaction History */}
<div className="space-y-4">
<h4 className="text-xs font-black text-slate-400 uppercase tracking-widest">Recent Transactions</h4>
<h4 className="text-xs font-black text-slate-400 uppercase tracking-widest">{t('recent_transactions', 'Recent Transactions')}</h4>
<div className="bg-slate-50 rounded-2xl border border-slate-100 overflow-hidden">
<table className="w-full text-left">
<thead className="bg-slate-100/50">
<tr>
<th className="px-4 py-3 text-[10px] font-black text-slate-400 uppercase tracking-tighter">Date</th>
<th className="px-4 py-3 text-[10px] font-black text-slate-400 uppercase tracking-tighter">Description</th>
<th className="px-4 py-3 text-[10px] font-black text-slate-400 uppercase tracking-tighter">Amount</th>
<th className="px-4 py-3 text-[10px] font-black text-slate-400 uppercase tracking-tighter text-right">Receipt</th>
<th className="px-4 py-3 text-[10px] font-black text-slate-400 uppercase tracking-tighter">{t('date_header', 'Date')}</th>
<th className="px-4 py-3 text-[10px] font-black text-slate-400 uppercase tracking-tighter">{t('description_header', 'Description')}</th>
<th className="px-4 py-3 text-[10px] font-black text-slate-400 uppercase tracking-tighter">{t('amount_header', 'Amount')}</th>
<th className="px-4 py-3 text-[10px] font-black text-slate-400 uppercase tracking-tighter text-right">{t('receipt_header', 'Receipt')}</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-100">
{[
{ date: 'May 01, 2026', desc: 'Premium Monthly Subscription', amount: '199 AED' },
{ date: 'Apr 01, 2026', desc: 'Premium Monthly Subscription', amount: '199 AED' }
].map((t, i) => (
].map((transaction, i) => (
<tr key={i}>
<td className="px-4 py-4 text-xs font-bold text-slate-600">{t.date}</td>
<td className="px-4 py-4 text-xs font-bold text-slate-900">{t.desc}</td>
<td className="px-4 py-4 text-xs font-black text-slate-900">{t.amount}</td>
<td className="px-4 py-4 text-xs font-bold text-slate-600">{transaction.date}</td>
<td className="px-4 py-4 text-xs font-bold text-slate-900">{transaction.desc}</td>
<td className="px-4 py-4 text-xs font-black text-slate-900">{transaction.amount}</td>
<td className="px-4 py-4 text-right">
<button
type="button"
@ -497,15 +494,15 @@ export default function Profile({ employerProfile }) {
{activeTab === 'notifications' && (
<div className="space-y-6">
<div className="border-b border-slate-100 pb-4">
<h3 className="text-lg font-black text-slate-900">Notification Settings Hub</h3>
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mt-1">Choose how you want to receive alerts</p>
<h3 className="text-lg font-black text-slate-900">{t('notification_settings_hub', 'Notification Settings Hub')}</h3>
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mt-1">{t('notification_settings_desc', 'Choose how you want to receive alerts')}</p>
</div>
<div className="space-y-4">
{[
{ title: 'Email Alerts', desc: 'Receive vetted worker recommendations and visa updates.' },
{ title: 'SMS Instant Receipts', desc: 'Get SMS notifications for interview schedules.' },
{ title: 'Push Notifications', desc: 'Get desktop sound alerts for new direct messages.' }
{ title: t('email_alerts', 'Email Alerts'), desc: t('email_alerts_desc', 'Receive vetted worker recommendations and visa updates.') },
{ title: t('sms_alerts', 'SMS Instant Receipts'), desc: t('sms_alerts_desc', 'Get SMS notifications for interview schedules.') },
{ title: t('push_alerts', 'Push Notifications'), desc: t('push_alerts_desc', 'Get desktop sound alerts for new direct messages.') }
].map((n, i) => (
<div key={i} className="flex items-center justify-between p-4 bg-slate-50 rounded-2xl border border-slate-100">
<div className="space-y-0.5">
@ -514,7 +511,7 @@ export default function Profile({ employerProfile }) {
</div>
<button
type="button"
onClick={() => setProfile({ ...profile, notifications: !profile.notifications })}
onClick={() => setData('notifications', !profile.notifications)}
className={`w-10 h-6 rounded-full p-1 transition-all ${profile.notifications ? 'bg-[#185FA5]' : 'bg-slate-200'}`}
>
<div className={`w-4 h-4 bg-white rounded-full transition-transform ${profile.notifications ? 'translate-x-4' : 'translate-x-0'}`} />
@ -529,20 +526,21 @@ export default function Profile({ employerProfile }) {
{saved ? (
<div className="flex items-center space-x-2 text-emerald-600 animate-in fade-in slide-in-from-left-4">
<CheckCircle2 className="w-5 h-5" />
<span className="text-xs font-black uppercase">Changes saved successfully</span>
<span className="text-xs font-black uppercase">{t('changes_saved', 'Changes saved successfully')}</span>
</div>
) : (
<p className="text-[10px] font-bold text-slate-400 max-w-xs text-center sm:text-left">
Some updates may require Emirates ID re-verification.
{t('emirates_id_reverification_notice', 'Some updates may require Emirates ID re-verification.')}
</p>
)}
<button
type="submit"
disabled={processing}
className="w-full sm:w-auto bg-[#185FA5] hover:bg-[#144f8a] text-white px-8 py-3 rounded-2xl text-xs font-black uppercase tracking-widest flex items-center justify-center space-x-2 transition-all shadow-md shadow-blue-200/50"
>
<Save className="w-4 h-4" />
<span>Update Settings</span>
<span>{t('update_settings', 'Update Settings')}</span>
</button>
</div>
</form>

View File

@ -1,6 +1,7 @@
import React, { useState, useEffect } from 'react';
import { Head, Link, router } from '@inertiajs/react';
import EmployerLayout from '../../Layouts/EmployerLayout';
import { useTranslation } from '../../lib/LanguageContext';
import {
CheckCircle2,
Globe2,
@ -31,6 +32,7 @@ import {
} from '@/components/ui/dropdown-menu';
export default function SelectedCandidates({ selectedWorkers }) {
const { t } = useTranslation();
const [workers, setWorkers] = useState((selectedWorkers || []).filter(w => w.status !== 'Searching'));
const [searchTerm, setSearchTerm] = useState('');
@ -48,72 +50,19 @@ export default function SelectedCandidates({ selectedWorkers }) {
});
};
const stats = [
{
label: 'Total Candidates',
count: workers.length,
icon: Users,
color: 'text-slate-600',
bg: 'bg-slate-50'
},
{
label: 'Reviewing',
count: workers.filter(w => w.status === 'Reviewing' || !w.status).length,
icon: Search,
color: 'text-amber-600',
bg: 'bg-amber-50'
},
{
label: 'Offer Sent',
count: workers.filter(w => w.status === 'Offer Sent').length,
icon: Send,
color: 'text-blue-600',
bg: 'bg-blue-50'
},
{
label: 'Hired',
count: workers.filter(w => w.status === 'Hired').length,
icon: CheckCircle2,
color: 'text-emerald-600',
bg: 'bg-emerald-50'
},
{
label: 'Rejected',
count: workers.filter(w => w.status === 'Rejected').length,
icon: UserCheck,
color: 'text-rose-600',
bg: 'bg-rose-50'
},
];
return (
<EmployerLayout>
<Head title="Candidates - Employer Portal" />
<EmployerLayout title={t('candidates_pipeline', 'Candidates')}>
<Head title={`${t('candidates_pipeline', 'Candidates')} - ${t('employer_portal', 'Employer Portal')}`} />
<div className="space-y-8 select-none">
{/* Header Section */}
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-black text-slate-900 tracking-tight">Candidates</h1>
<p className="text-xs font-medium text-slate-500 mt-1">Manage your workforce recruitment pipeline</p>
<h1 className="text-2xl font-black text-slate-900 tracking-tight">{t('candidates_pipeline', 'Candidates')}</h1>
<p className="text-xs font-medium text-slate-500 mt-1">{t('candidates_pipeline_desc', 'Manage your workforce recruitment pipeline')}</p>
</div>
</div>
{/* Stats Grid */}
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4">
{stats.map((stat) => (
<div key={stat.label} className="bg-white p-5 rounded-2xl border border-slate-100 shadow-sm flex items-center space-x-4">
<div className={`p-3 rounded-xl ${stat.bg}`}>
<stat.icon className={`w-6 h-6 ${stat.color}`} />
</div>
<div>
<div className="text-2xl font-black text-slate-900 leading-none">{stat.count}</div>
<div className="text-[10px] font-black text-slate-400 uppercase tracking-widest mt-1">{stat.label}</div>
</div>
</div>
))}
</div>
{/* Table Section */}
<div className="bg-white rounded-3xl border border-slate-200 shadow-sm overflow-hidden">
<div className="p-6 border-b border-slate-100 bg-slate-50/50 flex items-center justify-between">
@ -121,7 +70,7 @@ export default function SelectedCandidates({ selectedWorkers }) {
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" />
<input
type="text"
placeholder="Search by name..."
placeholder={t('search_by_name', 'Search by name...')}
className="w-full pl-10 pr-4 py-2 bg-white border border-slate-200 rounded-xl text-sm focus:ring-2 focus:ring-blue-100 focus:border-[#185FA5] transition-all outline-none"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
@ -146,12 +95,12 @@ export default function SelectedCandidates({ selectedWorkers }) {
<table className="w-full text-left">
<thead>
<tr className="border-b border-slate-100">
<th className="px-6 py-4 text-[10px] font-black text-slate-400 uppercase tracking-widest">Candidate</th>
<th className="px-6 py-4 text-[10px] font-black text-slate-400 uppercase tracking-widest">Selected</th>
<th className="px-6 py-4 text-[10px] font-black text-slate-400 uppercase tracking-widest">Category</th>
<th className="px-6 py-4 text-[10px] font-black text-slate-400 uppercase tracking-widest">Salary</th>
<th className="px-6 py-4 text-[10px] font-black text-slate-400 uppercase tracking-widest">Status</th>
<th className="px-6 py-4 text-[10px] font-black text-slate-400 uppercase tracking-widest text-right">Actions</th>
<th className="px-6 py-4 text-[10px] font-black text-slate-400 uppercase tracking-widest">{t('candidate_header', 'Candidate')}</th>
<th className="px-6 py-4 text-[10px] font-black text-slate-400 uppercase tracking-widest">{t('selected_header', 'Selected')}</th>
<th className="px-6 py-4 text-[10px] font-black text-slate-400 uppercase tracking-widest">{t('category_header', 'Category')}</th>
<th className="px-6 py-4 text-[10px] font-black text-slate-400 uppercase tracking-widest">{t('salary_header', 'Salary')}</th>
<th className="px-6 py-4 text-[10px] font-black text-slate-400 uppercase tracking-widest">{t('status_header', 'Status')}</th>
<th className="px-6 py-4 text-[10px] font-black text-slate-400 uppercase tracking-widest text-right">{t('actions_header', 'Actions')}</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-50">
@ -177,42 +126,10 @@ export default function SelectedCandidates({ selectedWorkers }) {
<span className="text-sm font-bold text-slate-800">{worker.salary} <span className="text-[10px] text-slate-400">AED</span></span>
</td>
<td className="px-6 py-5">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button className={`inline-flex items-center px-2.5 py-1 rounded-full text-[10px] font-black tracking-tight hover:ring-2 hover:ring-offset-1 transition-all ${
worker.status === 'Hired' ? 'bg-emerald-50 text-emerald-700 hover:ring-emerald-200' :
worker.status === 'Rejected' ? 'bg-rose-50 text-rose-700 hover:ring-rose-200' :
worker.status === 'Offer Sent' ? 'bg-blue-50 text-blue-700 hover:ring-blue-200' :
'bg-amber-50 text-amber-700 hover:ring-amber-200'
}`}>
<span className={`w-1 h-1 rounded-full mr-1.5 ${
worker.status === 'Hired' ? 'bg-emerald-500' :
worker.status === 'Rejected' ? 'bg-rose-500' :
worker.status === 'Offer Sent' ? 'bg-blue-500' :
'bg-amber-500'
}`} />
{(worker.status || 'Reviewing').toUpperCase()}
<ChevronRight className="w-3 h-3 ml-1 rotate-90 opacity-50" />
</button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="w-44 p-2 rounded-xl">
<DropdownMenuLabel className="text-[10px] font-black text-slate-400 uppercase tracking-widest px-2 py-1.5">Change Status</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => changeStatus(worker.id, 'Reviewing')} className="text-xs font-bold text-slate-600 focus:text-amber-700 focus:bg-amber-50 rounded-lg cursor-pointer">
Reviewing
</DropdownMenuItem>
<DropdownMenuItem onClick={() => changeStatus(worker.id, 'Offer Sent')} className="text-xs font-bold text-slate-600 focus:text-blue-700 focus:bg-blue-50 rounded-lg cursor-pointer">
Offer Sent
</DropdownMenuItem>
<DropdownMenuItem onClick={() => changeStatus(worker.id, 'Hired')} className="text-xs font-bold text-slate-600 focus:text-emerald-700 focus:bg-emerald-50 rounded-lg cursor-pointer">
Hired
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => changeStatus(worker.id, 'Rejected')} className="text-xs font-bold text-rose-600 focus:text-rose-700 focus:bg-rose-50 rounded-lg cursor-pointer">
Rejected
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<span className="inline-flex items-center px-2.5 py-1 rounded-full text-[10px] font-black tracking-tight bg-emerald-50 text-emerald-700 border border-emerald-100 shadow-xs">
<span className="w-1 h-1 rounded-full mr-1.5 bg-emerald-500" />
{t('hired', 'Hired').toUpperCase()}
</span>
</td>
<td className="px-6 py-5 text-right">
<div className="flex items-center justify-end space-x-1">
@ -237,7 +154,7 @@ export default function SelectedCandidates({ selectedWorkers }) {
<td colSpan="7" className="p-20 text-center">
<div className="space-y-3">
<UserCheck className="w-12 h-12 text-slate-200 mx-auto" />
<div className="text-base font-bold text-slate-400">No candidates found</div>
<div className="text-base font-bold text-slate-400">{t('no_candidates_found', 'No candidates found')}</div>
</div>
</td>
</tr>
@ -249,7 +166,10 @@ export default function SelectedCandidates({ selectedWorkers }) {
{/* Pagination Footer */}
<div className="px-6 py-4 bg-slate-50/50 border-t border-slate-100 flex items-center justify-between">
<div className="text-[10px] font-bold text-slate-500 uppercase tracking-widest">
Showing 1 to {workers.length} of {workers.length} candidates
{t('showing_candidates', 'Showing {start} to {end} of {total} candidates')
.replace('{start}', 1)
.replace('{end}', workers.length)
.replace('{total}', workers.length)}
</div>
<div className="flex items-center space-x-2">
<button className="px-3 py-1.5 bg-white border border-slate-200 text-slate-400 rounded-lg text-[10px] font-black cursor-not-allowed">PREV</button>

View File

@ -1,6 +1,7 @@
import React, { useState, useMemo } from 'react';
import { Head, Link, router } from '@inertiajs/react';
import EmployerLayout from '../../Layouts/EmployerLayout';
import { useTranslation } from '../../lib/LanguageContext';
import {
CheckCircle2,
Globe2,
@ -34,6 +35,7 @@ const getLanguageFlag = (lang) => {
};
export default function Shortlist({ shortlistedWorkers }) {
const { t } = useTranslation();
const [workers, setWorkers] = useState(shortlistedWorkers || []);
// Comparison & Quick Preview State
@ -56,7 +58,7 @@ export default function Shortlist({ shortlistedWorkers }) {
setComparisonIds(comparisonIds.filter(i => i !== id));
} else {
if (comparisonIds.length >= 3) {
alert('You can compare a maximum of 3 candidates.');
alert(t('max_compare_alert', 'You can compare a maximum of 3 candidates.'));
return;
}
setComparisonIds([...comparisonIds, id]);
@ -68,19 +70,21 @@ export default function Shortlist({ shortlistedWorkers }) {
}, [workers, comparisonIds]);
return (
<EmployerLayout title="My Shortlist">
<Head title="Shortlist - Employer Portal" />
<EmployerLayout title={t('my_shortlist', 'My Shortlist')}>
<Head title={`${t('shortlist', 'Shortlist')} - ${t('employer_portal', 'Employer Portal')}`} />
<div className="space-y-6 select-none pb-16">
<div className="flex items-center justify-between">
<p className="text-xs text-slate-500 font-medium">
You have <span className="text-slate-900 font-bold">{workers.length}</span> candidates saved for review
{t('candidates_saved', 'You have {count} candidates saved for review').split('{count}')[0]}
<span className="text-slate-900 font-bold">{workers.length}</span>
{t('candidates_saved', 'You have {count} candidates saved for review').split('{count}')[1]}
</p>
<Link
href="/employer/workers"
className="text-xs font-bold text-[#185FA5] hover:underline flex items-center space-x-1"
>
<span>Browse more workers</span>
<span>{t('browse_more', 'Browse more workers')}</span>
</Link>
</div>
@ -110,7 +114,7 @@ export default function Shortlist({ shortlistedWorkers }) {
{worker.verified && (
<span className="inline-flex items-center px-1.5 py-0.5 rounded-full text-[8px] font-black uppercase tracking-wider bg-emerald-500 text-white shadow-xs gap-0.5" title="OCR Verified">
<CheckCircle2 className="w-3 h-3" />
<span>Verified</span>
<span>{t('verified', 'Verified')}</span>
</span>
)}
</div>
@ -124,12 +128,12 @@ export default function Shortlist({ shortlistedWorkers }) {
{worker.visa_status && (worker.visa_status.toLowerCase().includes('tourist') || worker.visa_status.toLowerCase().includes('visit')) ? (
<div className="flex items-center space-x-1 text-[9px] font-black uppercase text-amber-700 bg-amber-50 px-1.5 py-0.5 rounded border border-amber-200">
<AlertTriangle className="w-3 h-3 text-amber-600 flex-shrink-0 animate-bounce" />
<span>{worker.visa_status} (Warning)</span>
<span>{worker.visa_status} ({t('warning', 'Warning')})</span>
</div>
) : worker.visa_status && worker.visa_status.toLowerCase().includes('cancelled') ? (
<div className="flex items-center space-x-1 text-[9px] font-black uppercase text-rose-700 bg-rose-50 px-1.5 py-0.5 rounded border border-rose-200 animate-pulse">
<AlertTriangle className="w-3 h-3 text-rose-600 flex-shrink-0" />
<span>{worker.visa_status} (Warning)</span>
<span>{worker.visa_status} ({t('warning', 'Warning')})</span>
</div>
) : (
<div className="flex items-center space-x-1 text-[9px] font-black uppercase text-blue-700 bg-blue-50 px-1.5 py-0.5 rounded border border-blue-100">
@ -161,7 +165,7 @@ export default function Shortlist({ shortlistedWorkers }) {
type="button"
onClick={() => removeWorker(worker.id)}
className="p-2 bg-rose-50 text-rose-600 hover:bg-rose-100 rounded-xl transition-colors border border-rose-100"
title="Remove from shortlist"
title={t('remove_from_shortlist', 'Remove from shortlist')}
>
<Trash2 className="w-3.5 h-3.5" />
</button>
@ -203,7 +207,7 @@ export default function Shortlist({ shortlistedWorkers }) {
{/* Core exact platform Skills List */}
<div className="space-y-1">
<div className="text-[9px] font-black text-slate-400 uppercase tracking-widest">Platform Skills</div>
<div className="text-[9px] font-black text-slate-400 uppercase tracking-widest">{t('platform_skills', 'Platform Skills')}</div>
<div className="flex flex-wrap gap-1">
{worker.skills?.map(skill => (
<span key={skill} className="px-2.5 py-0.5 bg-blue-50 border border-blue-100 text-[#185FA5] text-[9px] font-black rounded-lg uppercase tracking-wider">
@ -215,7 +219,7 @@ export default function Shortlist({ shortlistedWorkers }) {
{/* Languages Badges with Visual Flags */}
<div className="space-y-1">
<div className="text-[9px] font-black text-slate-400 uppercase tracking-widest">Languages Spoken</div>
<div className="text-[9px] font-black text-slate-400 uppercase tracking-widest">{t('languages_spoken', 'Languages Spoken')}</div>
<div className="flex flex-wrap gap-1.5">
{worker.languages?.map(lang => (
<span key={lang} className="text-[9px] bg-slate-100 text-slate-700 px-2 py-0.5 rounded font-bold uppercase flex items-center space-x-1 border border-slate-200">
@ -236,7 +240,7 @@ export default function Shortlist({ shortlistedWorkers }) {
className="w-full bg-slate-50 border border-slate-200 hover:bg-slate-100 text-slate-700 rounded-xl h-10 font-bold text-xs flex items-center justify-center transition-colors space-x-1"
>
<Eye className="w-3.5 h-3.5" />
<span>Quick Preview</span>
<span>{t('quick_preview', 'Quick Preview')}</span>
</button>
<button
@ -248,7 +252,7 @@ export default function Shortlist({ shortlistedWorkers }) {
: 'bg-white border-slate-200 hover:bg-slate-50 text-slate-700'
}`}
>
{isComparing ? 'Comparing ✓' : 'Compare Candidate'}
{isComparing ? t('comparing_active', 'Comparing ✓') : t('compare_candidate', 'Compare Candidate')}
</button>
</div>
@ -257,14 +261,14 @@ export default function Shortlist({ shortlistedWorkers }) {
href={`/employer/workers/${worker.id}`}
className="w-full bg-slate-100 hover:bg-slate-200 text-slate-700 rounded-xl h-10 font-bold text-xs flex items-center justify-center transition-colors"
>
Open Profile
{t('open_profile', 'Open Profile')}
</Link>
<Link
href={`/employer/messages/${worker.id}`}
className="w-full bg-[#185FA5] hover:bg-[#144f8a] text-white rounded-xl h-10 font-bold text-xs flex items-center justify-center space-x-1.5 transition-colors shadow-xs"
>
<MessageSquare className="w-4 h-4" />
<span>Message</span>
<span>{t('message', 'Message')}</span>
</Link>
</div>
</div>
@ -276,15 +280,15 @@ export default function Shortlist({ shortlistedWorkers }) {
) : (
<div className="text-center py-16 bg-white rounded-2xl border border-slate-200 shadow-sm space-y-3">
<SlidersHorizontal className="w-12 h-12 text-slate-300 mx-auto" />
<div className="text-base font-bold text-slate-800">Your shortlist is empty</div>
<div className="text-base font-bold text-slate-800">{t('shortlist_empty', 'Your shortlist is empty')}</div>
<p className="text-xs text-slate-500 max-w-sm mx-auto">
Explore candidate profiles and add them to your saved shortlist.
{t('shortlist_empty_desc', 'Explore candidate profiles and add them to your saved shortlist.')}
</p>
<Link
href="/employer/workers"
className="inline-block mt-2 bg-[#185FA5] text-white px-6 py-2.5 rounded-xl text-xs font-bold shadow-sm hover:bg-[#144f8a] transition-colors"
>
Find Workers Now
{t('find_workers_now', 'Find Workers Now')}
</Link>
</div>
)}
@ -295,14 +299,14 @@ export default function Shortlist({ shortlistedWorkers }) {
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<span className="w-2.5 h-2.5 rounded-full bg-[#185FA5] animate-ping" />
<h4 className="font-extrabold text-sm text-slate-900">Comparing Workers ({comparedWorkers.length} of 3)</h4>
<h4 className="font-extrabold text-sm text-slate-900">{t('comparing_workers', 'Comparing Workers')} ({comparedWorkers.length} of 3)</h4>
</div>
<button
onClick={() => setComparisonIds([])}
className="text-xs font-bold text-rose-600 hover:underline flex items-center space-x-1"
>
<X className="w-4 h-4" />
<span>Clear all</span>
<span>{t('clear_all', 'Clear all')}</span>
</button>
</div>
@ -393,17 +397,17 @@ export default function Shortlist({ shortlistedWorkers }) {
</p>
) : (
<p className="text-xs text-slate-400 italic bg-slate-50 p-4 rounded-xl leading-relaxed">
No bio details provided.
{t('no_bio_provided', 'No bio details provided.')}
</p>
)}
<div className="grid grid-cols-2 gap-4 text-xs font-bold text-slate-600">
<div className="p-3 bg-slate-50/50 rounded-xl">
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">Expectations</div>
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">{t('expectations', 'Expectations')}</div>
<div className="text-slate-800">{previewWorker.salary} AED / mo</div>
</div>
<div className="p-3 bg-slate-50/50 rounded-xl">
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">Languages</div>
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">{t('languages', 'Languages')}</div>
<div className="flex flex-wrap gap-1.5 mt-1">
{previewWorker.languages?.map(lang => (
<span key={lang} className="text-[9px] bg-white border border-slate-200 text-slate-700 px-2 py-0.5 rounded font-bold flex items-center space-x-1">
@ -414,7 +418,7 @@ export default function Shortlist({ shortlistedWorkers }) {
</div>
</div>
<div className="p-3 bg-slate-50/50 rounded-xl">
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">Availability Status</div>
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">{t('availability_status_label', 'Availability Status')}</div>
<span className={`inline-block px-2 py-0.5 text-[8px] font-black rounded-lg uppercase tracking-wider mt-1 border ${
previewWorker.availability_status === 'Active' ? 'bg-emerald-50 text-emerald-700 border-emerald-200' :
previewWorker.availability_status === 'Hired' ? 'bg-blue-50 text-blue-700 border-blue-200' :
@ -424,14 +428,14 @@ export default function Shortlist({ shortlistedWorkers }) {
</span>
</div>
<div className="p-3 bg-slate-50/50 rounded-xl">
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">Job Preference</div>
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">{t('job_preference', 'Job Preference')}</div>
<div className="text-slate-800 uppercase text-[10px] mt-1">{previewWorker.preferred_job_type}</div>
</div>
</div>
{/* Core Platform Skills inside Quick Preview */}
<div className="space-y-1 pt-1">
<div className="text-[9px] font-black text-slate-400 uppercase tracking-widest">Platform Skills</div>
<div className="text-[9px] font-black text-slate-400 uppercase tracking-widest">{t('platform_skills', 'Platform Skills')}</div>
<div className="flex flex-wrap gap-1">
{previewWorker.skills?.map(skill => (
<span key={skill} className="px-2.5 py-0.5 bg-blue-50 border border-blue-100 text-[#185FA5] text-[9px] font-black rounded-lg uppercase tracking-wider">
@ -447,13 +451,13 @@ export default function Shortlist({ shortlistedWorkers }) {
className="flex-1 border border-rose-200 hover:bg-rose-50 text-rose-600 rounded-xl h-11 text-xs font-bold flex items-center justify-center space-x-2"
>
<Trash2 className="w-4 h-4" />
<span>Remove Shortlist</span>
<span>{t('remove_shortlist', 'Remove Shortlist')}</span>
</button>
<Link
href={`/employer/workers/${previewWorker.id}`}
className="flex-1 bg-[#185FA5] hover:bg-[#144f8a] text-white rounded-xl h-11 text-xs font-black flex items-center justify-center shadow-xs"
>
View Full Details
{t('view_full_details', 'View Full Details')}
</Link>
</div>
</div>

View File

@ -1,6 +1,7 @@
import React, { useState } from 'react';
import { Head } from '@inertiajs/react';
import EmployerLayout from '../../Layouts/EmployerLayout';
import { useTranslation } from '../../lib/LanguageContext';
import {
CreditCard,
CheckCircle2,
@ -22,6 +23,7 @@ import {
import { toast } from 'sonner';
export default function Subscription({ currentPlan, expiresAt, plans }) {
const { t } = useTranslation();
const [selectedPlan, setSelectedPlan] = useState(null);
const [showPayTabsModal, setShowPayTabsModal] = useState(false);
const [showSuccess, setShowSuccess] = useState(false);
@ -53,7 +55,7 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
e.preventDefault();
if (cardNumber.length < 16) {
toast.error("💳 Invalid card number format");
toast.error(`💳 ${t('invalid_card_format', 'Invalid card number format')}`);
return;
}
@ -71,8 +73,8 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
};
setInvoices([newInvoice, ...invoices]);
toast.success(`🎉 Payment Approved by PayTabs!`, {
description: `Successfully subscribed to ${selectedPlan.name}. Premium access limits updated instantly.`,
toast.success(`🎉 ${t('payment_approved', 'Payment Approved by PayTabs!')}`, {
description: t('successfully_subscribed_desc', 'Successfully subscribed to {plan}. Premium access limits updated instantly.').replace('{plan}', selectedPlan.name),
duration: 5000,
});
@ -87,8 +89,8 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
const triggerFailedPaymentSimulation = () => {
setSimulatedFailedState(true);
toast.warning("Simulated billing failure triggered!", {
description: "An automatic system warning will now request payment retry options."
toast.warning(t('simulated_billing_failure_triggered', 'Simulated billing failure triggered!'), {
description: t('simulated_billing_failure_desc', 'An automatic system warning will now request payment retry options.')
});
};
@ -100,14 +102,14 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
};
const downloadReceipt = (invoiceId) => {
toast.success(`📄 Invoice ${invoiceId} generated`, {
description: "Direct MOHRE Sponsor receipt downloaded in PDF format successfully."
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.')
});
};
return (
<EmployerLayout title="Sponsor Pass & Billing">
<Head title="Subscription Billing & Invoices - Employer Portal" />
<EmployerLayout title={t('sponsor_pass_billing', 'Sponsor Pass & Billing')}>
<Head title={t('subscription_billing_title', 'Subscription Billing & Invoices - Employer Portal')} />
<div className="space-y-8 select-none w-full pb-16">
@ -119,8 +121,8 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
<AlertCircle className="w-5 h-5" />
</div>
<div>
<h4 className="font-extrabold text-sm text-slate-800">Your recurrent subscription billing has FAILED!</h4>
<p className="text-xs text-slate-500 font-medium">Card renewal on May 22 failed due to insufficient funds. Retry using PayTabs to avoid profile lockout.</p>
<h4 className="font-extrabold text-sm text-slate-800">{t('recurrent_billing_failed', 'Your recurrent subscription billing has FAILED!')}</h4>
<p className="text-xs text-slate-500 font-medium">{t('recurrent_billing_failed_desc', 'Card renewal failed due to insufficient funds. Retry using PayTabs to avoid profile lockout.')}</p>
</div>
</div>
<button
@ -128,7 +130,7 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
className="bg-rose-600 hover:bg-rose-700 text-white px-5 py-2.5 rounded-xl text-xs font-black shadow-sm transition-all flex items-center space-x-1.5 shrink-0"
>
<RefreshCw className="w-3.5 h-3.5 animate-spin" />
<span>Retry Payment Now</span>
<span>{t('retry_payment_now', 'Retry Payment Now')}</span>
</button>
</div>
)}
@ -140,10 +142,10 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
<CreditCard className="w-6 h-6" />
</div>
<div>
<div className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Active Plan Pass</div>
<div className="text-[10px] font-black text-slate-400 uppercase tracking-widest">{t('active_plan_pass', 'Active Plan Pass')}</div>
<h3 className="text-lg font-black text-slate-900 tracking-tight mt-0.5">{activePlan}</h3>
<p className="text-xs text-slate-500 font-semibold mt-0.5">
Renewing via auto-payment on <span className="font-bold text-[#185FA5]">{expiresAt}</span>
{t('renewing_auto_payment_on', 'Renewing via auto-payment on')} <span className="font-bold text-[#185FA5]">{expiresAt}</span>
</p>
</div>
</div>
@ -154,11 +156,11 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
className="text-[10px] font-black text-slate-400 hover:text-slate-600 underline"
title="Simulate card failure to test retry mechanism"
>
Simulate Billing Failure
{t('simulate_billing_failure', 'Simulate Billing Failure')}
</button>
<div className="flex items-center space-x-1.5 bg-emerald-50 border border-emerald-200 text-emerald-800 px-4 py-2 rounded-xl text-xs font-black">
<CheckCircle2 className="w-4 h-4 text-emerald-600" />
<span>Verified Sponsor Status</span>
<span>{t('verified_sponsor_status', 'Verified Sponsor Status')}</span>
</div>
</div>
</div>
@ -166,15 +168,15 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
{showSuccess && (
<div className="p-4 bg-gradient-to-r from-emerald-500 to-emerald-600 text-white rounded-2xl text-xs font-bold flex items-center space-x-2.5 shadow-md animate-fade-in border border-emerald-600">
<Sparkles className="w-4 h-4 text-amber-300" />
<span>Sponsor Pass updated successfully! PayTabs transaction logged.</span>
<span>{t('sponsor_pass_updated', 'Sponsor Pass updated successfully! PayTabs transaction logged.')}</span>
</div>
)}
{/* Available Plan Tiers Pricing Grid */}
<div className="space-y-4">
<div>
<h2 className="text-lg font-black text-slate-900 tracking-tight">Available Subscription Tiers</h2>
<p className="text-xs text-slate-500 mt-0.5 font-medium">Upgrade or cancel anytime. All contracts compliant with UAE Tadbeer MOHRE guides.</p>
<h2 className="text-lg font-black text-slate-900 tracking-tight">{t('available_subscription_tiers', 'Available Subscription Tiers')}</h2>
<p className="text-xs text-slate-500 mt-0.5 font-medium">{t('available_subscription_tiers_desc', 'Upgrade or cancel anytime. All contracts compliant with UAE Tadbeer MOHRE guides.')}</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 pt-2">
@ -192,7 +194,7 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
>
{plan.popular && (
<div className="bg-[#185FA5] text-white text-[9px] font-black uppercase tracking-wider text-center py-1.5 shadow-xs">
Most Popular Tier
{t('most_popular_tier', 'Most Popular Tier')}
</div>
)}
@ -225,7 +227,7 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
: 'bg-[#185FA5] hover:bg-[#144f8a] text-white'
}`}
>
{isCurrent ? 'Current Active Tier ✓' : 'Select Plan Tier'}
{isCurrent ? t('current_active_tier', 'Current Active Tier ✓') : t('select_plan_tier', 'Select Plan Tier')}
</button>
</div>
</div>
@ -241,9 +243,9 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
<div className="flex items-center justify-between border-b border-slate-100 pb-3">
<div className="flex items-center space-x-2">
<FileText className="w-5 h-5 text-[#185FA5]" />
<h3 className="font-extrabold text-base text-slate-900">Billing Payment Receipts</h3>
<h3 className="font-extrabold text-base text-slate-900">{t('billing_payment_receipts', 'Billing Payment Receipts')}</h3>
</div>
<span className="text-[10px] text-slate-400 font-bold uppercase">Tax Compliant invoices</span>
<span className="text-[10px] text-slate-400 font-bold uppercase">{t('tax_compliant_invoices', 'Tax Compliant invoices')}</span>
</div>
<div className="divide-y divide-slate-100">
@ -283,13 +285,13 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
{/* Sponsor Billing Details Form */}
<div className="lg:col-span-4 bg-white p-6 rounded-3xl border border-slate-200 shadow-sm space-y-6">
<div className="space-y-1">
<h3 className="font-extrabold text-base text-slate-900">Corporate Details</h3>
<p className="text-xs text-slate-500 font-medium">Update tax invoicing options.</p>
<h3 className="font-extrabold text-base text-slate-900">{t('corporate_details', 'Corporate Details')}</h3>
<p className="text-xs text-slate-500 font-medium">{t('update_tax_invoicing', 'Update tax invoicing options.')}</p>
</div>
<div className="space-y-4 text-xs font-bold text-slate-700">
<div>
<label className="block text-slate-400 uppercase tracking-widest text-[9px] mb-1.5">Sponsor Email Address</label>
<label className="block text-slate-400 uppercase tracking-widest text-[9px] mb-1.5">{t('sponsor_email_address', 'Sponsor Email Address')}</label>
<input
type="email"
value={billingEmail}
@ -299,7 +301,7 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
</div>
<div>
<label className="block text-slate-400 uppercase tracking-widest text-[9px] mb-1.5">Billing VAT Registry ID (Optional)</label>
<label className="block text-slate-400 uppercase tracking-widest text-[9px] mb-1.5">{t('billing_vat_id', 'Billing VAT Registry ID (Optional)')}</label>
<input
type="text"
placeholder="e.g. TRN 100293810200003"
@ -308,10 +310,10 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
</div>
<button
onClick={() => toast.success("Corporate billing details updated.")}
onClick={() => toast.success(t('corporate_billing_updated', 'Corporate billing details updated.'))}
className="w-full bg-[#185FA5] hover:bg-[#144f8a] text-white rounded-xl py-2.5 font-bold text-xs"
>
Save Billing Profile
{t('save_billing_profile', 'Save Billing Profile')}
</button>
</div>
</div>
@ -334,21 +336,21 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
<div className="flex items-center justify-between border-b border-slate-100 pb-3">
<div className="flex items-center space-x-2">
<CreditCard className="w-6 h-6 text-red-600" />
<span className="font-extrabold text-sm text-slate-900 tracking-tight uppercase">PayTabs Secured Checkout</span>
<span className="font-extrabold text-sm text-slate-900 tracking-tight uppercase">{t('paytabs_secured_checkout', 'PayTabs Secured Checkout')}</span>
</div>
<span className="text-[8px] bg-red-50 text-red-700 px-2 py-0.5 rounded font-black tracking-widest uppercase">
Gateway v4.0
{t('gateway_version', 'Gateway v4.0')}
</span>
</div>
{/* Order Summary */}
<div className="bg-slate-50 p-4 rounded-2xl border border-slate-200/60 flex justify-between items-center text-xs font-bold text-slate-700">
<div>
<span className="text-[10px] text-slate-400 uppercase tracking-widest">Order description</span>
<span className="text-[10px] text-slate-400 uppercase tracking-widest">{t('order_description', 'Order description')}</span>
<div className="text-slate-900">{selectedPlan.name} Subscription</div>
</div>
<div className="text-right">
<span className="text-[10px] text-slate-400 uppercase tracking-widest">Total amount</span>
<span className="text-[10px] text-slate-400 uppercase tracking-widest">{t('total_amount', 'Total amount')}</span>
<div className="text-emerald-700 text-sm font-black">{selectedPlan.price}</div>
</div>
</div>
@ -357,7 +359,7 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
<form onSubmit={handlePayTabsSubmit} className="space-y-4">
<div className="space-y-3.5 text-xs">
<div>
<label className="block font-bold text-slate-700 mb-1">Cardholder Name</label>
<label className="block font-bold text-slate-700 mb-1">{t('cardholder_name', 'Cardholder Name')}</label>
<input
type="text"
placeholder="e.g. Fatima Al Mansoori"
@ -369,7 +371,7 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
</div>
<div>
<label className="block font-bold text-slate-700 mb-1">Card Number</label>
<label className="block font-bold text-slate-700 mb-1">{t('card_number', 'Card Number')}</label>
<input
type="text"
maxLength="16"
@ -383,7 +385,7 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block font-bold text-slate-700 mb-1">Expiry Date (MM/YY)</label>
<label className="block font-bold text-slate-700 mb-1">{t('expiry_date', 'Expiry Date (MM/YY)')}</label>
<input
type="text"
placeholder="12/28"
@ -394,7 +396,7 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
/>
</div>
<div>
<label className="block font-bold text-slate-700 mb-1">Security Code (CVV)</label>
<label className="block font-bold text-slate-700 mb-1">{t('security_code', 'Security Code (CVV)')}</label>
<input
type="password"
maxLength="3"
@ -411,7 +413,7 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
<div className="pt-4 border-t border-slate-100 flex items-center justify-between text-[10px] text-slate-500">
<span className="flex items-center space-x-1 font-bold">
<Lock className="w-3.5 h-3.5 text-emerald-600" />
<span>256-bit PCI DSS Cryptography Protected</span>
<span>{t('pci_dss_cryptography', '256-bit PCI DSS Cryptography Protected')}</span>
</span>
</div>
@ -419,7 +421,7 @@ export default function Subscription({ currentPlan, expiresAt, plans }) {
type="submit"
className="w-full bg-red-600 hover:bg-red-700 text-white py-3.5 rounded-2xl font-black text-xs uppercase tracking-widest shadow-lg shadow-red-500/10 flex items-center justify-center space-x-2"
>
<span>Authorize Payment</span>
<span>{t('authorize_payment', 'Authorize Payment')}</span>
<ArrowRight className="w-4 h-4" />
</button>
</form>

View File

@ -1,6 +1,7 @@
import React, { useState, useMemo, useEffect } from 'react';
import { Head, Link, router } from '@inertiajs/react';
import EmployerLayout from '../../../Layouts/EmployerLayout';
import { useTranslation } from '../../../lib/LanguageContext';
import {
Search,
SlidersHorizontal,
@ -42,6 +43,7 @@ const getLanguageFlag = (lang) => {
};
export default function Index({ initialWorkers = [], initialShortlistedIds = [], filtersMetadata = {} }) {
const { t } = useTranslation();
// Basic Filters
const [searchQuery, setSearchQuery] = useState('');
const [selectedCategory, setSelectedCategory] = useState('All Categories');
@ -247,8 +249,8 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
}, [initialWorkers, comparisonIds]);
return (
<EmployerLayout title="Find Vetted Domestic Workers">
<Head title="Find Workers - Domestic Worker Platform" />
<EmployerLayout title={t('find_vetted_workers')}>
<Head title={t('find_workers_platform')} />
<div className="space-y-8 select-none pb-16">
@ -260,11 +262,11 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
<div className="flex items-center space-x-2">
<span className="bg-blue-50 text-[#185FA5] px-3 py-1 rounded-xl text-[10px] font-black uppercase tracking-wider border border-blue-100 flex items-center space-x-1">
<HeartHandshake className="w-3.5 h-3.5" />
<span>No Middlemen Platform</span>
<span>{t('no_middlemen_platform')}</span>
</span>
</div>
<h2 className="text-2xl font-black text-slate-900 tracking-tight leading-none">Find Verified Candidates</h2>
<p className="text-slate-500 font-bold text-xs">Instantly connect with UAE vetted, background-checked domestic workers.</p>
<h2 className="text-2xl font-black text-slate-900 tracking-tight leading-none">{t('find_verified_candidates')}</h2>
<p className="text-slate-500 font-bold text-xs">{t('connect_vetted_workers_desc')}</p>
</div>
</div>
@ -279,7 +281,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
type="text"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
placeholder="Search by name, skills, bio (e.g. Cooking, Childcare, Gardening, Driving)..."
placeholder={t('search_by_name_skills_bio')}
className="w-full pl-11 pr-4 py-3 rounded-xl border border-slate-300 text-sm focus:outline-none focus:ring-2 focus:ring-[#185FA5]/20 focus:border-[#185FA5]"
/>
</div>
@ -294,11 +296,11 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
onChange={(e) => setSortBy(e.target.value)}
className="bg-transparent focus:outline-none cursor-pointer"
>
<option value="default">Default Match</option>
<option value="salary_asc">Salary: Low to High</option>
<option value="salary_desc">Salary: High to Low</option>
<option value="rating">Rating: High to Low</option>
<option value="experience">Experience Level</option>
<option value="default">{t('default_match')}</option>
<option value="salary_asc">{t('salary_low_to_high')}</option>
<option value="salary_desc">{t('salary_high_to_low')}</option>
<option value="rating">{t('rating_high_to_low')}</option>
<option value="experience">{t('experience_level')}</option>
</select>
</div>
@ -308,7 +310,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
className="flex items-center justify-center space-x-1.5 px-4 py-2.5 rounded-xl border border-slate-200 hover:bg-slate-50 text-xs font-semibold text-slate-600 transition-colors"
>
<RotateCcw className="w-4 h-4 text-slate-400" />
<span>Reset</span>
<span>{t('reset')}</span>
</button>
</div>
</div>
@ -317,7 +319,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-3 pt-4 border-t border-slate-100">
{/* Nationality */}
<div>
<label className="block text-[10px] font-black text-slate-400 uppercase tracking-widest mb-1.5">Nationality</label>
<label className="block text-[10px] font-black text-slate-400 uppercase tracking-widest mb-1.5">{t('nationality')}</label>
<select
value={selectedNationality}
onChange={(e) => setSelectedNationality(e.target.value)}
@ -331,7 +333,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
{/* Skills */}
<div className="relative">
<label className="block text-[10px] font-black text-slate-400 uppercase tracking-widest mb-1.5">Skills</label>
<label className="block text-[10px] font-black text-slate-400 uppercase tracking-widest mb-1.5">{t('skills')}</label>
<button
type="button"
onClick={() => {
@ -343,8 +345,8 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
>
<span className="truncate">
{selectedSkills.length === 0
? 'Select Skills'
: `${selectedSkills.length} Selected`}
? t('select_skills')
: `${selectedSkills.length} ${t('selected')}`}
</span>
<ChevronDown className="w-4 h-4 ml-1 flex-shrink-0" />
</button>
@ -367,7 +369,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
{/* Language */}
<div className="relative">
<label className="block text-[10px] font-black text-slate-400 uppercase tracking-widest mb-1.5">Language</label>
<label className="block text-[10px] font-black text-slate-400 uppercase tracking-widest mb-1.5">{t('languages_spoken', 'Language')}</label>
<button
type="button"
onClick={() => {
@ -379,8 +381,8 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
>
<span className="truncate">
{selectedLanguages.length === 0
? 'Select Languages'
: `${selectedLanguages.length} Selected`}
? t('select_languages')
: `${selectedLanguages.length} ${t('selected')}`}
</span>
<ChevronDown className="w-4 h-4 ml-1 flex-shrink-0" />
</button>
@ -403,7 +405,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
{/* Availability */}
<div>
<label className="block text-[10px] font-black text-slate-400 uppercase tracking-widest mb-1.5">Availability</label>
<label className="block text-[10px] font-black text-slate-400 uppercase tracking-widest mb-1.5">{t('availability_status', 'Availability')}</label>
<select
value={selectedAvailability}
onChange={(e) => setSelectedAvailability(e.target.value)}
@ -417,7 +419,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
{/* Visa Status */}
<div className="relative">
<label className="block text-[10px] font-black text-slate-400 uppercase tracking-widest mb-1.5">Visa Status</label>
<label className="block text-[10px] font-black text-slate-400 uppercase tracking-widest mb-1.5">{t('visa_status', 'Visa Status')}</label>
<button
type="button"
onClick={() => {
@ -429,8 +431,8 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
>
<span className="truncate">
{selectedVisaStatuses.length === 0
? 'Select Visa Status'
: `${selectedVisaStatuses.length} Selected`}
? t('select_visa_status')
: `${selectedVisaStatuses.length} ${t('selected')}`}
</span>
<ChevronDown className="w-4 h-4 ml-1 flex-shrink-0" />
</button>
@ -456,11 +458,13 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
{/* Listing metadata bar */}
<div className="flex items-center justify-between px-1">
<div className="text-xs font-semibold text-slate-500">
Found <span className="text-slate-900 font-bold">{filteredWorkers.length}</span> domestic workers matching search
{t('found_workers_matching').split('{count}')[0]}
<span className="text-slate-900 font-bold">{filteredWorkers.length}</span>
{t('found_workers_matching').split('{count}')[1]}
</div>
<div className="flex items-center space-x-2 text-xs font-medium text-slate-600">
<CheckCircle className="w-3.5 h-3.5 text-emerald-600" />
<span>MOHRE UAE Direct Sponsoring Active</span>
<span>{t('direct_sponsoring_active')}</span>
</div>
</div>
@ -492,7 +496,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
{worker.verified && (
<span className="inline-flex items-center px-1.5 py-0.5 rounded-full text-[8px] font-black uppercase tracking-wider bg-emerald-500 text-white shadow-xs gap-0.5 animate-pulse" title="OCR Verified">
<CheckCircle2 className="w-3 h-3" />
<span>Verified</span>
<span>{t('verified')}</span>
</span>
)}
</div>
@ -506,12 +510,12 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
{worker.visa_status && (worker.visa_status.toLowerCase().includes('tourist') || worker.visa_status.toLowerCase().includes('visit')) ? (
<div className="flex items-center space-x-1 text-[9px] font-black uppercase text-amber-700 bg-amber-50 px-1.5 py-0.5 rounded border border-amber-200">
<AlertTriangle className="w-3 h-3 text-amber-600 flex-shrink-0 animate-bounce" />
<span>{worker.visa_status} (Warning)</span>
<span>{worker.visa_status} ({t('warning', 'Warning')})</span>
</div>
) : worker.visa_status && worker.visa_status.toLowerCase().includes('cancelled') ? (
<div className="flex items-center space-x-1 text-[9px] font-black uppercase text-rose-700 bg-rose-50 px-1.5 py-0.5 rounded border border-rose-200 animate-pulse">
<AlertTriangle className="w-3 h-3 text-rose-600 flex-shrink-0" />
<span>{worker.visa_status} (Warning)</span>
<span>{worker.visa_status} ({t('warning', 'Warning')})</span>
</div>
) : (
<div className="flex items-center space-x-1 text-[9px] font-black uppercase text-blue-700 bg-blue-50 px-1.5 py-0.5 rounded border border-blue-100">
@ -524,7 +528,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
<Globe2 className="w-3.5 h-3.5 text-slate-400" />
<span className="font-bold">{worker.nationality}</span>
<span></span>
<span>{worker.age} yrs</span>
<span>{worker.age} {t('yrs', 'yrs')}</span>
</div>
</div>
</div>
@ -564,8 +568,8 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
</span>
<div className="flex items-center space-x-1 font-bold text-slate-800">
<DollarSign className="w-3.5 h-3.5 text-emerald-600" />
<span className="text-sm font-black">{worker.salary} AED</span>
<span className="text-[10px] text-slate-400 font-medium">/mo</span>
<span className="text-sm font-black">{worker.salary} {t('aed', 'AED')}</span>
<span className="text-[10px] text-slate-400 font-medium">/{t('mo', 'mo')}</span>
</div>
</div>
@ -574,7 +578,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
<div className="grid grid-cols-2 gap-2.5 p-3.5 bg-slate-50 rounded-xl text-[11px] text-slate-600 font-bold">
<div className="flex items-center space-x-1.5 truncate">
<Briefcase className="w-3.5 h-3.5 text-slate-400 flex-shrink-0" />
<span className="truncate">Exp: {worker.experience}</span>
<span className="truncate">{t('experience', 'Exp')}: {worker.experience}</span>
</div>
<div className="flex items-center space-x-1.5 truncate">
<Sparkles className="w-3.5 h-3.5 text-slate-400 flex-shrink-0" />
@ -582,13 +586,13 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
</div>
<div className="flex items-center space-x-1.5 truncate col-span-2">
<Star className="w-3.5 h-3.5 text-amber-500 flex-shrink-0 fill-amber-500" />
<span className="truncate">{worker.rating} ({worker.reviews_count} reviews)</span>
<span className="truncate">{worker.rating} ({worker.reviews_count} {t('reviews', 'reviews')})</span>
</div>
</div>
{/* Core exact platform Skills List */}
<div className="space-y-1">
<div className="text-[9px] font-black text-slate-400 uppercase tracking-widest">Platform Skills</div>
<div className="text-[9px] font-black text-slate-400 uppercase tracking-widest">{t('platform_skills', 'Platform Skills')}</div>
<div className="flex flex-wrap gap-1">
{worker.skills?.map(skill => (
<span key={skill} className="px-2.5 py-0.5 bg-blue-50 border border-blue-100 text-[#185FA5] text-[9px] font-black rounded-lg uppercase tracking-wider">
@ -600,7 +604,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
{/* Languages Badges with Visual Flags */}
<div className="space-y-1">
<div className="text-[9px] font-black text-slate-400 uppercase tracking-widest">Languages Spoken</div>
<div className="text-[9px] font-black text-slate-400 uppercase tracking-widest">{t('languages_spoken', 'Languages Spoken')}</div>
<div className="flex flex-wrap gap-1.5">
{worker.languages?.map(lang => (
<span key={lang} className="text-[9px] bg-slate-100 text-slate-700 px-2 py-0.5 rounded font-bold uppercase flex items-center space-x-1 border border-slate-200">
@ -621,7 +625,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
className="w-full bg-slate-50 border border-slate-200 hover:bg-slate-100 text-slate-700 rounded-xl h-10 font-bold text-xs flex items-center justify-center transition-colors space-x-1"
>
<Eye className="w-3.5 h-3.5" />
<span>Quick Preview</span>
<span>{t('quick_preview')}</span>
</button>
<button
@ -633,7 +637,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
: 'bg-white border-slate-200 hover:bg-slate-50 text-slate-700'
}`}
>
{isComparing ? 'Comparing ✓' : 'Compare Candidate'}
{isComparing ? t('comparing', 'Comparing ✓') : t('compare_candidate', 'Compare Candidate')}
</button>
</div>
@ -641,7 +645,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
href={`/employer/workers/${worker.id}`}
className="w-full bg-[#185FA5] hover:bg-[#144f8a] text-white rounded-xl h-10 font-bold text-xs flex items-center justify-center transition-colors shadow-xs"
>
Open Full Profile
{t('open_full_profile')}
</Link>
</div>
</div>
@ -652,16 +656,16 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
) : (
<div className="text-center py-20 bg-white rounded-2xl border border-slate-200 shadow-sm space-y-4">
<SlidersHorizontal className="w-14 h-14 text-slate-300 mx-auto" />
<h4 className="text-base font-bold text-slate-800">No candidates match your filters</h4>
<h4 className="text-base font-bold text-slate-800">{t('no_candidates_matching')}</h4>
<p className="text-xs text-slate-500 max-w-sm mx-auto leading-relaxed">
Try adjusting your salary limit, adding additional languages, or broadening nationality preferences.
{t('adjust_filters_desc')}
</p>
<button
type="button"
onClick={resetFilters}
className="bg-[#185FA5] text-white px-5 py-2.5 rounded-xl text-xs font-bold hover:bg-[#144f8a] transition-all shadow-sm"
>
Reset Filters
{t('reset_filters')}
</button>
</div>
)}
@ -673,7 +677,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
onClick={() => setVisibleCount(visibleCount + 6)}
className="bg-white border border-slate-200 hover:bg-slate-50 text-[#185FA5] px-8 py-3 rounded-xl text-xs font-bold transition-all shadow-xs"
>
Load More Workers
{t('load_more_workers')}
</button>
</div>
)}
@ -684,14 +688,16 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<span className="w-2.5 h-2.5 rounded-full bg-[#185FA5] animate-ping" />
<h4 className="font-extrabold text-sm text-slate-900">Comparing Workers ({comparedWorkers.length} of 3)</h4>
<h4 className="font-extrabold text-sm text-slate-900">
{t('comparing_workers_count').replace('{count}', comparedWorkers.length)}
</h4>
</div>
<button
onClick={() => setComparisonIds([])}
className="text-xs font-bold text-rose-600 hover:underline flex items-center space-x-1"
>
<X className="w-4 h-4" />
<span>Clear all</span>
<span>{t('clear_all', 'Clear all')}</span>
</button>
</div>
@ -720,14 +726,14 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
</div>
<div className="grid grid-cols-2 gap-2 text-[10px] bg-white p-2.5 rounded-xl border border-slate-100 font-bold text-slate-600">
<div>Salary: <span className="text-slate-800">{w.salary} AED</span></div>
<div>Age: <span className="text-slate-800">{w.age} yrs</span></div>
<div>Job Type: <span className="text-slate-800 uppercase">{w.preferred_job_type}</span></div>
<div>Status: <span className="text-slate-800 font-black">{w.availability_status}</span></div>
<div>{t('salary', 'Salary')}: <span className="text-slate-800">{w.salary} {t('aed', 'AED')}</span></div>
<div>{t('age', 'Age')}: <span className="text-slate-800">{w.age} {t('yrs', 'yrs')}</span></div>
<div>{t('job_type', 'Job Type')}: <span className="text-slate-800 uppercase">{w.preferred_job_type}</span></div>
<div>{t('status', 'Status')}: <span className="text-slate-800 font-black">{w.availability_status}</span></div>
</div>
<div className="space-y-1">
<div className="text-[8px] font-black text-slate-400 uppercase tracking-wider">Skills</div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-wider">{t('skills')}</div>
<div className="flex flex-wrap gap-1">
{w.skills?.map(skill => (
<span key={skill} className="px-1.5 py-0.5 bg-blue-50 border border-blue-100 text-[#185FA5] text-[8px] font-black rounded uppercase tracking-wider">
@ -781,11 +787,11 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
<div className="grid grid-cols-2 gap-4 text-xs font-bold text-slate-600">
<div className="p-3 bg-slate-50/50 rounded-xl">
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">Expectations</div>
<div className="text-slate-800">{previewWorker.salary} AED / mo</div>
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">{t('expectations', 'Expectations')}</div>
<div className="text-slate-800">{previewWorker.salary} {t('aed', 'AED')} / {t('mo', 'mo')}</div>
</div>
<div className="p-3 bg-slate-50/50 rounded-xl">
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">Languages</div>
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">{t('languages_spoken', 'Languages')}</div>
<div className="flex flex-wrap gap-1.5 mt-1">
{previewWorker.languages?.map(lang => (
<span key={lang} className="text-[9px] bg-white border border-slate-200 text-slate-700 px-2 py-0.5 rounded font-bold flex items-center space-x-1">
@ -796,7 +802,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
</div>
</div>
<div className="p-3 bg-slate-50/50 rounded-xl">
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">Availability Status</div>
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">{t('availability_status', 'Availability Status')}</div>
<span className={`inline-block px-2 py-0.5 text-[8px] font-black rounded-lg uppercase tracking-wider mt-1 border ${
previewWorker.availability_status === 'Active' ? 'bg-emerald-50 text-emerald-700 border-emerald-200' :
previewWorker.availability_status === 'Hired' ? 'bg-blue-50 text-blue-700 border-blue-200' :
@ -806,14 +812,14 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
</span>
</div>
<div className="p-3 bg-slate-50/50 rounded-xl">
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">Job Preference</div>
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-0.5">{t('job_preference', 'Job Preference')}</div>
<div className="text-slate-800 uppercase text-[10px] mt-1">{previewWorker.preferred_job_type}</div>
</div>
</div>
{/* Core Platform Skills inside Quick Preview */}
<div className="space-y-1 pt-1">
<div className="text-[9px] font-black text-slate-400 uppercase tracking-widest">Platform Skills</div>
<div className="text-[9px] font-black text-slate-400 uppercase tracking-widest">{t('platform_skills', 'Platform Skills')}</div>
<div className="flex flex-wrap gap-1">
{previewWorker.skills?.map(skill => (
<span key={skill} className="px-2.5 py-0.5 bg-blue-50 border border-blue-100 text-[#185FA5] text-[9px] font-black rounded-lg uppercase tracking-wider">
@ -829,13 +835,13 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
className="flex-1 border border-slate-200 hover:bg-slate-50 rounded-xl h-11 text-xs font-bold text-slate-700 flex items-center justify-center space-x-2"
>
<Bookmark className="w-4 h-4" />
<span>{shortlistedIds.includes(previewWorker.id) ? 'Shortlisted ✓' : 'Add to Shortlist'}</span>
<span>{shortlistedIds.includes(previewWorker.id) ? t('shortlisted', 'Shortlisted ✓') : t('add_to_shortlist', 'Add to Shortlist')}</span>
</button>
<Link
href={`/employer/workers/${previewWorker.id}`}
className="flex-1 bg-[#185FA5] hover:bg-[#144f8a] text-white rounded-xl h-11 text-xs font-black flex items-center justify-center shadow-xs"
>
View Full Details
{t('view_full_details', 'View Full Details')}
</Link>
</div>
</div>
@ -861,7 +867,7 @@ export default function Index({ initialWorkers = [], initialShortlistedIds = [],
onClick={() => setShowPresetModal(false)}
className="px-4 py-2 border border-slate-200 hover:bg-slate-50 rounded-lg"
>
Cancel
{t('cancel', 'Cancel')}
</button>
<button
type="submit"

View File

@ -1,6 +1,7 @@
import React, { useState } from 'react';
import { Head, Link, router } from '@inertiajs/react';
import EmployerLayout from '../../../Layouts/EmployerLayout';
import { useTranslation } from '../../../lib/LanguageContext';
import {
CheckCircle2,
Globe2,
@ -40,6 +41,7 @@ const getLanguageFlag = (lang) => {
};
export default function Show({ worker }) {
const { t } = useTranslation();
const [showReportModal, setShowReportModal] = useState(false);
const [reportReason, setReportReason] = useState('');
const [reportDetails, setReportDetails] = useState('');
@ -57,20 +59,20 @@ export default function Show({ worker }) {
const handleShare = () => {
navigator.clipboard.writeText(window.location.href);
toast.success("📋 Profile link copied to clipboard!", {
description: "You can now share this URL with your family or sponsor contacts."
toast.success(t('profile_link_copied', 'Profile link copied to clipboard!'), {
description: t('profile_link_copied_desc', 'You can now share this URL with your family or sponsor contacts.')
});
};
const handleReportSubmit = (e) => {
e.preventDefault();
if (!reportReason) {
toast.error("Please select a reason for reporting.");
toast.error(t('select_report_reason', 'Please select a reason for reporting.'));
return;
}
toast.success("🛡️ Worker report submitted successfully", {
description: "Our admin compliance team will investigate this worker's credentials within 24 hours."
toast.success(t('report_submitted', 'Worker report submitted successfully'), {
description: t('report_submitted_desc', "Our admin compliance team will investigate this worker's credentials within 24 hours.")
});
setShowReportModal(false);
setReportReason('');
@ -80,21 +82,21 @@ export default function Show({ worker }) {
const handleReviewSubmit = (e) => {
e.preventDefault();
if (!newComment.trim()) {
toast.error("Please add a comment.");
toast.error(t('add_comment', 'Please add a comment.'));
return;
}
const newReview = {
id: Date.now(),
employer_name: "You (Verified Sponsor)",
employer_name: t('you_verified_sponsor', 'You (Verified Sponsor)'),
rating: newRating,
date: "Today",
date: t('today', 'Today'),
comment: newComment,
};
setWorkerReviews([newReview, ...workerReviews]);
toast.success("⭐ Review posted successfully!", {
description: "Your trust feedback is live and helps other sponsors hire securely."
toast.success(t('review_posted', 'Review posted successfully!'), {
description: t('review_posted_desc', 'Your trust feedback is live and helps other sponsors hire securely.')
});
setShowReviewModal(false);
setNewComment('');
@ -105,21 +107,26 @@ export default function Show({ worker }) {
router.post('/employer/shortlist/toggle', { worker_id: worker.id }, {
preserveScroll: true,
onSuccess: () => {
toast.success(isShortlisted ? "Removed from Shortlist" : "Added to Shortlist");
toast.success(isShortlisted ? t('removed_from_shortlist', 'Removed from Shortlist') : t('added_to_shortlist', 'Added to Shortlist'));
}
});
};
const handleMarkHired = () => {
router.post(`/employer/workers/${worker.id}/mark-hired`, {}, {
preserveScroll: true,
onSuccess: () => {
setAvailabilityStatus('Hired');
setShowHiredModal(true);
toast.success("🎉 Worker successfully marked as Hired!", {
description: "Sponsorship direct match finalized. Please leave an anonymous trust review!"
toast.success(t('marked_hired', 'Worker successfully marked as Hired!'), {
description: t('marked_hired_desc', 'Sponsorship direct match finalized. Please leave an anonymous trust review!')
});
}
});
};
return (
<EmployerLayout title="Candidate Profile Detail">
<EmployerLayout title={t('candidate_profile_detail', 'Candidate Profile Detail')}>
<Head title={`${worker.name} - ${worker.category} Profile`} />
<div className="space-y-6 select-none w-full pb-16">
@ -131,7 +138,7 @@ export default function Show({ worker }) {
className="inline-flex items-center space-x-2 text-xs font-black text-slate-500 hover:text-[#185FA5] transition-colors"
>
<ArrowLeft className="w-4 h-4" />
<span>BACK TO FIND WORKERS</span>
<span>{t('back_to_find_workers', 'BACK TO FIND WORKERS')}</span>
</Link>
{/* Quick Profile Actions */}
@ -142,7 +149,7 @@ export default function Show({ worker }) {
title="Share Profile link"
>
<Share2 className="w-4 h-4" />
<span className="hidden sm:inline">Share Profile</span>
<span className="hidden sm:inline">{t('share_profile', 'Share Profile')}</span>
</button>
<button
@ -151,7 +158,7 @@ export default function Show({ worker }) {
title="Report Abuse / Terms violations"
>
<Flag className="w-4 h-4" />
<span className="hidden sm:inline">Report Worker</span>
<span className="hidden sm:inline">{t('report_worker', 'Report Worker')}</span>
</button>
</div>
</div>
@ -175,7 +182,7 @@ export default function Show({ worker }) {
{worker.verified && (
<span className="inline-flex items-center px-2 py-0.5 rounded-full text-[9px] font-black uppercase tracking-wider bg-emerald-500 text-white shadow-xs gap-1 animate-pulse" title="OCR Verified via UAE PDPL Compliant Pipeline">
<CheckCircle2 className="w-3.5 h-3.5" />
<span>Verified</span>
<span>{t('verified')}</span>
</span>
)}
@ -198,12 +205,12 @@ export default function Show({ worker }) {
{worker.visa_status && (worker.visa_status.toLowerCase().includes('tourist') || worker.visa_status.toLowerCase().includes('visit')) ? (
<div className="flex items-center space-x-1.5 bg-amber-50 px-2.5 py-1 rounded-lg text-amber-800 border border-amber-200 text-[9px] font-black uppercase tracking-wider w-fit shadow-xs">
<AlertTriangle className="w-3.5 h-3.5 text-amber-600 animate-bounce" />
<span>{worker.visa_status} (Warning: Visit Visa)</span>
<span>{worker.visa_status} ({t('warning', 'Warning')}: {t('visit_visa', 'Visit Visa')})</span>
</div>
) : worker.visa_status && worker.visa_status.toLowerCase().includes('cancelled') ? (
<div className="flex items-center space-x-1.5 bg-rose-50 px-2.5 py-1 rounded-lg text-rose-800 border border-rose-200 text-[9px] font-black uppercase tracking-wider w-fit shadow-xs animate-pulse">
<AlertTriangle className="w-3.5 h-3.5 text-rose-600" />
<span>{worker.visa_status} (Warning: Cancelled)</span>
<span>{worker.visa_status} ({t('warning', 'Warning')}: {t('cancelled', 'Cancelled')})</span>
</div>
) : (
<div className="flex items-center space-x-1.5 bg-blue-50 px-2.5 py-1 rounded-lg text-blue-700 border border-blue-100 text-[9px] font-black uppercase tracking-wider w-fit">
@ -218,13 +225,13 @@ export default function Show({ worker }) {
<span>{worker.nationality}</span>
</span>
<span></span>
<span>{worker.age} Years Old</span>
<span>{worker.age} {t('years_old', 'Years Old')}</span>
<span></span>
<span className="bg-blue-50 text-[#185FA5] border border-blue-100 px-2 py-0.5 rounded text-[10px] uppercase font-black tracking-widest">{worker.category}</span>
</div>
<div className="flex items-center space-x-1 text-amber-500 font-bold text-xs">
<Star className="w-3.5 h-3.5 fill-amber-500 text-amber-500" />
<span className="text-slate-700">{worker.rating} / 5.0 ({workerReviews.length} reviews)</span>
<span className="text-slate-700">{worker.rating} / 5.0 ({workerReviews.length} {t('reviews', 'reviews')})</span>
</div>
</div>
</div>
@ -250,18 +257,20 @@ export default function Show({ worker }) {
className="bg-white border border-slate-250 hover:bg-slate-50 px-6 py-3 rounded-xl font-bold text-sm shadow-xs transition-colors flex items-center justify-center space-x-2 text-slate-700 flex-1 sm:flex-initial"
>
<MessageSquare className="w-4 h-4 text-slate-500" />
<span>Start Direct Chat</span>
<span>{t('start_direct_chat', 'Start Direct Chat')}</span>
</Link>
{/* Stage 4 Hire: Mark Hired (Finalize Hiring Direct Flow) */}
{availabilityStatus !== 'Hired' && (
<button
type="button"
onClick={handleMarkHired}
className="bg-emerald-600 hover:bg-emerald-700 text-white border border-emerald-700 px-8 py-3 rounded-xl font-black text-sm shadow-md transition-all flex items-center justify-center space-x-2 flex-1 sm:flex-initial scale-105 active:scale-100"
>
<CheckCircle2 className="w-4 h-4 text-white" />
<span>Mark Hired</span>
<span>{t('mark_hired_action', 'Mark Hired')}</span>
</button>
)}
</div>
</div>
@ -270,20 +279,20 @@ export default function Show({ worker }) {
{/* Left Column: Quick Stats */}
<div className="space-y-6">
<div className="bg-slate-50 p-6 rounded-2xl border border-slate-200 space-y-4">
<h3 className="font-black text-xs text-slate-500 uppercase tracking-widest">Sponsorship Details</h3>
<h3 className="font-black text-xs text-slate-500 uppercase tracking-widest">{t('sponsorship_details', 'Sponsorship Details')}</h3>
<div className="flex items-center justify-between pb-3 border-b border-slate-200">
<div className="flex items-center space-x-2 text-xs text-slate-600 font-bold">
<DollarSign className="w-4 h-4 text-emerald-600" />
<span>Salary Expectations</span>
<span>{t('salary_expectations', 'Salary Expectations')}</span>
</div>
<span className="font-extrabold text-slate-900 text-sm">{worker.salary} AED / mo</span>
<span className="font-extrabold text-slate-900 text-sm">{worker.salary} {t('aed', 'AED')} / {t('mo', 'mo')}</span>
</div>
<div className="flex items-center justify-between pb-3 border-b border-slate-200">
<div className="flex items-center space-x-2 text-xs text-slate-600 font-bold">
<Calendar className="w-4 h-4 text-[#185FA5]" />
<span>Availability Status</span>
<span>{t('availability_status', 'Availability Status')}</span>
</div>
<span className="font-black text-[#185FA5] bg-blue-50 px-2 py-0.5 rounded text-xs border border-blue-100">
{availabilityStatus}
@ -293,7 +302,7 @@ export default function Show({ worker }) {
<div className="flex items-center justify-between pb-3 border-b border-slate-200">
<div className="flex items-center space-x-2 text-xs text-slate-600 font-bold">
<Briefcase className="w-4 h-4 text-amber-600" />
<span>Work Experience</span>
<span>{t('work_experience', 'Work Experience')}</span>
</div>
<span className="font-extrabold text-slate-900 text-xs">{worker.experience}</span>
</div>
@ -301,7 +310,7 @@ export default function Show({ worker }) {
<div className="flex items-center justify-between pb-3 border-b border-slate-200">
<div className="flex items-center space-x-2 text-xs text-slate-600 font-bold">
<Sparkles className="w-4 h-4 text-purple-600" />
<span>Preferred Job Type</span>
<span>{t('preferred_job_type', 'Preferred Job Type')}</span>
</div>
<span className="font-black text-slate-900 text-xs uppercase">{worker.preferred_job_type}</span>
</div>
@ -309,7 +318,7 @@ export default function Show({ worker }) {
<div className="flex items-center justify-between pb-3 border-b border-slate-200">
<div className="flex items-center space-x-2 text-xs text-slate-655 font-bold">
<ShieldCheck className="w-4 h-4 text-emerald-600" />
<span>Emirates ID Vetting</span>
<span>{t('emirates_id_vetting', 'Emirates ID Vetting')}</span>
</div>
<span className="font-bold text-emerald-700 text-xs uppercase">{worker.emirates_id_status}</span>
</div>
@ -317,7 +326,7 @@ export default function Show({ worker }) {
<div className="flex items-center justify-between pb-3 border-b border-slate-200">
<div className="flex items-center space-x-2 text-xs text-slate-600 font-bold">
<FileText className="w-4 h-4 text-blue-600" />
<span>Visa Status</span>
<span>{t('visa_status', 'Visa Status')}</span>
</div>
<span className="font-bold text-blue-700 text-xs uppercase">{worker.visa_status}</span>
</div>
@ -325,10 +334,10 @@ export default function Show({ worker }) {
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2 text-xs text-slate-600 font-bold">
<CheckCircle2 className="w-4 h-4 text-emerald-600" />
<span>Medical Health Test</span>
<span>{t('medical_health_test', 'Medical Health Test')}</span>
</div>
<span className="font-black text-emerald-700 bg-emerald-50 px-2.5 py-0.5 rounded text-[10px] uppercase border border-emerald-200">
PASSED CERTIFIED
{t('passed_certified', 'PASSED CERTIFIED')}
</span>
</div>
</div>
@ -337,7 +346,7 @@ export default function Show({ worker }) {
<div className="bg-slate-50 p-6 rounded-2xl border border-slate-200 space-y-3">
<div className="flex items-center space-x-2 font-bold text-sm text-slate-800">
<Languages className="w-4 h-4 text-[#185FA5]" />
<span>Languages Spoken</span>
<span>{t('languages_spoken', 'Languages Spoken')}</span>
</div>
<div className="flex flex-wrap gap-2">
{worker.languages?.map(lang => (
@ -354,7 +363,7 @@ export default function Show({ worker }) {
<div className="lg:col-span-2 space-y-8">
{/* Professional Summary */}
<div className="space-y-3">
<h3 className="font-extrabold text-base text-slate-900">Professional Summary</h3>
<h3 className="font-extrabold text-base text-slate-900">{t('professional_summary', 'Professional Summary')}</h3>
<p className="text-sm text-slate-600 leading-relaxed bg-slate-50 p-6 rounded-2xl border border-slate-200 italic">
"{worker.bio}"
</p>
@ -362,7 +371,7 @@ export default function Show({ worker }) {
{/* Verified Skills & Competencies */}
<div className="space-y-4">
<h3 className="font-extrabold text-base text-slate-900">Verified Skills & Competencies</h3>
<h3 className="font-extrabold text-base text-slate-900">{t('verified_skills_competencies', 'Verified Skills & Competencies')}</h3>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{worker.skills?.map(skill => (
<div key={skill} className="flex items-center space-x-3 p-3.5 bg-white border border-slate-200 rounded-xl shadow-xs">
@ -377,39 +386,39 @@ export default function Show({ worker }) {
<div className="space-y-4">
<h3 className="font-extrabold text-base text-slate-900 flex items-center space-x-2">
<ShieldCheck className="w-5 h-5 text-emerald-600" />
<span>Verified Legal Documents (UAE MOHRE Vetted)</span>
<span>{t('verified_legal_docs', 'Verified Legal Documents (UAE MOHRE Vetted)')}</span>
</h3>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* Document Card: Passport */}
<div className="bg-white border border-slate-200 rounded-2xl overflow-hidden shadow-xs hover:shadow-sm">
<div className="bg-slate-50 px-4 py-3 border-b border-slate-100 flex items-center justify-between">
<span className="text-[10px] font-black text-slate-500 uppercase tracking-widest">Passport (Verified)</span>
<span className="text-[10px] font-black text-slate-500 uppercase tracking-widest">{t('passport_verified', 'Passport (Verified)')}</span>
<FileText className="w-4 h-4 text-slate-400" />
</div>
<div className="p-4 flex space-x-4">
<div className="w-20 h-28 bg-slate-100 rounded-lg flex-shrink-0 border border-slate-200 flex flex-col items-center justify-center p-2 relative group cursor-zoom-in">
<Search className="w-5 h-5 text-slate-300" />
<span className="absolute bottom-1 text-[7px] font-bold text-slate-400 uppercase">Click zoom</span>
<span className="absolute bottom-1 text-[7px] font-bold text-slate-400 uppercase">{t('click_zoom', 'Click zoom')}</span>
</div>
<div className="flex-1 space-y-2">
<div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">Document ID</div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">{t('document_id', 'Document ID')}</div>
<div className="text-xs font-bold text-slate-800">L82739102-UAE</div>
</div>
<div className="grid grid-cols-2 gap-1">
<div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">Issue</div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">{t('issue_date', 'Issue')}</div>
<div className="text-[10px] font-bold text-slate-800">12 Jan 2021</div>
</div>
<div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">Expiry</div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">{t('expiry_date', 'Expiry')}</div>
<div className="text-[10px] font-bold text-emerald-600">11 Jan 2031</div>
</div>
</div>
<div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">OCR Match</div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">{t('ocr_match', 'OCR Match')}</div>
<div className="flex items-center space-x-2 mt-0.5">
<div className="flex-1 h-1 bg-slate-100 rounded-full overflow-hidden">
<div className="h-full bg-emerald-500 w-[95%]" />
@ -424,31 +433,31 @@ export default function Show({ worker }) {
{/* Document Card: Emirates ID */}
<div className="bg-white border border-slate-200 rounded-2xl overflow-hidden shadow-xs hover:shadow-sm">
<div className="bg-slate-50 px-4 py-3 border-b border-slate-100 flex items-center justify-between">
<span className="text-[10px] font-black text-slate-500 uppercase tracking-widest">Emirates ID (PDPL Compliant)</span>
<span className="text-[10px] font-black text-slate-500 uppercase tracking-widest">{t('emirates_id_pdpl', 'Emirates ID (PDPL Compliant)')}</span>
<ShieldCheck className="w-4 h-4 text-emerald-500" />
</div>
<div className="p-4 flex space-x-4">
<div className="w-20 h-28 bg-slate-950 rounded-lg flex-shrink-0 border border-slate-800 flex flex-col items-center justify-center p-1.5 text-center relative shadow-inner">
<ShieldCheck className="w-6 h-6 text-emerald-500 mb-1 animate-pulse" />
<span className="text-[6px] font-black text-emerald-500 uppercase tracking-tighter block">Scan Purged</span>
<span className="text-[5px] font-medium text-slate-400 mt-1 leading-tight block">UAE PDPL compliant</span>
<span className="text-[6px] font-black text-emerald-500 uppercase tracking-tighter block">{t('scan_purged', 'Scan Purged')}</span>
<span className="text-[5px] font-medium text-slate-400 mt-1 leading-tight block">{t('uae_pdpl_compliant', 'UAE PDPL compliant')}</span>
</div>
<div className="flex-1 space-y-2">
<div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">Verification Type</div>
<div className="text-xs font-black text-slate-800">Emirates ID OCR</div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">{t('verification_type', 'Verification Type')}</div>
<div className="text-xs font-black text-slate-800">{t('emirates_id_ocr', 'Emirates ID OCR')}</div>
</div>
<div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">Status</div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">{t('status', 'Status')}</div>
<div className="flex items-center space-x-1 mt-0.5">
<CheckCircle2 className="w-3.5 h-3.5 text-emerald-600 flex-shrink-0" />
<span className="text-[9px] font-black text-emerald-700 uppercase tracking-wider">{worker.emirates_id_status}</span>
</div>
</div>
<div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">Physical Scan Storage</div>
<span className="text-[7px] font-mono text-emerald-600 bg-emerald-50 px-1 py-0.5 rounded font-black uppercase tracking-wider block w-fit border border-emerald-100">Permanently Purged</span>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">{t('physical_scan_storage', 'Physical Scan Storage')}</div>
<span className="text-[7px] font-mono text-emerald-600 bg-emerald-50 px-1 py-0.5 rounded font-black uppercase tracking-wider block w-fit border border-emerald-100">{t('permanently_purged', 'Permanently Purged')}</span>
</div>
</div>
</div>
@ -457,7 +466,7 @@ export default function Show({ worker }) {
{/* Document Card: Visa */}
<div className="bg-white border border-slate-200 rounded-2xl overflow-hidden shadow-xs hover:shadow-sm">
<div className="bg-slate-50 px-4 py-3 border-b border-slate-100 flex items-center justify-between">
<span className="text-[10px] font-black text-slate-500 uppercase tracking-widest">Entry Visa (Verified)</span>
<span className="text-[10px] font-black text-slate-500 uppercase tracking-widest">{t('entry_visa_verified', 'Entry Visa (Verified)')}</span>
{worker.visa_status && (worker.visa_status.toLowerCase().includes('tourist') || worker.visa_status.toLowerCase().includes('visit') || worker.visa_status.toLowerCase().includes('cancelled')) ? (
<AlertTriangle className="w-4 h-4 text-amber-500 animate-pulse" />
) : (
@ -467,29 +476,29 @@ export default function Show({ worker }) {
<div className="p-4 flex space-x-4">
<div className="w-20 h-28 bg-slate-100 rounded-lg flex-shrink-0 border border-slate-200 flex flex-col items-center justify-center p-2 relative group cursor-zoom-in">
<Search className="w-5 h-5 text-slate-300" />
<span className="absolute bottom-1 text-[7px] font-bold text-slate-400 uppercase">Click zoom</span>
<span className="absolute bottom-1 text-[7px] font-bold text-slate-400 uppercase">{t('click_zoom', 'Click zoom')}</span>
</div>
<div className="flex-1 space-y-2">
<div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">Visa Category</div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">{t('visa_category', 'Visa Category')}</div>
<div className="text-xs font-bold text-slate-800">{worker.visa_status}</div>
</div>
<div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">Vetting status</div>
<div className="text-[8px] font-black text-slate-400 uppercase tracking-tighter">{t('vetting_status', 'Vetting status')}</div>
<div className="flex items-center space-x-1.5 mt-0.5">
{worker.visa_status && (worker.visa_status.toLowerCase().includes('tourist') || worker.visa_status.toLowerCase().includes('visit')) ? (
<span className="inline-flex items-center bg-amber-50 border border-amber-200 text-[8px] font-black uppercase text-amber-700 px-1.5 py-0.5 rounded tracking-wide">
Transfer Required
{t('transfer_required', 'Transfer Required')}
</span>
) : worker.visa_status && worker.visa_status.toLowerCase().includes('cancelled') ? (
<span className="inline-flex items-center bg-rose-50 border border-rose-200 text-[8px] font-black uppercase text-rose-700 px-1.5 py-0.5 rounded tracking-wide animate-pulse">
Needs Regularization
{t('needs_regularization', 'Needs Regularization')}
</span>
) : (
<>
<CheckCircle2 className="w-3.5 h-3.5 text-emerald-600" />
<span className="text-[9px] font-bold text-slate-700">Clear Records</span>
<span className="text-[9px] font-bold text-slate-700">{t('clear_records', 'Clear Records')}</span>
</>
)}
</div>
@ -508,14 +517,14 @@ export default function Show({ worker }) {
<div className="bg-white p-8 rounded-3xl border border-slate-200 shadow-sm space-y-6">
<div className="flex items-center justify-between border-b border-slate-150 pb-4">
<div className="space-y-1">
<h3 className="font-extrabold text-base text-slate-900">Sponsor Reviews & Star Ratings</h3>
<p className="text-xs text-slate-500 font-medium">Ratings can only be posted by verified sponsors who completed verified direct hiring.</p>
<h3 className="font-extrabold text-base text-slate-900">{t('sponsor_reviews_star_ratings', 'Sponsor Reviews & Star Ratings')}</h3>
<p className="text-xs text-slate-500 font-medium">{t('reviews_posted_by_sponsors_desc', 'Ratings can only be posted by verified sponsors who completed verified direct hiring.')}</p>
</div>
<button
onClick={() => setShowReviewModal(true)}
className="bg-[#185FA5] hover:bg-[#144f8a] text-white px-5 py-2.5 rounded-xl text-xs font-bold shadow-xs transition-colors"
>
Post a Trust Review
{t('post_trust_review', 'Post a Trust Review')}
</button>
</div>
@ -547,7 +556,7 @@ export default function Show({ worker }) {
{/* Similar Recommendations Slider */}
<div className="space-y-4">
<h3 className="font-extrabold text-base text-slate-900">Similar Recommended Workers</h3>
<h3 className="font-extrabold text-base text-slate-900">{t('similar_recommended_workers', 'Similar Recommended Workers')}</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{worker.similar_workers?.map((sim) => (
<div key={sim.id} className="bg-white p-5 rounded-2xl border border-slate-200 shadow-xs space-y-4">
@ -561,12 +570,12 @@ export default function Show({ worker }) {
</span>
</div>
<div className="flex items-center justify-between pt-2 border-t border-slate-100">
<span className="font-black text-slate-800 text-xs">{sim.salary} AED/mo</span>
<span className="font-black text-slate-800 text-xs">{sim.salary} {t('aed', 'AED')}/{t('mo', 'mo')}</span>
<Link
href={`/employer/workers/${sim.id}`}
className="text-[#185FA5] font-black text-xs hover:underline flex items-center space-x-1"
>
<span>View Profile</span>
<span>{t('view_profile', 'View Profile')}</span>
<span></span>
</Link>
</div>
@ -585,16 +594,16 @@ export default function Show({ worker }) {
<div className="w-16 h-16 bg-emerald-50 text-emerald-600 rounded-full flex items-center justify-center mx-auto shadow-inner">
<CheckCircle2 className="w-8 h-8" />
</div>
<h4 className="font-extrabold text-lg text-slate-900">Direct Sponsoring Finalized!</h4>
<h4 className="font-extrabold text-lg text-slate-900">{t('direct_sponsoring_finalized', 'Direct Sponsoring Finalized!')}</h4>
<p className="text-xs text-slate-500 leading-relaxed">
{worker.name} is successfully marked as <strong>Hired</strong> under your sponsorship! This direct matching conforms exactly with Stage 4 of our UAE MOHRE zero-middlemen flow.
{t('hired_under_sponsorship_desc', '{name} is successfully marked as Hired under your sponsorship! This direct matching conforms exactly with Stage 4 of our UAE MOHRE zero-middlemen flow.').replace('{name}', worker.name)}
</p>
</div>
<div className="p-4 bg-blue-50/50 rounded-2xl border border-blue-100/50 space-y-2">
<span className="text-[9px] font-black text-[#185FA5] uppercase tracking-widest block">Next Step: Stage 5 Post-Hire Review</span>
<span className="text-[9px] font-black text-[#185FA5] uppercase tracking-widest block">{t('next_step_post_hire_review', 'Next Step: Stage 5 Post-Hire Review')}</span>
<p className="text-[11px] text-slate-700 leading-relaxed font-bold">
Help the UAE community hire safely by posting an anonymous review describing {worker.name}'s childcare, cooking, driving, or domestic skills.
{t('help_community_post_review', "Help the UAE community hire safely by posting an anonymous review describing {name}'s childcare, cooking, driving, or domestic skills.").replace('{name}', worker.name)}
</p>
</div>
@ -607,13 +616,13 @@ export default function Show({ worker }) {
className="w-full bg-[#185FA5] hover:bg-[#144f8a] text-white py-3 rounded-xl flex items-center justify-center space-x-2"
>
<Star className="w-4 h-4 fill-white" />
<span>Leave a Trust Review</span>
<span>{t('leave_trust_review', 'Leave a Trust Review')}</span>
</button>
<Link
href="/employer/workers"
className="w-full bg-slate-50 border border-slate-200 hover:bg-slate-100 text-slate-700 py-3 rounded-xl flex items-center justify-center"
>
Back to Worker Directory
{t('back_to_worker_directory', 'Back to Worker Directory')}
</Link>
</div>
</div>
@ -634,36 +643,36 @@ export default function Show({ worker }) {
<div className="flex items-center space-x-2 text-rose-600">
<AlertTriangle className="w-5 h-5" />
<h4 className="font-black text-sm uppercase">Report Vetting Abuse / Terms Violation</h4>
<h4 className="font-black text-sm uppercase">{t('report_abuse_violation', 'Report Vetting Abuse / Terms Violation')}</h4>
</div>
<p className="text-xs text-slate-500 leading-relaxed">
We maintain zero-tolerance for fake documentation, independent recruiters trading cash, or incorrect contact details.
{t('zero_tolerance_abuse_desc', 'We maintain zero-tolerance for fake documentation, independent recruiters trading cash, or incorrect contact details.')}
</p>
<div className="space-y-3">
<div className="space-y-1">
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Reason</label>
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">{t('reason', 'Reason')}</label>
<select
value={reportReason}
onChange={(e) => setReportReason(e.target.value)}
className="w-full p-2.5 border border-slate-300 rounded-xl text-xs font-bold text-slate-700 bg-slate-50 focus:outline-none"
>
<option value="">Select a reason...</option>
<option value="fees">Worker / agent requested hiring commission fees</option>
<option value="profile">Profile details / passport did not match actual person</option>
<option value="contact">Invalid phone number / unreachable</option>
<option value="other">Other compliance violations</option>
<option value="">{t('select_reason', 'Select a reason...')}</option>
<option value="fees">{t('reason_fees', 'Worker / agent requested hiring commission fees')}</option>
<option value="profile">{t('reason_profile', 'Profile details / passport did not match actual person')}</option>
<option value="contact">{t('reason_contact', 'Invalid phone number / unreachable')}</option>
<option value="other">{t('reason_other', 'Other compliance violations')}</option>
</select>
</div>
<div className="space-y-1">
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Additional context details</label>
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">{t('additional_context_details', 'Additional context details')}</label>
<textarea
rows="3"
value={reportDetails}
onChange={(e) => setReportDetails(e.target.value)}
placeholder="Provide detailed specifics of what happened..."
placeholder={t('provide_specifics_placeholder', 'Provide detailed specifics of what happened...')}
className="w-full p-2.5 border border-slate-300 rounded-xl text-xs focus:outline-none"
/>
</div>
@ -675,13 +684,13 @@ export default function Show({ worker }) {
onClick={() => setShowReportModal(false)}
className="px-4 py-2 border border-slate-200 hover:bg-slate-50 rounded-lg"
>
Cancel
{t('cancel', 'Cancel')}
</button>
<button
type="submit"
className="px-4 py-2 bg-rose-600 text-white hover:bg-rose-700 rounded-lg shadow-sm"
>
Submit Compliance Report
{t('submit_compliance_report', 'Submit Compliance Report')}
</button>
</div>
</form>
@ -702,16 +711,16 @@ export default function Show({ worker }) {
<div className="flex items-center space-x-2 text-[#185FA5]">
<Star className="w-5 h-5 text-amber-500 fill-amber-500" />
<h4 className="font-black text-sm uppercase">Submit a Verified Performance Review</h4>
<h4 className="font-black text-sm uppercase">{t('submit_performance_review', 'Submit a Verified Performance Review')}</h4>
</div>
<p className="text-xs text-slate-500 leading-relaxed">
Your feedback helps other sponsors make secure and direct hiring choices.
{t('feedback_helps_sponsors_desc', 'Your feedback helps other sponsors make secure and direct hiring choices.')}
</p>
<div className="space-y-3">
<div className="space-y-1">
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest block">Star Rating</label>
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest block">{t('star_rating', 'Star Rating')}</label>
<div className="flex items-center space-x-1.5">
{[1, 2, 3, 4, 5].map((star) => (
<button
@ -729,12 +738,12 @@ export default function Show({ worker }) {
</div>
<div className="space-y-1">
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Share Your Experience</label>
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">{t('share_your_experience', 'Share Your Experience')}</label>
<textarea
rows="3"
value={newComment}
onChange={(e) => setNewComment(e.target.value)}
placeholder="Tell other sponsors about childcare skills, cleaning, cooking style, driving safety, etc..."
placeholder={t('share_experience_placeholder', 'Tell other sponsors about childcare skills, cleaning, cooking style, driving safety, etc...')}
className="w-full p-2.5 border border-slate-300 rounded-xl text-xs focus:outline-none"
/>
</div>
@ -746,13 +755,13 @@ export default function Show({ worker }) {
onClick={() => setShowReviewModal(false)}
className="px-4 py-2 border border-slate-200 hover:bg-slate-50 rounded-lg"
>
Cancel
{t('cancel', 'Cancel')}
</button>
<button
type="submit"
className="px-4 py-2 bg-[#185FA5] text-white hover:bg-[#144f8a] rounded-lg shadow-sm"
>
Post Trust Review
{t('post_trust_review_action', 'Post Trust Review')}
</button>
</div>
</form>

View File

@ -7,6 +7,7 @@ import { createInertiaApp } from '@inertiajs/react';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { Toaster } from 'sonner';
import { LanguageProvider } from './lib/LanguageContext';
const appName = import.meta.env.VITE_APP_NAME || 'Laravel';
@ -16,10 +17,10 @@ createInertiaApp({
setup({ el, App, props }) {
const root = createRoot(el);
root.render(
<>
<LanguageProvider>
<App {...props} />
<Toaster richColors position="top-right" closeButton />
</>
</LanguageProvider>
);
},
progress: {

426
resources/js/lang/en.json Normal file
View File

@ -0,0 +1,426 @@
{
"dashboard": "Dashboard",
"find_workers": "Find Workers",
"shortlist": "Shortlist",
"candidates": "Candidates",
"messages": "Messages",
"charity_events": "Charity Events",
"subscription": "Subscription",
"my_profile": "My Profile",
"search": "Search",
"profile": "Profile",
"sub_warning": "You need an active subscription to contact workers.",
"subscribe_now": "Subscribe now",
"employer_portal": "Employer Portal",
"active_until": "Active until",
"expired_renew": "Expired — Renew now",
"overview": "Overview",
"my_account": "My Account",
"profile_settings": "Profile Settings",
"sign_out": "Sign Out",
"employer_account": "Employer Account",
"welcome_title": "Welcome to Marketplace!",
"welcome_desc": "Your employer profile is verified and active with 30 days of Premium Access.",
"control_center": "Sponsor Control Center",
"dashboard_title": "Sponsor Dashboard - Verified UAE Domestic Workers",
"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.",
"renew_sub": "Renew Subscription",
"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.",
"renew_now": "Renew Now",
"sub_status": "Subscription Status",
"days_left": "Days Left",
"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.",
"browse_workers": "Browse 500+ Verified Workers",
"sponsor_pass_tier": "Sponsor Pass Tier",
"renews": "Renews",
"manage_billing": "Manage billing & invoices",
"pending_job_offers": "Pending Job Offers",
"direct_recruitment": "Direct recruitment proposals",
"view_hiring": "View hiring workflow",
"total_hired_workers": "Total Hired Workers",
"direct_contracts": "Direct contracts initiated",
"track_active_staff": "Track active staff",
"shortlisted_candidates": "Shortlisted Candidates",
"bookmark_list": "Bookmark list for interviews",
"open_shortlist": "Open shortlist book",
"discover_insights": "Discover Insights & Market Stats",
"dubai_insights": "Dubai General Market Insights",
"hired_dubai": "Hired using app in Dubai",
"cooking_care": "Cooking, Care, Driving",
"top_skills": "Top Skills Hired",
"turnover_rate": "Turnover rate",
"sponsor_activity": "Your Sponsor Activity Stats",
"workers_contacted": "Workers Contacted",
"secure_hires": "Secure Hires",
"quick_actions": "Quick Actions",
"speed_up": "Speed up your sponsorship process.",
"find_nannies": "Find Baby Care & Nannies",
"browse_nannies": "Browse premium verified nannies",
"whatsapp_support": "Direct WhatsApp Support",
"chat_manager": "Chat with a recruitment manager",
"legal_platform": "100% Legal UAE Agency-Free Platform",
"recommended_for_you": "Recommended for You",
"browse_all": "Browse all",
"view_profile": "View Profile",
"no_recommended": "No workers currently recommended. Update profile details.",
"active_shortlist": "Active Shortlist",
"view_book": "View book",
"category": "Category",
"availability": "Availability",
"open_profile": "Open Profile",
"shortlist_candidates_desc": "Shortlist candidates to compare their documents side-by-side",
"recent_chats": "Recent Chats",
"all_channels": "All channels",
"no_chats": "No recent chat logs found. Find workers to start conversing.",
"charity_drives": "Community Charity Drives",
"live_events": "Live Events",
"charity_drive": "Charity Drive",
"provided_items": "Provided Items",
"event_date": "Event Date",
"open_maps": "Open Google Maps Location Pin",
"mohre_compliant": "UAE Tadbeer & MOHRE Compliant",
"mohre_desc": "Our direct contract system aligns automatically with the Ministry of Human Resources and Emiratisation guidelines. Fully legal, zero agent fees, complete transparency.",
"visit_mohre": "Visit MOHRE UAE website",
"my_shortlist": "My Shortlist",
"candidates_saved": "You have {count} candidates saved for review",
"browse_more": "Browse more workers",
"verified": "Verified",
"warning": "Warning",
"platform_skills": "Platform Skills",
"languages_spoken": "Languages Spoken",
"quick_preview": "Quick Preview",
"compare_candidate": "Compare Candidate",
"comparing_active": "Comparing ✓",
"message": "Message",
"shortlist_empty": "Your shortlist is empty",
"shortlist_empty_desc": "Explore candidate profiles and add them to your saved shortlist.",
"find_workers_now": "Find Workers Now",
"comparing_workers": "Comparing Workers",
"clear_all": "Clear all",
"remove_shortlist": "Remove Shortlist",
"view_full_details": "View Full Details",
"no_bio_provided": "No bio details provided.",
"expectations": "Expectations",
"languages": "Languages",
"availability_status_label": "Availability Status",
"job_preference": "Job Preference",
"remove_from_shortlist": "Remove from shortlist",
"max_compare_alert": "You can compare a maximum of 3 candidates.",
"sponsor_pass_billing": "Sponsor Pass & Billing",
"subscription_billing_title": "Subscription Billing & Invoices - Employer Portal",
"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.",
"retry_payment_now": "Retry Payment Now",
"active_plan_pass": "Active Plan Pass",
"renewing_auto_payment_on": "Renewing via auto-payment on",
"simulate_billing_failure": "Simulate Billing Failure",
"verified_sponsor_status": "Verified Sponsor Status",
"sponsor_pass_updated": "Sponsor Pass updated successfully! PayTabs transaction logged.",
"available_subscription_tiers": "Available Subscription Tiers",
"available_subscription_tiers_desc": "Upgrade or cancel anytime. All contracts compliant with UAE Tadbeer MOHRE guides.",
"most_popular_tier": "Most Popular Tier",
"current_active_tier": "Current Active Tier ✓",
"select_plan_tier": "Select Plan Tier",
"billing_payment_receipts": "Billing Payment Receipts",
"tax_compliant_invoices": "Tax Compliant invoices",
"corporate_details": "Corporate Details",
"update_tax_invoicing": "Update tax invoicing options.",
"sponsor_email_address": "Sponsor Email Address",
"billing_vat_id": "Billing VAT Registry ID (Optional)",
"save_billing_profile": "Save Billing Profile",
"paytabs_secured_checkout": "PayTabs Secured Checkout",
"gateway_version": "Gateway v4.0",
"order_description": "Order description",
"total_amount": "Total amount",
"cardholder_name": "Cardholder Name",
"card_number": "Card Number",
"expiry_date": "Expiry Date (MM/YY)",
"security_code": "Security Code (CVV)",
"pci_dss_cryptography": "256-bit PCI DSS Cryptography Protected",
"authorize_payment": "Authorize Payment",
"simulated_billing_failure_triggered": "Simulated billing failure triggered!",
"simulated_billing_failure_desc": "An automatic system warning will now request payment retry options.",
"payment_approved": "Payment Approved by PayTabs!",
"successfully_subscribed_desc": "Successfully subscribed to {plan}. Premium access limits updated instantly.",
"invoice_generated": "Invoice {id} generated",
"invoice_download_desc": "Direct MOHRE Sponsor receipt downloaded in PDF format successfully.",
"corporate_billing_updated": "Corporate billing details updated.",
"invalid_card_format": "Invalid card number format",
"candidates_pipeline": "Candidates",
"candidates_pipeline_desc": "Manage your workforce recruitment pipeline",
"total_candidates": "Total Candidates",
"reviewing": "Reviewing",
"offer_sent": "Offer Sent",
"hired": "Hired",
"rejected": "Rejected",
"search_by_name": "Search by name...",
"candidate_header": "Candidate",
"selected_header": "Selected",
"category_header": "Category",
"salary_header": "Salary",
"status_header": "Status",
"actions_header": "Actions",
"change_status_label": "Change Status",
"no_candidates_found": "No candidates found",
"showing_candidates": "Showing {start} to {end} of {total} candidates",
"account_settings": "Account Settings",
"profile_employer_portal": "Profile - Employer Portal",
"profile_updated_successfully": "Profile updated successfully",
"profile_updated_successfully_desc": "Household sponsor preferences and vetted credentials synchronized successfully.",
"profile_update_failed": "Failed to update profile",
"check_form_fields": "Please check the form fields.",
"tab_personal": "Personal",
"tab_security": "Security & Password",
"tab_billing": "Billing & Receipts",
"tab_notifications": "Notifications Hub",
"emirates_id_vetted": "Emirates ID Vetted",
"direct_sponsor_portal": "Direct Sponsor Portal",
"personal_details_header": "Personal details",
"personal_details_desc": "Manage sponsor bio and credentials",
"full_sponsor_name": "Full Sponsor Name",
"invoicing_email": "Invoicing Email",
"uae_mobile_contact": "UAE Mobile Contact",
"sponsor_nationality": "Sponsor Nationality",
"select_nationality": "Select Nationality",
"uae_national": "UAE National",
"expat_uk_europe": "Expat (UK / Europe)",
"expat_usa_canada": "Expat (USA / Canada)",
"expat_asia_gcc": "Expat (Asia / GCC)",
"family_members_size": "Family Members Size",
"select_family_size": "Select Family Size",
"family_1_2": "1-2 Members",
"family_3_4": "3-4 Members",
"family_5_plus": "5+ Members",
"accommodation_residence": "Accommodation Residence",
"select_accommodation": "Select Accommodation",
"villa": "Villa",
"penthouse": "Apartment (Penthouse)",
"apartment_1_3": "Apartment (1-3 Bed)",
"city_district_area": "City District / Area",
"emirates_id_verification_header": "Emirates ID Verification",
"emirates_id_verification_desc": "Regulatory compliance credentials",
"emirates_id_verified_status": "Emirates ID Verified",
"mohre_guidelines": "Vetted under MOHRE Guidelines",
"emirates_id_verified_desc": "Your Emirates ID has been verified successfully. Your account is active for direct hiring.",
"verification_pending_status": "Verification Pending Audit",
"audit_queue": "Audit Queue",
"verification_pending_desc": "Your Emirates ID document uploads are currently under review. Audits are typically completed within 24 hours.",
"verification_required_status": "Emirates ID Verification Required",
"action_needed": "Action Needed",
"verification_required_desc": "Please upload high-resolution color scans of your Emirates ID to verify your identity and activate full hiring features.",
"emirates_id_front_side": "Emirates ID (Front Side)",
"emirates_id_back_side": "Emirates ID (Back Side)",
"uploaded_credentials_scans": "Uploaded Credentials Scans",
"view_scan": "View Scan",
"security_password_header": "Security & Password",
"security_password_desc": "Keep your sponsor account secure",
"current_password": "Current Password",
"new_password": "New Password",
"confirm_new_password": "Confirm New Password",
"current_plan": "Current Plan",
"active_status": "Active",
"next_payment": "Next Payment",
"recent_transactions": "Recent Transactions",
"date_header": "Date",
"description_header": "Description",
"amount_header": "Amount",
"receipt_header": "Receipt",
"notification_settings_hub": "Notification Settings Hub",
"notification_settings_desc": "Choose how you want to receive alerts",
"email_alerts": "Email Alerts",
"email_alerts_desc": "Receive vetted worker recommendations and visa updates.",
"sms_alerts": "SMS Instant Receipts",
"sms_alerts_desc": "Get SMS notifications for interview schedules.",
"push_alerts": "Push Notifications",
"push_alerts_desc": "Get desktop sound alerts for new direct messages.",
"changes_saved": "Changes saved successfully",
"emirates_id_reverification_notice": "Some updates may require Emirates ID re-verification.",
"update_settings": "Update Settings",
"charity_events_support_drives": "Charity Events & Support Drives",
"community_charity_events_sponsor_hub": "Community Charity Events - Sponsor Hub",
"community_charity_event_posted": "COMMUNITY CHARITY EVENT POSTED!",
"community_charity_event_posted_desc": "Instant Push Notification sent to all workers in Dubai! Morning-of reminder notification scheduled successfully.",
"dubai_community_support_drives": "Dubai Community Support Drives",
"free_medical_checks_title": "Free Medical Checks, Food Drives & Support Services",
"free_medical_checks_desc": "Organizing a support program? Share community campaigns directly. The platform will automatically push an instant pop-up notification to workers, followed by a morning-of event reminder to keep attendance strong.",
"search_charity_events_placeholder": "Search charity events & drives...",
"post_charity_event": "Post Charity Event",
"broadcast_support_program_desc": "Broadcast a support program, medical camp, or distribution drive to the worker community.",
"charity_drive_metadata": "Charity Drive Metadata (Dubai Support)",
"event_time_placeholder": "e.g. 9:00 AM - 4:00 PM",
"what_is_provided": "What is Being Provided",
"provided_items_placeholder": "e.g. Free Medical Check, Food Boxes, Supplies",
"location_details_pin": "Location Details & Pin URL",
"location_details_placeholder": "e.g. Al Quoz Community Center, Dubai",
"maps_pin_link_placeholder": "Google Maps Pin Link (e.g. https://maps.app.goo.gl/xyz)",
"title_label": "Title",
"title_placeholder": "e.g. Free Dental checkup by Emirates Charity",
"event_desc_instructions": "Event Description & Instructions",
"event_desc_placeholder": "Enter details of the charity event here...",
"publish_charity_event": "Publish Charity Event",
"no_announcements_title": "No Announcements",
"no_announcements_desc": "You haven't posted any announcements yet",
"community_charity_drive": "COMMUNITY CHARITY DRIVE",
"push_reminder_scheduled": "Push & Reminder Scheduled",
"provided_packages": "Provided Packages",
"event_timing": "Event Timing",
"event_location_address": "Event Location Address",
"view_map_location_pin": "View Map Location Pin",
"find_vetted_workers": "Find Vetted Domestic Workers",
"find_workers_platform": "Find Workers - Domestic Worker Platform",
"no_middlemen_platform": "No Middlemen Platform",
"find_verified_candidates": "Find Verified Candidates",
"connect_vetted_workers_desc": "Instantly connect with UAE vetted, background-checked domestic workers.",
"search_by_name_skills_bio": "Search by name, skills, bio (e.g. Cooking, Childcare, Gardening, Driving)...",
"default_match": "Default Match",
"salary_low_to_high": "Salary: Low to High",
"salary_high_to_low": "Salary: High to Low",
"rating_high_to_low": "Rating: High to Low",
"experience_level": "Experience Level",
"reset": "Reset",
"nationality": "Nationality",
"select_skills": "Select Skills",
"select_languages": "Select Languages",
"select_visa_status": "Select Visa Status",
"found_workers_matching": "Found {count} domestic workers matching search",
"direct_sponsoring_active": "MOHRE UAE Direct Sponsoring Active",
"load_more_workers": "Load More Workers",
"no_candidates_matching": "No candidates match your filters",
"adjust_filters_desc": "Try adjusting your salary limit, adding additional languages, or broadening nationality preferences.",
"reset_filters": "Reset Filters",
"comparing_workers_count": "Comparing Workers ({count} of 3)",
"expected": "Expected",
"region": "Region",
"visa_transfer": "Visa Transfer",
"medical_status": "Medical Status",
"passport_ocr": "Passport OCR",
"open_worker_profile": "Open Worker Profile",
"attach_verified_sponsor_docs": "Attach Verified Sponsor Documents",
"upload_sponsor_papers_desc": "Upload sponsor papers, employment agreements, or work descriptions to review securely.",
"select_files_drag": "Select files or drag here",
"max_file_size": "PDF, JPG, PNG (Max 5MB)",
"close": "Close",
"chat_with_worker": "Chat with {name} - Messages",
"messages_hub": "Messages Hub",
"ssl_secure": "SSL SECURE",
"active_now": "Active Now",
"whatsapp_bridge": "WhatsApp Bridge",
"toggle_context_sidebar": "Toggle Context Sidebar",
"today_realtime_chat": "Today • Realtime Chat Logs",
"read": "Read",
"type_compliant_message": "Type a compliant secure message...",
"conversation_messages": "Candidate Messages",
"messages_employer_portal": "Messages - Employer Portal",
"search_conversations": "Search conversations...",
"new_conversation": "New Conversation",
"active_threads": "Active Threads",
"total_conversations": "{count} Total",
"no_active_messages": "No active messages",
"no_active_messages_desc": "When you message workers or schedule interviews, your conversation threads will appear here.",
"candidate_profile_detail": "Candidate Profile Detail",
"back_to_find_workers": "BACK TO FIND WORKERS",
"share_profile": "Share Profile",
"report_worker": "Report Worker",
"sponsorship_details": "Sponsorship Details",
"salary_expectations": "Salary Expectations",
"work_experience": "Work Experience",
"emirates_id_vetting": "Emirates ID Vetting",
"medical_health_test": "Medical Health Test",
"passed_certified": "PASSED CERTIFIED",
"professional_summary": "Professional Summary",
"verified_skills_competencies": "Verified Skills & Competencies",
"verified_legal_documents": "Verified Legal Documents (UAE MOHRE Vetted)",
"passport_verified": "Passport (Verified)",
"click_zoom": "Click zoom",
"document_id": "Document ID",
"issue": "Issue",
"expiry": "Expiry",
"ocr_match": "OCR Match",
"emirates_id_pdpl": "Emirates ID (PDPL Compliant)",
"scan_purged": "Scan Purged",
"uae_pdpl_compliant": "UAE PDPL compliant",
"verification_type": "Verification Type",
"physical_scan_storage": "Physical Scan Storage",
"permanently_purged": "Permanently Purged",
"entry_visa_verified": "Entry Visa (Verified)",
"visa_category": "Visa Category",
"vetting_status": "Vetting status",
"transfer_required": "Transfer Required",
"needs_regularization": "Needs Regularization",
"clear_records": "Clear Records",
"sponsor_reviews_ratings": "Sponsor Reviews & Star Ratings",
"ratings_policy_desc": "Ratings can only be posted by verified sponsors who completed verified direct hiring.",
"post_trust_review": "Post a Trust Review",
"similar_recommended_workers": "Similar Recommended Workers",
"direct_sponsoring_finalized": "Direct Sponsoring Finalized!",
"hired_stage4_desc": "{name} is successfully marked as Hired under your sponsorship! This direct matching conforms exactly with Stage 4 of our UAE MOHRE zero-middlemen flow.",
"next_step_stage5": "Next Step: Stage 5 Post-Hire Review",
"post_hire_review_desc": "Help the UAE community hire safely by posting an anonymous review describing {name}'s childcare, cooking, driving, or domestic skills.",
"leave_trust_review": "Leave a Trust Review",
"back_to_directory": "Back to Worker Directory",
"report_abuse_title": "Report Vetting Abuse / Terms Violation",
"report_abuse_desc": "We maintain zero-tolerance for fake documentation, independent recruiters trading cash, or incorrect contact details.",
"reason": "Reason",
"select_reason": "Select a reason...",
"reason_fees": "Worker / agent requested hiring commission fees",
"reason_profile": "Profile details / passport did not match actual person",
"reason_contact": "Invalid phone number / unreachable",
"reason_other": "Other compliance violations",
"additional_context": "Additional context details",
"provide_specifics": "Provide detailed specifics of what happened...",
"cancel": "Cancel",
"submit_report": "Submit Compliance Report",
"submit_verified_review": "Submit a Verified Performance Review",
"review_help_desc": "Your feedback helps other sponsors make secure and direct hiring choices.",
"star_rating": "Star Rating",
"share_experience": "Share Your Experience",
"review_textarea_placeholder": "Tell other sponsors about childcare skills, cleaning, cooking style, driving safety, etc...",
"post_trust_review_btn": "Post Trust Review",
"start_direct_chat": "Start Direct Chat",
"mark_hired": "Mark Hired",
"selected": "Selected",
"total": "Total",
"candidate_messages": "Candidate Messages",
"search_conversations_placeholder": "Search conversations...",
"total_count": "{count} Total",
"chat_with": "Chat with",
"today_realtime_chat_logs": "Today • Realtime Chat Logs",
"just_now": "Just Now",
"direct_push_sent": "Direct Mobile Push Notification sent!",
"popped_up_instantly_desc": "Popped up instantly on {name}'s mobile device.",
"auto_reply_text": "Thank you for your response! I have reviewed your offer proposal and am looking forward to our video interview.",
"new_message_from": "New message from {name}!",
"document_attached": "Document attached successfully!",
"document_attached_msg": "Document Attached",
"today": "Today",
"chip_interview": "Are you available for a video interview today?",
"chip_salary": "What is your final expected salary?",
"chip_visa": "Can you transfer your visa immediately?",
"type_message_placeholder": "Type a compliant secure message...",
"compliance_profile": "Compliance Profile",
"transferable": "Transferable",
"cleared": "Cleared",
"attach_sponsor_documents": "Attach Verified Sponsor Documents",
"attach_documents_desc": "Upload sponsor papers, employment agreements, or work descriptions to review securely.",
"sponsor_reviews_star_ratings": "Sponsor Reviews & Star Ratings",
"reviews_posted_by_sponsors_desc": "Ratings can only be posted by verified sponsors who completed verified direct hiring.",
"aed": "AED",
"mo": "mo",
"hired_under_sponsorship_desc": "{name} is successfully marked as Hired under your sponsorship! This direct matching conforms exactly with Stage 4 of our UAE MOHRE zero-middlemen flow.",
"next_step_post_hire_review": "Next Step: Stage 5 Post-Hire Review",
"help_community_post_review": "Help the UAE community hire safely by posting an anonymous review describing {name}'s childcare, cooking, driving, or domestic skills.",
"back_to_worker_directory": "Back to Worker Directory",
"report_abuse_violation": "Report Vetting Abuse / Terms Violation",
"zero_tolerance_abuse_desc": "We maintain zero-tolerance for fake documentation, independent recruiters trading cash, or incorrect contact details.",
"additional_context_details": "Additional context details",
"provide_specifics_placeholder": "Provide detailed specifics of what happened...",
"submit_compliance_report": "Submit Compliance Report",
"submit_performance_review": "Submit a Verified Performance Review",
"feedback_helps_sponsors_desc": "Your feedback helps other sponsors make secure and direct hiring choices.",
"share_your_experience": "Share Your Experience",
"share_experience_placeholder": "Tell other sponsors about childcare skills, cleaning, cooking style, driving safety, etc...",
"post_trust_review_action": "Post Trust Review"
}

426
resources/js/lang/hi.json Normal file
View File

@ -0,0 +1,426 @@
{
"dashboard": "डैशबोर्ड",
"find_workers": "कामगार खोजें",
"shortlist": "शॉर्टलिस्ट",
"candidates": "उम्मीदवार",
"messages": "संदेश",
"charity_events": "दान कार्यक्रम",
"subscription": "सदस्यता",
"my_profile": "मेरी प्रोफाइल",
"search": "खोजें",
"profile": "प्रोफाइल",
"sub_warning": "कर्मचारियों से संपर्क करने के लिए आपको एक सक्रिय सदस्यता की आवश्यकता है।",
"subscribe_now": "अभी सदस्यता लें",
"employer_portal": "नियोक्ता पोर्टल",
"active_until": "तक सक्रिय",
"expired_renew": "समाप्त — अभी नवीनीकृत करें",
"overview": "अवलोकन",
"my_account": "मेरा खाता",
"profile_settings": "प्रोफ़ाइल सेटिंग्स",
"sign_out": "साइन आउट",
"employer_account": "नियोक्ता खाता",
"welcome_title": "मार्केटप्लेस में आपका स्वागत है!",
"welcome_desc": "आपका नियोक्ता प्रोफ़ाइल सत्यापित और सक्रिय है जिसमें 30 दिनों की प्रीमियम पहुँच है।",
"control_center": "प्रायोजक नियंत्रण केंद्र",
"dashboard_title": "प्रायोजक डैशबोर्ड - सत्यापित संयुक्त अरब अमीरात घरेलू कामगार",
"expired_pass_title": "आपका प्रायोजक सदस्यता पास समाप्त हो गया है!",
"expired_pass_desc": "सीधा संवाद, उम्मीदवार डोजियर और संदेश सेवा बंद हैं। भर्ती फिर से शुरू करने के लिए अब अपनी वार्षिक प्रायोजक सदस्यता का नवीनीकरण करें।",
"renew_sub": "सदस्यता का नवीनीकरण करें",
"expiring_pass_title": "आपका प्रीमियम प्रायोजक पास जल्द ही समाप्त होने वाला है!",
"expiring_pass_desc": "केवल {days} दिन बचे हैं। 500+ सत्यापित उम्मीदवारों तक संपर्क पहुंच खोने से बचने के लिए अभी नवीनीकरण करें।",
"renew_now": "अभी नवीनीकरण करें",
"sub_status": "सदस्यता की स्थिति",
"days_left": "दिन बचे हैं",
"welcome_back": "वापसी पर स्वागत है",
"welcome_desc_dash": "बिना किसी बिचौलिये के कमीशन के सीधे, एमओएचआरई-अनुरूप घरेलू कामगारों को काम पर रखें। ओसीआर पासपोर्ट जांच वाले उम्मीदवारों के हमारे अद्यतन डेटाबेस को ब्राउज़ करें।",
"browse_workers": "500+ सत्यापित कामगारों को ब्राउज़ करें",
"sponsor_pass_tier": "प्रायोजक पास श्रेणी",
"renews": "नवीनीकरण",
"manage_billing": "बिलिंग और चालान प्रबंधित करें",
"pending_job_offers": "लंबित नौकरी प्रस्ताव",
"direct_recruitment": "सीधे भर्ती प्रस्ताव",
"view_hiring": "भर्ती कार्यप्रवाह देखें",
"total_hired_workers": "कुल काम पर रखे गए कामगार",
"direct_contracts": "सीधे अनुबंध शुरू किए गए",
"track_active_staff": "सक्रिय कर्मचारियों को ट्रैक करें",
"shortlisted_candidates": "शॉर्टलिस्ट किए गए उम्मीदवार",
"bookmark_list": "साक्षात्कार के लिए बुकमार्क सूची",
"open_shortlist": "शॉर्टलिस्ट बुक खोलें",
"discover_insights": "इनसाइट्स और मार्केट आँकड़े खोजें",
"dubai_insights": "दुबई सामान्य बाज़ार इनसाइट्स",
"hired_dubai": "दुबई में ऐप का उपयोग करके काम पर रखा गया",
"cooking_care": "कुकिंग, केयर, ड्राइविंग",
"top_skills": "शीर्ष कौशल काम पर रखे गए",
"turnover_rate": "टर्नओवर दर",
"sponsor_activity": "आपकी प्रायोजक गतिविधि आँकड़े",
"workers_contacted": "कामगारों से संपर्क किया गया",
"secure_hires": "सुरक्षित नियुक्तियाँ",
"quick_actions": "त्वरित कार्रवाइयां",
"speed_up": "अपनी प्रायोजन प्रक्रिया को तेज़ करें।",
"find_nannies": "बेबी केयर और नैनी खोजें",
"browse_nannies": "प्रीमियम सत्यापित नैनी ब्राउज़ करें",
"whatsapp_support": "सीधा व्हाट्सएप समर्थन",
"chat_manager": "भर्ती प्रबंधक के साथ चैट करें",
"legal_platform": "100% कानूनी यूएई एजेंसी-मुक्त मंच",
"recommended_for_you": "आपके लिए अनुशंसित",
"browse_all": "सभी ब्राउज़ करें",
"view_profile": "प्रोफ़ाइल देखें",
"no_recommended": "वर्तमान में कोई कामगार अनुशंसित नहीं है। प्रोफ़ाइल विवरण अपडेट करें।",
"active_shortlist": "सक्रिय शॉर्टलिस्ट",
"view_book": "बुक देखें",
"category": "श्रेणी",
"availability": "उपलब्धता",
"open_profile": "प्रोफ़ाइल खोलें",
"shortlist_candidates_desc": "दस्तावेजों की साथ-साथ तुलना करने के लिए उम्मीदवारों को शॉर्टलिस्ट करें",
"recent_chats": "हालिया चैट",
"all_channels": "सभी चैनल",
"no_chats": "कोई हालिया चैट लॉग नहीं मिला। बातचीत शुरू करने के लिए कामगारों को खोजें।",
"charity_drives": "सामुदायिक चैरिटी ड्राइव",
"live_events": "लाइव इवेंट्स",
"charity_drive": "चैरिटी ड्राइव",
"provided_items": "प्रदान की गई वस्तुएं",
"event_date": "इवेंट की तारीख",
"open_maps": "गूगल मैप्स लोकेशन पिन खोलें",
"mohre_compliant": "यूएई तदबीर और एमओएचआरई अनुपालन",
"mohre_desc": "हमारी सीधी अनुबंध प्रणाली मानव संसाधन और अमीरात मंत्रालय के दिशानिर्देशों के साथ स्वचालित रूप से संरेखित होती है। पूरी तरह से कानूनी, शून्य एजेंट शुल्क, पूर्ण पारदर्शिता।",
"visit_mohre": "एमओएचआरई यूएई वेबसाइट पर जाएं",
"my_shortlist": "मेरी शॉर्टलिस्ट",
"candidates_saved": "आपके पास समीक्षा के लिए {count} उम्मीदवार सहेजे गए हैं",
"browse_more": "अधिक कामगारों को ब्राउज़ करें",
"verified": "सत्यापित",
"warning": "चेतावनी",
"platform_skills": "प्लेटफ़ॉर्म कौशल",
"languages_spoken": "बोली जाने वाली भाषाएं",
"quick_preview": "त्वरित पूर्वावलोकन",
"compare_candidate": "उम्मीदवार की तुलना करें",
"comparing_active": "तुलना सक्रिय ✓",
"message": "संदेश",
"shortlist_empty": "आपकी शॉर्टलिस्ट खाली है",
"shortlist_empty_desc": "उम्मीदवार प्रोफाइल का पता लगाएं और उन्हें अपनी सहेजी गई शॉर्टलिस्ट में जोड़ें।",
"find_workers_now": "अभी कामगार खोजें",
"comparing_workers": "कामगारों की तुलना करना",
"clear_all": "सभी साफ़ करें",
"remove_shortlist": "शॉर्टलिस्ट हटाएं",
"view_full_details": "पूर्ण विवरण देखें",
"no_bio_provided": "कोई बायो विवरण प्रदान नहीं किया गया।",
"expectations": "अपेक्षाएं",
"languages": "भाषाएं",
"availability_status_label": "उपलब्धता की स्थिति",
"job_preference": "नौकरी की प्राथमिकता",
"remove_from_shortlist": "शॉर्टलिस्ट से हटाएं",
"max_compare_alert": "आप अधिकतम 3 उम्मीदवारों की तुलना कर सकते हैं।",
"sponsor_pass_billing": "प्रायोजक पास और बिलिंग",
"subscription_billing_title": "सदस्यता बिलिंग और चालान - नियोक्ता पोर्टल",
"recurrent_billing_failed": "आपकी आवर्ती सदस्यता बिलिंग विफल हो गई है!",
"recurrent_billing_failed_desc": "अपर्याप्त राशि के कारण कार्ड नवीनीकरण विफल रहा। प्रोफ़ाइल तालाबंदी से बचने के लिए PayTabs का उपयोग करके पुनः प्रयास करें।",
"retry_payment_now": "अभी भुगतान का पुनः प्रयास करें",
"active_plan_pass": "सक्रिय योजना पास",
"renewing_auto_payment_on": "स्वतः भुगतान के माध्यम से नवीनीकरण की तिथि",
"simulate_billing_failure": "बिलिंग विफलता का अनुकरण करें",
"verified_sponsor_status": "सत्यापित प्रायोजक स्थिति",
"sponsor_pass_updated": "प्रायोजक पास सफलतापूर्वक अपडेट किया गया! PayTabs लेनदेन दर्ज किया गया।",
"available_subscription_tiers": "उपलब्ध सदस्यता श्रेणियां",
"available_subscription_tiers_desc": "कभी भी अपग्रेड या रद्द करें। सभी अनुबंध यूएई तदबीर एमओएचआरई दिशानिर्देशों के अनुरूप हैं।",
"most_popular_tier": "सबसे लोकप्रिय श्रेणी",
"current_active_tier": "वर्तमान सक्रिय श्रेणी ✓",
"select_plan_tier": "योजना श्रेणी चुनें",
"billing_payment_receipts": "बिलिंग भुगतान रसीदें",
"tax_compliant_invoices": "कर अनुपालन चालान",
"corporate_details": "कॉर्पोरेट विवरण",
"update_tax_invoicing": "कर चालान विकल्प अपडेट करें।",
"sponsor_email_address": "प्रायोजक ईमेल पता",
"billing_vat_id": "बिलिंग वैट रजिस्ट्री आईडी (वैकल्पिक)",
"save_billing_profile": "बिलिंग प्रोफ़ाइल सहेजें",
"paytabs_secured_checkout": "पे-टैब्स सुरक्षित चेकआउट",
"gateway_version": "गेटवे v4.0",
"order_description": "ऑर्डर विवरण",
"total_amount": "कुल राशि",
"cardholder_name": "कार्डधारक का नाम",
"card_number": "कार्ड नंबर",
"expiry_date": "समाप्ति तिथि (MM/YY)",
"security_code": "सुरक्षा कोड (CVV)",
"pci_dss_cryptography": "256-बिट PCI DSS क्रिप्टोग्राफी सुरक्षित",
"authorize_payment": "भुगतान अधिकृत करें",
"simulated_billing_failure_triggered": "कृत्रिम बिलिंग विफलता सक्रिय की गई!",
"simulated_billing_failure_desc": "एक स्वचालित प्रणाली चेतावनी अब भुगतान पुनः प्रयास विकल्पों का अनुरोध करेगी।",
"payment_approved": "पे-टैब्स द्वारा भुगतान स्वीकृत!",
"successfully_subscribed_desc": "सफलतापूर्वक {plan} की सदस्यता ली गई। प्रीमियम पहुंच सीमाएं तुरंत अपडेट हो गईं।",
"invoice_generated": "चालान {id} जनरेट किया गया",
"invoice_download_desc": "प्रत्यक्ष एमओएचआरई प्रायोजक रसीद पीडीएफ प्रारूप में सफलतापूर्वक डाउनलोड की गई।",
"corporate_billing_updated": "कॉर्पोरेट बिलिंग विवरण अपडेट किए गए।",
"invalid_card_format": "अमान्य कार्ड नंबर प्रारूप",
"candidates_pipeline": "उम्मीदवार",
"candidates_pipeline_desc": "अपनी कार्यबल भर्ती पाइपलाइन प्रबंधित करें",
"total_candidates": "कुल उम्मीदवार",
"reviewing": "समीक्षा की जा रही है",
"offer_sent": "प्रस्ताव भेजा गया",
"hired": "काम पर रखा गया",
"rejected": "अस्वीकृत",
"search_by_name": "नाम से खोजें...",
"candidate_header": "उम्मीदवार",
"selected_header": "चयनित",
"category_header": "श्रेणी",
"salary_header": "वेतन",
"status_header": "स्थिति",
"actions_header": "कार्रवाई",
"change_status_label": "स्थिति बदलें",
"no_candidates_found": "कोई उम्मीदवार नहीं मिला",
"showing_candidates": "कुल {total} उम्मीदवारों में से {start} से {end} दिखाए जा रहे हैं",
"account_settings": "खाता सेटिंग्स",
"profile_employer_portal": "प्रोफाइल - नियोक्ता पोर्टल",
"profile_updated_successfully": "प्रोफ़ाइल सफलतापूर्वक अपडेट की गई",
"profile_updated_successfully_desc": "घरेलू प्रायोजक प्राथमिकताओं और सत्यापित क्रेडेंशियल्स को सफलतापूर्वक सिंक किया गया।",
"profile_update_failed": "प्रोफ़ाइल अपडेट करने में विफल",
"check_form_fields": "कृपया फ़ॉर्म फ़ील्ड की जाँच करें।",
"tab_personal": "व्यक्तिगत",
"tab_security": "सुरक्षा और पासवर्ड",
"tab_billing": "बिलिंग और रसीदें",
"tab_notifications": "सूचना केंद्र",
"emirates_id_vetted": "अमीरात आईडी सत्यापित",
"direct_sponsor_portal": "सीधा प्रायोजक पोर्टल",
"personal_details_header": "व्यक्तिगत विवरण",
"personal_details_desc": "प्रायोजक बायो और क्रेडेंशियल्स प्रबंधित करें",
"full_sponsor_name": "प्रायोजक का पूरा नाम",
"invoicing_email": "चालान ईमेल",
"uae_mobile_contact": "यूएई मोबाइल संपर्क",
"sponsor_nationality": "प्रायोजक राष्ट्रीयता",
"select_nationality": "राष्ट्रीयता चुनें",
"uae_national": "यूएई नागरिक",
"expat_uk_europe": "प्रवासी (यूके / यूरोप)",
"expat_usa_canada": "प्रवासी (यूएसए / कनाडा)",
"expat_asia_gcc": "प्रवासी (एशिया / जीसीसी)",
"family_members_size": "परिवार के सदस्यों का आकार",
"select_family_size": "परिवार का आकार चुनें",
"family_1_2": "1-2 सदस्य",
"family_3_4": "3-4 सदस्य",
"family_5_plus": "5+ सदस्य",
"accommodation_residence": "आवास निवास",
"select_accommodation": "आवास चुनें",
"villa": "विला",
"penthouse": "अपार्टमेंट (पेंटहाउस)",
"apartment_1_3": "अपार्टमेंट (1-3 बेड)",
"city_district_area": "शहर जिला / क्षेत्र",
"emirates_id_verification_header": "अमीरात आईडी सत्यापन",
"emirates_id_verification_desc": "नियामक अनुपालन क्रेडेंशियल",
"emirates_id_verified_status": "अमीरात आईडी सत्यापित",
"mohre_guidelines": "एमओएचआरई दिशानिर्देशों के तहत जांचा गया",
"emirates_id_verified_desc": "आपकी अमीरात आईडी सफलतापूर्वक सत्यापित हो गई है। आपका खाता सीधी भर्ती के लिए सक्रिय है।",
"verification_pending_status": "सत्यापन लंबित ऑडिट",
"audit_queue": "ऑडिट कतार",
"verification_pending_desc": "आपके अमीरात आईडी दस्तावेज़ अपलोड वर्तमान में समीक्षा के अधीन हैं। ऑडिट आम तौर पर 24 घंटे के भीतर पूरे हो जाते हैं।",
"verification_required_status": "अमीरात आईडी सत्यापन आवश्यक",
"action_needed": "कार्रवाई आवश्यक",
"verification_required_desc": "अपनी पहचान सत्यापित करने और पूर्ण भर्ती सुविधाओं को सक्रिय करने के लिए कृपया अपने अमीरात आईडी के उच्च-रिज़ॉल्यूशन रंगीन स्कैन अपलोड करें।",
"emirates_id_front_side": "अमीरात आईडी (सामने का हिस्सा)",
"emirates_id_back_side": "अमीरात आईडी (पीछे का हिस्सा)",
"uploaded_credentials_scans": "अपलोड किए गए क्रेडेंशियल स्कैन",
"view_scan": "स्कैन देखें",
"security_password_header": "सुरक्षा और पासवर्ड",
"security_password_desc": "अपने प्रायोजक खाते को सुरक्षित रखें",
"current_password": "वर्तमान पासवर्ड",
"new_password": "नया पासवर्ड",
"confirm_new_password": "नए पासवर्ड की पुष्टि करें",
"current_plan": "वर्तमान योजना",
"active_status": "सक्रिय",
"next_payment": "अगला भुगतान",
"recent_transactions": "हाल के लेनदेन",
"date_header": "तारीख",
"description_header": "विवरण",
"amount_header": "रकम",
"receipt_header": "रसीद",
"notification_settings_hub": "अधिसूचना सेटिंग्स हब",
"notification_settings_desc": "चुनें कि आप सूचनाएं कैसे प्राप्त करना चाहते हैं",
"email_alerts": "ईमेल सूचनाएं",
"email_alerts_desc": "जांचे गए कामगारों की सिफारिशें और वीज़ा अपडेट प्राप्त करें।",
"sms_alerts": "एसएमएस त्वरित रसीदें",
"sms_alerts_desc": "साक्षात्कार कार्यक्रम के लिए एसएमएस सूचनाएं प्राप्त करें।",
"push_alerts": "पुश सूचनाएं",
"push_alerts_desc": "नए सीधे संदेशों के लिए डेस्कटॉप ध्वनि सूचनाएं प्राप्त करें।",
"changes_saved": "परिवर्तन सफलतापूर्वक सहेजे गए",
"emirates_id_reverification_notice": "कुछ अपडेट के लिए अमीरात आईडी पुनः सत्यापन की आवश्यकता हो सकती है।",
"update_settings": "सेटिंग्स अपडेट करें",
"charity_events_support_drives": "चैरिटी कार्यक्रम और सहायता अभियान",
"community_charity_events_sponsor_hub": "सामुदायिक चैरिटी कार्यक्रम - प्रायोजक केंद्र",
"community_charity_event_posted": "सामुदायिक चैरिटी कार्यक्रम पोस्ट किया गया!",
"community_charity_event_posted_desc": "दुबई में सभी कामगारों को त्वरित पुश अधिसूचना भेजी गई! कार्यक्रम की सुबह का अनुस्मारक सफलतापूर्वक निर्धारित किया गया।",
"dubai_community_support_drives": "दुबई सामुदायिक सहायता अभियान",
"free_medical_checks_title": "मुफ़्त चिकित्सा जांच, भोजन अभियान और सहायता सेवाएँ",
"free_medical_checks_desc": "एक सहायता कार्यक्रम का आयोजन कर रहे हैं? सीधे सामुदायिक अभियानों को साझा करें। प्लेटफ़ॉर्म स्वचालित रूप से कामगारों को एक त्वरित पॉप-अप अधिसूचना भेजेगा, जिसके बाद उपस्थिति को मजबूत रखने के लिए कार्यक्रम की सुबह अनुस्मारक भेजा जाएगा।",
"search_charity_events_placeholder": "चैरिटी कार्यक्रमों और अभियानों की खोज करें...",
"post_charity_event": "चैरिटी कार्यक्रम पोस्ट करें",
"broadcast_support_program_desc": "कामगार समुदाय के लिए एक सहायता कार्यक्रम, चिकित्सा शिविर या वितरण अभियान का प्रसारण करें।",
"charity_drive_metadata": "चैरिटी अभियान मेटाडेटा (दुबई सहायता)",
"event_time_placeholder": "जैसे 9:00 पूर्वाह्न - 4:00 अपराह्न",
"what_is_provided": "क्या प्रदान किया जा रहा है",
"provided_items_placeholder": "जैसे मुफ़्त चिकित्सा जांच, भोजन के डिब्बे, आपूर्ति",
"location_details_pin": "स्थान विवरण और पिन यूआरएल",
"location_details_placeholder": "जैसे अल कुओज़ कम्युनिटी सेंटर, दुबई",
"maps_pin_link_placeholder": "गूगल मैप्स पिन लिंक (जैसे https://maps.app.goo.gl/xyz)",
"title_label": "शीर्षक",
"title_placeholder": "जैसे अमीरात चैरिटी द्वारा मुफ्त दंत चिकित्सा जांच",
"event_desc_instructions": "कार्यक्रम का विवरण और निर्देश",
"event_desc_placeholder": "यहाँ चैरिटी कार्यक्रम का विवरण दर्ज करें...",
"publish_charity_event": "चैरिटी कार्यक्रम प्रकाशित करें",
"no_announcements_title": "कोई घोषणा नहीं",
"no_announcements_desc": "आपने अभी तक कोई घोषणा पोस्ट नहीं की है",
"community_charity_drive": "सामुदायिक चैरिटी अभियान",
"push_reminder_scheduled": "पुश और अनुस्मारक निर्धारित",
"provided_packages": "प्रदान किए गए पैकेज",
"event_timing": "कार्यक्रम का समय",
"event_location_address": "कार्यक्रम का स्थान पता",
"view_map_location_pin": "मानचित्र पर स्थान देखें",
"find_vetted_workers": "जांचे गए घरेलू कामगारों को खोजें",
"find_workers_platform": "कामगार खोजें - घरेलू कामगार मंच",
"no_middlemen_platform": "बिना बिचौलिए का मंच",
"find_verified_candidates": "सत्यापित उम्मीदवारों को खोजें",
"connect_vetted_workers_desc": "दुबई/यूएई के जांचे गए, पृष्ठभूमि सत्यापित घरेलू कामगारों से तुरंत जुड़ें।",
"search_by_name_skills_bio": "नाम, कौशल, बायो द्वारा खोजें (जैसे कुकिंग, चाइल्डकेयर, बागवानी, ड्राइविंग)...",
"default_match": "डिफ़ॉल्ट मिलान",
"salary_low_to_high": "वेतन: कम से अधिक",
"salary_high_to_low": "वेतन: अधिक से कम",
"rating_high_to_low": "रेटिंग: उच्च से कम",
"experience_level": "अनुभव स्तर",
"reset": "रीसेट",
"nationality": "राष्ट्रीयता",
"select_skills": "कौशल चुनें",
"select_languages": "भाषाएं चुनें",
"select_visa_status": "वीज़ा स्थिति चुनें",
"found_workers_matching": "खोज से मेल खाते {count} घरेलू कामगार मिले",
"direct_sponsoring_active": "MOHRE यूएई प्रत्यक्ष प्रायोजन सक्रिय",
"load_more_workers": "और कामगार लोड करें",
"no_candidates_matching": "आपके फ़िल्टर से कोई उम्मीदवार मेल नहीं खाता",
"adjust_filters_desc": "अपनी वेतन सीमा को समायोजित करने, अतिरिक्त भाषाएं जोड़ने, या राष्ट्रीयता प्राथमिकताओं को व्यापक बनाने का प्रयास करें।",
"reset_filters": "फ़िल्टर रीसेट करें",
"comparing_workers_count": "कामगारों की तुलना ({count} में से 3)",
"expected": "अपेक्षित",
"region": "क्षेत्र",
"visa_transfer": "वीज़ा स्थानांतरण",
"medical_status": "चिकित्सा स्थिति",
"passport_ocr": "पासपोर्ट ओसीआर",
"open_worker_profile": "कामगार प्रोफ़ाइल खोलें",
"attach_verified_sponsor_docs": "सत्यापित प्रायोजक दस्तावेज संलग्न करें",
"upload_sponsor_papers_desc": "सुरक्षित रूप से समीक्षा करने के लिए प्रायोजक कागजात, रोजगार समझौते, या कार्य विवरण अपलोड करें।",
"select_files_drag": "फ़ाइलें चुनें या यहाँ खींचें",
"max_file_size": "PDF, JPG, PNG (अधिकतम 5MB)",
"close": "बंद करें",
"chat_with_worker": "{name} के साथ चैट करें - संदेश",
"messages_hub": "संदेश हब",
"ssl_secure": "एसएसएल सुरक्षित",
"active_now": "अभी सक्रिय",
"whatsapp_bridge": "व्हाट्सएप ब्रिज",
"toggle_context_sidebar": "प्रसंग साइडबार टॉगल करें",
"today_realtime_chat": "आज • रीयलटाइम चैट लॉग",
"read": "पढ़ा गया",
"type_compliant_message": "एक अनुपालन सुरक्षित संदेश टाइप करें...",
"conversation_messages": "उम्मीदवार के संदेश",
"messages_employer_portal": "संदेश - प्रायोजक पोर्टल",
"search_conversations": "चैट खोजें...",
"new_conversation": "नई बातचीत",
"active_threads": "सक्रिय सूत्र",
"total_conversations": "कुल {count}",
"no_active_messages": "कोई सक्रिय संदेश नहीं",
"no_active_messages_desc": "जब आप कामगारों को संदेश भेजते हैं या साक्षात्कार निर्धारित करते हैं, तो आपकी बातचीत के सूत्र यहाँ दिखाई देंगे।",
"candidate_profile_detail": "उम्मीदवार प्रोफ़ाइल विवरण",
"back_to_find_workers": "कामगार खोज पर वापस जाएं",
"share_profile": "प्रोफ़ाइल साझा करें",
"report_worker": "कामगार की रिपोर्ट करें",
"sponsorship_details": "प्रायोजन विवरण",
"salary_expectations": "वेतन अपेक्षाएं",
"work_experience": "कार्य अनुभव",
"emirates_id_vetting": "अमीरात आईडी जांच",
"medical_health_test": "चिकित्सा स्वास्थ्य परीक्षण",
"passed_certified": "उत्तीर्ण प्रमाणित",
"professional_summary": "पेशेवर सारांश",
"verified_skills_competencies": "सत्यापित कौशल और क्षमताएं",
"verified_legal_documents": "सत्यापित कानूनी दस्तावेज़ (यूएई MOHRE सत्यापित)",
"passport_verified": "पासपोर्ट (सत्यापित)",
"click_zoom": "ज़ूम करने के लिए क्लिक करें",
"document_id": "दस्तावेज़ आईडी",
"issue": "जारी करने की तिथि",
"expiry": "समाप्ति तिथि",
"ocr_match": "ओसीआर मिलान",
"emirates_id_pdpl": "अमीरात आईडी (PDPL अनुपालन)",
"scan_purged": "स्कैन मिटा दिया गया",
"uae_pdpl_compliant": "यूएई PDPL अनुपालन",
"verification_type": "सत्यापन प्रकार",
"physical_scan_storage": "भौतिक स्कैन संग्रहण",
"permanently_purged": "स्थायी रूप से मिटा दिया गया",
"entry_visa_verified": "प्रवेश वीज़ा (सत्यापित)",
"visa_category": "वीज़ा श्रेणी",
"vetting_status": "जांच की स्थिति",
"transfer_required": "स्थानांतरण आवश्यक",
"needs_regularization": "नियमितीकरण की आवश्यकता है",
"clear_records": "स्पष्ट रिकॉर्ड",
"sponsor_reviews_ratings": "प्रायोजक समीक्षाएं और स्टार रेटिंग",
"ratings_policy_desc": "रेटिंग केवल उन सत्यापित प्रायोजकों द्वारा पोस्ट की जा सकती है जिन्होंने सत्यापित सीधी भर्ती पूरी कर ली है।",
"post_trust_review": "एक समीक्षा पोस्ट करें",
"similar_recommended_workers": "समान अनुशंसित कामगार",
"direct_sponsoring_finalized": "प्रत्यक्ष प्रायोजन अंतिम रूप दिया गया!",
"hired_stage4_desc": "{name} को आपके प्रायोजन के तहत सफलतापूर्वक काम पर रख लिया गया है! यह सीधी भर्ती हमारे यूएई MOHRE शून्य-बिचौलिया प्रवाह के चरण 4 के बिल्कुल अनुरूप है।",
"next_step_stage5": "अगला कदम: चरण 5 पोस्ट-हायर समीक्षा",
"post_hire_review_desc": "अन्य नियोक्ताओं को सुरक्षित रूप से भर्ती करने में मदद करने के लिए {name} की देखभाल, खाना पकाने, ड्राइविंग या घरेलू कौशल का वर्णन करने वाली एक गुमनाम समीक्षा पोस्ट करें।",
"leave_trust_review": "एक समीक्षा छोड़ें",
"back_to_directory": "कामगार निर्देशिका पर वापस जाएं",
"report_abuse_title": "जांच दुरुपयोग / शर्तों के उल्लंघन की रिपोर्ट करें",
"report_abuse_desc": "हम नकली दस्तावेज़ों, नकद लेनदेन करने वाले स्वतंत्र भर्तीकर्ताओं, या गलत संपर्क विवरणों के लिए शून्य-सहनशीलता बनाए रखते।",
"reason": "कारण",
"select_reason": "एक कारण चुनें...",
"reason_fees": "कामगार / एजेंट ने भर्ती कमीशन शुल्क का अनुरोध किया",
"reason_profile": "प्रोफ़ाइल विवरण / पासपोर्ट वास्तविक व्यक्ति से मेल नहीं खाता था",
"reason_contact": "अमान्य फ़ोन नंबर / संपर्क न हो पाना",
"reason_other": "अन्य अनुपालन उल्लंघन",
"additional_context": "अतिरिक्त विवरण",
"provide_specifics": "क्या हुआ था इसका विस्तृत विवरण प्रदान करें...",
"cancel": "रद्द करें",
"submit_report": "अनुपालन रिपोर्ट प्रस्तुत करें",
"submit_verified_review": "एक सत्यापित प्रदर्शन समीक्षा प्रस्तुत करें",
"review_help_desc": "आपकी प्रतिक्रिया अन्य प्रायोजकों को सुरक्षित और प्रत्यक्ष भर्ती विकल्प चुनने में मदद करती है।",
"star_rating": "स्टार रेटिंग",
"share_experience": "अपना अनुभव साझा करें",
"review_textarea_placeholder": "अन्य प्रायोजकों को बाल देखभाल कौशल, सफाई, खाना पकाने की शैली, ड्राइविंग सुरक्षा आदि के बारे में बताएं...",
"post_trust_review_btn": "समीक्षा पोस्ट करें",
"start_direct_chat": "सीधी बातचीत शुरू करें",
"mark_hired": "काम पर रखें",
"selected": "चयनित",
"total": "कुल",
"candidate_messages": "उम्मीदवार के संदेश",
"search_conversations_placeholder": "चैट खोजें...",
"total_count": "कुल {count}",
"chat_with": "चैट करें",
"today_realtime_chat_logs": "आज • रीयलटाइम चैट लॉग",
"just_now": "अभी-अभी",
"direct_push_sent": "प्रत्यक्ष मोबाइल पुश सूचना भेजी गई!",
"popped_up_instantly_desc": "{name} के मोबाइल डिवाइस पर तुरंत दिखाई दी।",
"auto_reply_text": "आपकी प्रतिक्रिया के लिए धन्यवाद! मैंने आपके प्रस्ताव की समीक्षा की है और मैं हमारे वीडियो साक्षात्कार की प्रतीक्षा कर रहा हूँ।",
"new_message_from": "{name} से नया संदेश!",
"document_attached": "दस्तावेज़ सफलतापूर्वक संलग्न किया गया!",
"document_attached_msg": "दस्तावेज़ संलग्न",
"today": "आज",
"chip_interview": "क्या आप आज वीडियो साक्षात्कार के लिए उपलब्ध हैं?",
"chip_salary": "आपका अंतिम अपेक्षित वेतन क्या है?",
"chip_visa": "क्या आप अपना वीज़ा तुरंत स्थानांतरित कर सकते हैं?",
"type_message_placeholder": "एक अनुपालन सुरक्षित संदेश टाइप करें...",
"compliance_profile": "अनुपालन प्रोफ़ाइल",
"transferable": "स्थानांतरणीय",
"cleared": "स्पष्ट / स्वीकृत",
"attach_sponsor_documents": "सत्यापित प्रायोजक दस्तावेज संलग्न करें",
"attach_documents_desc": "सुरक्षित रूप से समीक्षा करने के लिए प्रायोजक कागजात, रोजगार समझौते, या कार्य विवरण अपलोड करें।",
"sponsor_reviews_star_ratings": "प्रायोजक समीक्षाएं और स्टार रेटिंग",
"reviews_posted_by_sponsors_desc": "रेटिंग केवल उन सत्यापित प्रायोजकों द्वारा पोस्ट की जा सकती है जिन्होंने सत्यापित सीधी भर्ती पूरी कर ली है।",
"aed": "AED",
"mo": "माह",
"hired_under_sponsorship_desc": "{name} को आपके प्रायोजन के तहत सफलतापूर्वक काम पर रख लिया गया है! यह सीधी भर्ती हमारे यूएई MOHRE शून्य-बिचौलिया प्रवाह के चरण 4 के बिल्कुल अनुरूप है।",
"next_step_post_hire_review": "अगला कदम: चरण 5 पोस्ट-हायर समीक्षा",
"help_community_post_review": "अन्य नियोक्ताओं को सुरक्षित रूप से भर्ती करने में मदद करने के लिए {name} की देखभाल, खाना पकाने, ड्राइविंग या घरेलू कौशल का वर्णन करने वाली एक गुमनाम समीक्षा पोस्ट करें।",
"back_to_worker_directory": "कामगार निर्देशिका पर वापस जाएं",
"report_abuse_violation": "जांच दुरुपयोग / शर्तों के उल्लंघन की रिपोर्ट करें",
"zero_tolerance_abuse_desc": "हम नकली दस्तावेज़ों, नकद लेनदेन करने वाले स्वतंत्र भर्तीकर्ताओं, या गलत संपर्क विवरणों के लिए शून्य-सहनशीलता बनाए रखते हैं।",
"additional_context_details": "अतिरिक्त विवरण",
"provide_specifics_placeholder": "क्या हुआ था इसका विस्तृत विवरण प्रदान करें...",
"submit_compliance_report": "अनुपालन रिपोर्ट प्रस्तुत करें",
"submit_performance_review": "एक सत्यापित प्रदर्शन समीक्षा प्रस्तुत करें",
"feedback_helps_sponsors_desc": "आपकी प्रतिक्रिया अन्य प्रायोजकों को सुरक्षित और प्रत्यक्ष भर्ती विकल्प चुनने में मदद करती है।",
"share_your_experience": "अपना अनुभव साझा करें",
"share_experience_placeholder": "अन्य प्रायोजकों को बाल देखभाल कौशल, सफाई, खाना पकाने की शैली, ड्राइविंग सुरक्षा आदि के बारे में बताएं...",
"post_trust_review_action": "समीक्षा पोस्ट करें"
}

426
resources/js/lang/sw.json Normal file
View File

@ -0,0 +1,426 @@
{
"dashboard": "Dashibodi",
"find_workers": "Tafuta Wafanyakazi",
"shortlist": "Orodha fupi",
"candidates": "Watahiniwa",
"messages": "Ujumbe",
"charity_events": "Matukio ya Misaada",
"subscription": "Usajili",
"my_profile": "Wasifu Wangu",
"search": "Tafuta",
"profile": "Wasifu",
"sub_warning": "Unahitaji usajili unaofanya kazi ili kuwasiliana na wafanyakazi.",
"subscribe_now": "Jiandikishe sasa",
"employer_portal": "Tovuti ya Waajiri",
"active_until": "Inatumika hadi",
"expired_renew": "Imeisha muda wake — Jisajili upya sasa",
"overview": "Mapitio",
"my_account": "Akaunti Yangu",
"profile_settings": "Mipangilio ya Wasifu",
"sign_out": "Ondoka",
"employer_account": "Akaunti ya Mwajiri",
"welcome_title": "Karibu kwenye Soko!",
"welcome_desc": "Wasifu wako wa mwajiri umethibitishwa na unafanya kazi ukiwa na siku 30 za Ufikiaji wa Kulipia.",
"control_center": "Kituo cha Kudhibiti Mdhamini",
"dashboard_title": "Dashibodi ya Mdhamini - Wafanyakazi wa Nyumbani Waliothibitishwa wa UAE",
"expired_pass_title": "Pasi Yako ya Usajili wa Mdhamini Imeisha Muda Wake!",
"expired_pass_desc": "Mawasiliano ya moja kwa moja, wasifu wa watahiniwa, na ujumbe vimefungwa. Jisajili upya sasa ili uendelee na uajiri.",
"renew_sub": "Jisajili Upya",
"expiring_pass_title": "Pasi Yako ya Mdhamini wa Premium inakaribia kuisha muda wake!",
"expiring_pass_desc": "Zimesalia siku {days} pekee. Jisajili upya sasa ili kuepuka kupoteza ufikiaji wa mawasiliano kwa watahiniwa 500+ waliothibitishwa.",
"renew_now": "Jisajili Sasa",
"sub_status": "Hali ya Usajili",
"days_left": "Siku Zilizosalia",
"welcome_back": "Karibu Tena",
"welcome_desc_dash": "Ajiri wafanyakazi wa nyumbani wa moja kwa moja, wanaotii MOHRE kama vile baby nannies na maid tanpa kumi-kumi komisi. Vinjari hifadhidata yetu iliyosasishwa ya watahiniwa walio na ukaguzi wa pasipoti wa OCR.",
"browse_workers": "Vinjari Wafanyakazi 500+ Waliothibitishwa",
"sponsor_pass_tier": "Daraja la Pasi ya Mdhamini",
"renews": "Inasasishwa",
"manage_billing": "Dhibiti malipo na ankara",
"pending_job_offers": "Ofa za Kazi Zinazosubiri",
"direct_recruitment": "Mapendekezo ya uajiri wa moja kwa moja",
"view_hiring": "Angalia mtiririko wa uajiri",
"total_hired_workers": "Jumla ya Wafanyakazi Walioajiriwa",
"direct_contracts": "Mikataba ya moja kwa moja iliyoanzishwa",
"track_active_staff": "Fuatilia wafanyakazi wanaofanya kazi",
"shortlisted_candidates": "Watahiniwa Kwenye Orodha Fupi",
"bookmark_list": "Hifadhi orodha kwa ajili ya mahojiano",
"open_shortlist": "Fungua kitabu cha orodha fupi",
"discover_insights": "Gundua Maarifa na Takwimu za Soko",
"dubai_insights": "Maarifa ya Jumla ya Soko la Dubai",
"hired_dubai": "Walioajiriwa kwa kutumia programu huko Dubai",
"cooking_care": "Kupika, Matunzo, Kuendesha Gari",
"top_skills": "Ujuzi Unaoongoza Kuajiriwa",
"turnover_rate": "Kiwango cha mabadiliko ya wafanyakazi",
"sponsor_activity": "Takwimu Zako za Shughuli za Mdhamini",
"workers_contacted": "Wafanyakazi Waliowasiliana Nao",
"secure_hires": "Uajiri Salama",
"quick_actions": "Hatua za Haraka",
"speed_up": "Harikisha mchakato wako wa udhamini.",
"find_nannies": "Tafuta Wanaotunza Watoto na Yaya",
"browse_nannies": "Vinjari yaya waliothibitishwa wa kiwango cha juu",
"whatsapp_support": "Msaada wa Moja kwa Moja wa WhatsApp",
"chat_manager": "Ongea na meneja wa uajiri",
"legal_platform": "Jukwaa la Kisheria la 100% la UAE Bila Wakala",
"recommended_for_you": "Imependekezwa kwa Ajili Yako",
"browse_all": "Vinjari zote",
"view_profile": "Angalia Wasifu",
"no_recommended": "Hakuna wafanyakazi wanaopendekezwa kwa sasa. Sasisha maelezo ya wasifu.",
"active_shortlist": "Orodha Fupi Inayofanya Kazi",
"view_book": "Angalia kitabu",
"category": "Kundi",
"availability": "Upatikanaji",
"open_profile": "Fungua Wasifu",
"shortlist_candidates_desc": "Weka watahiniwa kwenye orodha fupi ili kulinganisha hati zao bega kwa bega",
"recent_chats": "Mazungumzo ya Hivi Karibuni",
"all_channels": "Njia zote",
"no_chats": "Hakuna kumbukumbu za mazungumzo ya hivi karibuni zilizopatikana. Tafuta wafanyakazi ili kuanza mazungumzo.",
"charity_drives": "Michango ya Misaada ya Jamii",
"live_events": "Matukio ya Moja kwa Moja",
"charity_drive": "Mchango wa Msaada",
"provided_items": "Vitu Vilivyotolewa",
"event_date": "Tarehe ya Tukio",
"open_maps": "Fungua Pin ya Mahali ya Google Maps",
"mohre_compliant": "Kuzingatia Sheria za UAE Tadbeer na MOHRE",
"mohre_desc": "Mfumo wetu wa mkataba wa moja kwa moja unajipanga kiotomatiki na miongozo ya Wizara ya Rasilimali Watu na Uraia. Ni halali kabisa, hakuna ada ya wakala, uwazi kamili.",
"visit_mohre": "Tembelea tovuti ya MOHRE UAE",
"my_shortlist": "Orodha Fupi Yangu",
"candidates_saved": "Una watahiniwa {count} waliotengwa kwa ajili ya mapitio",
"browse_more": "Vinjari wafanyakazi wengi zaidi",
"verified": "Imethibitishwa",
"warning": "Onyo",
"platform_skills": "Ujuzi wa Jukwaa",
"languages_spoken": "Lugha Zinazozungumzwa",
"quick_preview": "Hakiki ya Haraka",
"compare_candidate": "Linganisha Mtahiniwa",
"comparing_active": "Inalinganisha ✓",
"message": "Tuma Ujumbe",
"shortlist_empty": "Orodha yako fupi haina kitu",
"shortlist_empty_desc": "Gundua wasifu wa watahiniwa na uwaongeze kwenye orodha yako fupi iliyohifadhiwa.",
"find_workers_now": "Tafuta Wafanyakazi Sasa",
"comparing_workers": "Kulinganisha Wafanyakazi",
"clear_all": "Futa yote",
"remove_shortlist": "Ondoa Kwenye Orodha Fupi",
"view_full_details": "Angalia Maelezo Kamili",
"no_bio_provided": "Hakuna wasifu uliotolewa.",
"expectations": "Matarajio",
"languages": "Lugha",
"availability_status_label": "Hali ya Upatikanaji",
"job_preference": "Upendeleo wa Kazi",
"remove_from_shortlist": "Ondoa kwenye orodha fupi",
"max_compare_alert": "Unaweza kulinganisha kiwango cha juu cha watahiniwa 3.",
"sponsor_pass_billing": "Pasi ya Mdhamini & Ankara",
"subscription_billing_title": "Malipo na Ankara za Usajili - Tovuti ya Mwajiri",
"recurrent_billing_failed": "Malipo yako ya kujirudia ya usajili YAMEFELI!",
"recurrent_billing_failed_desc": "Urejesho wa kadi ulifeli kwa sababu ya ukosefu vya fedha. Jaribu tena ukitumia PayTabs ili kuepuka kufungiwa wasifu.",
"retry_payment_now": "Jaribu Kulipa Sasa",
"active_plan_pass": "Pasi ya Mpango Inayotumika",
"renewing_auto_payment_on": "Inasasishwa kupitia malipo ya kiotomatiki mnamo",
"simulate_billing_failure": "Simulate Kufeli kwa Malipo",
"verified_sponsor_status": "Hali ya Mdhamini Aliothibitishwa",
"sponsor_pass_updated": "Pasi ya Mdhamini imesasishwa kikamilifu! Muamala vya PayTabs umerekodiwa.",
"available_subscription_tiers": "Viwango vya Usajili Vinavyopatikana",
"available_subscription_tiers_desc": "Boresha au ghairi wakati wowote. Mikataba yote inafuata miongozo ya UAE Tadbeer MOHRE.",
"most_popular_tier": "Kiwango Maarufu Zaidi",
"current_active_tier": "Kiwango Ambacho Kinafanya Kazi Sasa ✓",
"select_plan_tier": "Chagua Kiwango cha Mpango",
"billing_payment_receipts": "Risiti za Malipo",
"tax_compliant_invoices": "Ankara Zinazofuata Sheria ya Kodi",
"corporate_details": "Maelezo ya Kampuni",
"update_tax_invoicing": "Sasisha maelezo ya ankara ya kodi.",
"sponsor_email_address": "Barua Pepe ya Mdhamini",
"billing_vat_id": "Nambari ya Usajili wa VAT (Hiari)",
"save_billing_profile": "Hifadhi Wasifu wa Malipo",
"paytabs_secured_checkout": "Secured Checkout ya PayTabs",
"gateway_version": "Lango la Malipo v4.0",
"order_description": "Maelezo ya Agizo",
"total_amount": "Jumla ya Kiasi",
"cardholder_name": "Jina la Mwenye Kadi",
"card_number": "Nambari ya Kadi",
"expiry_date": "Tarehe ya Mwisho (MM/YY)",
"security_code": "Nambari ya Siri ya CVV",
"pci_dss_cryptography": "Ulinzi wa Siri wa PCI DSS Bit-256",
"authorize_payment": "Idhinisha Malipo",
"simulated_billing_failure_triggered": "Kufeli kwa malipo ya majaribio kumeanzishwa!",
"simulated_billing_failure_desc": "Onyo la mfumo vya kiotomatiki sasa litaomba chaguzi za kujaribu tena malipo.",
"payment_approved": "Malipo Yameidhinishwa na PayTabs!",
"successfully_subscribed_desc": "Imefanikiwa kujiandikisha kwenye {plan}. Mipaka ya ufikiaji wa kulipia imesasishwa papo hapo.",
"invoice_generated": "Ankara {id} Imeundwa",
"invoice_download_desc": "Risiti ya moja kwa moja ya Mdhamini wa MOHRE imepakuliwa katika muundo vya PDF kikamilifu.",
"corporate_billing_updated": "Maelezo ya malipo ya kampuni yamesasishwa.",
"invalid_card_format": "Nambari ya kadi sio sahihi",
"candidates_pipeline": "Watahiniwa",
"candidates_pipeline_desc": "Dhibiti mfumo wako wa uajiri wa wafanyakazi",
"total_candidates": "Jumla ya Watahiniwa",
"reviewing": "Kuhakiki",
"offer_sent": "Ofa Imetumwa",
"hired": "Ameajiriwa",
"rejected": "Imekataliwa",
"search_by_name": "Tafuta kwa jina...",
"candidate_header": "Mtahiniwa",
"selected_header": "Amechaguliwa",
"category_header": "Kundi",
"salary_header": "Mshahara",
"status_header": "Hali",
"actions_header": "Vitendo",
"change_status_label": "Badilisha Hali",
"no_candidates_found": "Hakuna watahiniwa waliopatikana",
"showing_candidates": "Inaonyesha watahiniwa {start} hadi {end} kati ya {total}",
"account_settings": "Mipangilio ya Akaunti",
"profile_employer_portal": "Wasifu - Tovuti ya Mwajiri",
"profile_updated_successfully": "Wasifu umesasishwa kikamilifu",
"profile_updated_successfully_desc": "Vipendeleo vya mdhamini wa nyumbani vimesasishwa kwa ufanisi.",
"profile_update_failed": "Imeshindikana kusasisha wasifu",
"check_form_fields": "Tafadhali angalia sehemu za fomu.",
"tab_personal": "Binafsi",
"tab_security": "Usalama & Nywila",
"tab_billing": "Malipo & Risiti",
"tab_notifications": "Kituo cha Arifa",
"emirates_id_vetted": "Emirates ID Imethibitishwa",
"direct_sponsor_portal": "Tovuti ya Moja kwa Moja ya Mdhamini",
"personal_details_header": "Maelezo binafsi",
"personal_details_desc": "Dhibiti wasifu na hati za mdhamini",
"full_sponsor_name": "Jina Kamili la Mdhamini",
"invoicing_email": "Barua Pepe ya Ankara",
"uae_mobile_contact": "Nambari ya Simu ya UAE",
"sponsor_nationality": "Uraia wa Mdhamini",
"select_nationality": "Chagua Uraia",
"uae_national": "Mwananchi wa UAE",
"expat_uk_europe": "Mgeni (UK / Ulaya)",
"expat_usa_canada": "Mgeni (USA / Kanada)",
"expat_asia_gcc": "Mgeni (Asia / GCC)",
"family_members_size": "Idadi ya Wanafamilia",
"select_family_size": "Chagua Idadi",
"family_1_2": "Wanafamilia 1-2",
"family_3_4": "Wanafamilia 3-4",
"family_5_plus": "Wanafamilia 5+",
"accommodation_residence": "Aina ya Makazi",
"select_accommodation": "Chagua Makazi",
"villa": "Jumba la Kifahari (Villa)",
"penthouse": "Penthouse",
"apartment_1_3": "Ghorofa (Vyumba 1-3)",
"city_district_area": "Eneo la Mji / Wilaya",
"emirates_id_verification_header": "Uthibitisho wa Emirates ID",
"emirates_id_verification_desc": "Nyaraka za kisheria na kufuata kanuni",
"emirates_id_verified_status": "Emirates ID Imethibitishwa",
"mohre_guidelines": "Imekaguliwa chini ya Miongozo ya MOHRE",
"emirates_id_verified_desc": "Emirates ID yako imethibitishwa kikamilifu. Akaunti yako inafanya kazi kwa uajiri vya moja kwa moja.",
"verification_pending_status": "Uhakiki Unasubiri Ukaguzi",
"audit_queue": "Msururu wa Ukaguzi",
"verification_pending_desc": "Nyaraka zako za Emirates ID zilizopakiwa kwa sasa zinakaguliwa. Kawaida inachukua chini ya saa 24.",
"verification_required_status": "Uthibitisho wa Emirates ID Unahitajika",
"action_needed": "Hatua Inahitajika",
"verification_required_desc": "Tafadhali pakia picha za rangi za Emirates ID yako ili kudhibitisha utambulisho wako.",
"emirates_id_front_side": "Emirates ID (Upande wa Mbele)",
"emirates_id_back_side": "Emirates ID (Upande wa Nyuma)",
"uploaded_credentials_scans": "Nyaraka Zilizopakiwa",
"view_scan": "Angalia Picha",
"security_password_header": "Usalama & Nywila",
"security_password_desc": "Weka akaunti yako ya udhamini salama",
"current_password": "Nywila ya Sasa",
"new_password": "Nywila Mpya",
"confirm_new_password": "Thibitisha Nywila Mpya",
"current_plan": "Mpango wa Sasa",
"active_status": "Inatumika",
"next_payment": "Malipo Yanayofuata",
"recent_transactions": "Miamala ya Hivi Karibuni",
"date_header": "Tarehe",
"description_header": "Maelezo",
"amount_header": "Kiasi",
"receipt_header": "Risiti",
"notification_settings_hub": "Kituo cha Mipangilio ya Arifa",
"notification_settings_desc": "Chagua jinsi unavyotaka kupokea arifa",
"email_alerts": "Arifa za Barua Pepe",
"email_alerts_desc": "Pokea mapendekezo ya wafanyakazi na sasisho za visa.",
"sms_alerts": "Risiti za Papo hapo za SMS",
"sms_alerts_desc": "Pokea arifa za SMS za ratiba ya mahojiano.",
"push_alerts": "Arifa za Skrini",
"push_alerts_desc": "Pokea arifa za sauti kwa ujumbe mpya wa moja kwa moja.",
"changes_saved": "Mabadiliko yamehifadhiwa",
"emirates_id_reverification_notice": "Baadhi ya sasisho zinaweza kuhitaji uthibitisho mpya vya Emirates ID.",
"update_settings": "Sasisha Mipangilio",
"charity_events_support_drives": "Matukio ya Misaada & Kampeni za Usaidizi",
"community_charity_events_sponsor_hub": "Matukio ya Misaada ya Jamii - Kituo cha Mdhamini",
"community_charity_event_posted": "TUKIO LA MISAADA LA JAMII LIMEPOSITIWA!",
"community_charity_event_posted_desc": "Arifa ya papo hapo imetumwa kwa wafanyakazi wote huko Dubai! Kikumbusho cha asubuhi ya tukio kimeratibiwa kwa mafanikio.",
"dubai_community_support_drives": "Kampeni za Usaidizi za Jamii ya Dubai",
"free_medical_checks_title": "Uchunguzi wa Matibabu Bila Malipo, Kampeni za Chakula na Huduma za Usaidizi",
"free_medical_checks_desc": "Unaratibu mpango wa usaidizi? Shiriki kampeni za jamii moja kwa moja. Jukwaa litatuma arifa ya papo hapo kwa wafanyakazi, ikifuatiwa na kikumbusho cha asubuhi ya tukio ili kudumisha mahudhurio mazuri.",
"search_charity_events_placeholder": "Tafuta matukio ya misaada na kampeni...",
"post_charity_event": "Positi Tukio la Misaada",
"broadcast_support_program_desc": "Tangaza mpango wa usaidizi, kambi ya matibabu, au kampeni ya ugawaji kwa jamii ya wafanyakazi.",
"charity_drive_metadata": "Metadata ya Kampeni ya Misaada (Usaidizi wa Dubai)",
"event_time_placeholder": "m.f. 9:00 Asubuhi - 4:00 Jioni",
"what_is_provided": "Kile Kinachotolewa",
"provided_items_placeholder": "m.f. Uchunguzi wa Matibabu wa Bure, Masanduku ya Chakula, Vifaa",
"location_details_pin": "Maelezo ya Eneo & URL ya Ramani",
"location_details_placeholder": "m.f. Kituo cha Jamii cha Al Quoz, Dubai",
"maps_pin_link_placeholder": "Kiungo cha Ramani ya Google Maps (m.f. https://maps.app.goo.gl/xyz)",
"title_label": "Kichwa",
"title_placeholder": "m.f. Uchunguzi wa meno wa bure na Shirika la Misaada la Emirates",
"event_desc_instructions": "Maelezo ya Tukio & Maagizo",
"event_desc_placeholder": "Weka maelezo ya tukio la misaada hapa...",
"publish_charity_event": "Chapisha Tukio la Misaada",
"no_announcements_title": "Hakuna Tangazo",
"no_announcements_desc": "Bado haujaposti tangazo lolote",
"community_charity_drive": "KAMPENI YA MISAADA YA JAMII",
"push_reminder_scheduled": "Arifa & Kikumbusho Kimeratibiwa",
"provided_packages": "Vifurushi Vilivyotolewa",
"event_timing": "Muda wa Tukio",
"event_location_address": "Anwani ya Eneo la Tukio",
"view_map_location_pin": "Angalia Mahali kwenye Ramani",
"find_vetted_workers": "Pata Wafanyakazi wa Nyumbani Waliokaguliwa",
"find_workers_platform": "Tafuta Wafanyakazi - Jukwaa la Wafanyakazi wa Nyumbani",
"no_middlemen_platform": "Jukwaa Bila Madalali",
"find_verified_candidates": "Pata Watahiniwa Waliothibitishwa",
"connect_vetted_workers_desc": "Ungana papo hapo na wafanyakazi wa nyumbani waliokaguliwa na kuthibitishwa nchini UAE.",
"search_by_name_skills_bio": "Tafuta kwa jina, ujuzi, wasifu (k.v. Kupika, Kulelea Watoto, Bustani, Udereva)...",
"default_match": "Mechi Chaguomsingi",
"salary_low_to_high": "Mshahara: Chini hadi Juu",
"salary_high_to_low": "Mshahara: Juu hadi Chini",
"rating_high_to_low": "Ukadiriaji: Juu hadi Chini",
"experience_level": "Kiwango cha Uzoefu",
"reset": "Weka upya",
"nationality": "Uraia",
"select_skills": "Chagua Ujuzi",
"select_languages": "Chagua Lugha",
"select_visa_status": "Chagua Hali ya Visa",
"found_workers_matching": "Imepata wafanyakazi wa nyumbani {count} wanaolingana na utafutaji",
"direct_sponsoring_active": "Ufadhili wa Moja kwa Moja wa MOHRE UAE Umerejeshwa",
"load_more_workers": "Pakia Wafanyakazi Zaidi",
"no_candidates_matching": "Hakuna watahiniwa wanaolingana na vichujio vyako",
"adjust_filters_desc": "Jaribu kurekebisha kikomo chako cha mshahara, kuongeza lugha za ziada, au kupanua mapendeleo ya uraia.",
"reset_filters": "Weka upya Vichujio",
"comparing_workers_count": "Kulinganisha Wafanyakazi ({count} kati ya 3)",
"expected": "Inayotarajiwa",
"region": "Mkoa",
"visa_transfer": "Uhamisho wa Visa",
"medical_status": "Hali ya Afya",
"passport_ocr": "OCR ya Pasipoti",
"open_worker_profile": "Fungua Wasifu wa Mfanyakazi",
"attach_verified_sponsor_docs": "Ambatanisha Nyaraka Zilizothibitishwa za Mfadhili",
"upload_sponsor_papers_desc": "Pakia karatasi za mfadhili, makubaliano ya ajira, au maelezo ya kazi ili kukagua kwa usalama.",
"select_files_drag": "Chagua faili au buruta hapa",
"max_file_size": "PDF, JPG, PNG (Max 5MB)",
"close": "Funga",
"chat_with_worker": "Piga gumzo na {name} - Ujumbe",
"messages_hub": "Kituo cha Ujumbe",
"ssl_secure": "SSL SALAMA",
"active_now": "Yuko Mtandaoni Sasa",
"whatsapp_bridge": "Daraja la WhatsApp",
"toggle_context_sidebar": "Togle Upau wa Kando wa Wasifu",
"today_realtime_chat": "Leo • Kumbukumbu za Gumzo la Wakati Halisi",
"read": "Imesomwa",
"type_compliant_message": "Andika ujumbe unaotii usalama...",
"conversation_messages": "Ujumbe wa Watahiniwa",
"messages_employer_portal": "Ujumbe - Tovuti ya Mfadhili",
"search_conversations": "Tafuta mazungumzo...",
"new_conversation": "Mazungumzo Mapya",
"active_threads": "Nyuzi Amilifu",
"total_conversations": "Jumla ya {count}",
"no_active_messages": "Hakuna ujumbe unaotumika",
"no_active_messages_desc": "Unapotuma ujumbe kwa wafanyakazi au kupanga mahojiano, mazungumzo yako yataonekana hapa.",
"candidate_profile_detail": "Maelezo ya Wasifu wa Mtahiniwa",
"back_to_find_workers": "RUDI KWENYE TAFUTA WAFANYAKAZI",
"share_profile": "Shiriki Wasifu",
"report_worker": "Ripoti Mfanyakazi",
"sponsorship_details": "Maelezo ya Ufadhili",
"salary_expectations": "Matarajio ya Mshahara",
"work_experience": "Uzoefu wa Kazi",
"emirates_id_vetting": "Uhakiki wa Emirates ID",
"medical_health_test": "Kipimo cha Afya ya Matibabu",
"passed_certified": "PASSED CERTIFIED",
"professional_summary": "Muhtasari wa Kitaalamu",
"verified_skills_competencies": "Ujuzi na Ufahamu Uliothibitishwa",
"verified_legal_documents": "Nyaraka za Kisheria Zilizothibitishwa (MOHRE UAE)",
"passport_verified": "Pasipoti (Imethibitishwa)",
"click_zoom": "Bofya ili kukuza",
"document_id": "Kitambulisho cha Hati",
"issue": "Imetolewa",
"expiry": "Muda wake unaisha",
"ocr_match": "Kulingana kwa OCR",
"emirates_id_pdpl": "Emirates ID (Inatii PDPL)",
"scan_purged": "Scan Imefutwa",
"uae_pdpl_compliant": "Inatii sheria ya PDPL ya UAE",
"verification_type": "Aina ya Uthibitishaji",
"physical_scan_storage": "Uhifadhi wa Scan ya Kimwili",
"permanently_purged": "Imefutwa Kabisa",
"entry_visa_verified": "Visa ya Kuingia (Imethibitishwa)",
"visa_category": "Aina ya Visa",
"vetting_status": "Hali ya Uhakiki",
"transfer_required": "Uhamisho Unahitajika",
"needs_regularization": "Inahitaji Udhibiti",
"clear_records": "Nyaraka Ziko Wazi",
"sponsor_reviews_ratings": "Mapitio ya Wafadhili & Ukadiriaji wa Nyota",
"ratings_policy_desc": "Ukadiriaji unaweza tu kuchapishwa na wafadhili waliothibitishwa ambao walikamilisha ajira ya moja kwa moja iliyothibitishwa.",
"post_trust_review": "Chapisha Mapitio ya Uaminifu",
"similar_recommended_workers": "Wafanyakazi Sawa Wanaopendekezwa",
"direct_sponsoring_finalized": "Ufadhili wa Moja kwa Moja Umekamilika!",
"hired_stage4_desc": "{name} amefaulu kuandikishwa kazi chini ya ufadhili wako! Ulinganifu huu wa moja kwa moja unalingana kikamilifu na Hatua ya 4 ya mtiririko wetu wa MOHRE UAE bila madalali.",
"next_step_stage5": "Hatua Inayofuata: Hatua ya 5 Mapitio ya Baada ya Kuajiri",
"post_hire_review_desc": "Saidia jamii ya UAE kuajiri kwa usalama kwa kuchapisha mapitio yasiyojulikana yanayoelezea ulezi wa watoto, kupika, kuendesha gari, au ujuzi wa nyumbani wa {name}.",
"leave_trust_review": "Acha Mapitio ya Uaminifu",
"back_to_directory": "Rudi kwenye Orodha ya Wafanyakazi",
"report_abuse_title": "Ripoti Unyanyasaji wa Uhakiki / Ukiukaji wa Masharti",
"report_abuse_desc": "Tunasimamia kutovumilia kabisa nyaraka za kughushi, waajiri wa kujitegemea wanaofanya biashara kwa pesa taslimu, au maelezo yasiyo sahihi ya mawasiliano.",
"reason": "Sababu",
"select_reason": "Chagua sababu...",
"reason_fees": "Mfanyakazi / wakala alihitaji ada ya tume ya kuajiri",
"reason_profile": "Maelezo ya wasifu / pasipoti hailingani na mtu halisi",
"reason_contact": "Nambari ya simu si sahihi / haipatikani",
"reason_other": "Ukiukaji mwingine wa kisheria",
"additional_context": "Maelezo ya ziada ya muktadha",
"provide_specifics": "Toa maelezo ya kina ya kile kilichotokea...",
"cancel": "Ghairi",
"submit_report": "Wasilisha Ripoti ya Utiifu",
"submit_verified_review": "Wasilisha Mapitio ya Utendaji Yaliyothibitishwa",
"review_help_desc": "Maoni yako yanasaidia wafadhili wengine kufanya maamuzi salama na ya moja kwa moja ya kuajiri.",
"star_rating": "Ukadiriaji wa Nyota",
"share_experience": "Shiriki Uzoefu Wako",
"review_textarea_placeholder": "Waambie wafadhili wengine kuhusu ujuzi wa kulelea watoto, kusafisha, mtindo wa kupika, usalama wa kuendesha gari, n.k...",
"post_trust_review_btn": "Chapisha Mapitio ya Uaminifu",
"start_direct_chat": "Anza Gumzo la Moja kwa Moja",
"mark_hired": "Weka Alama Amekodiwa",
"selected": "Zilizochaguliwa",
"total": "Jumla",
"candidate_messages": "Ujumbe wa Watahiniwa",
"search_conversations_placeholder": "Tafuta mazungumzo...",
"total_count": "Jumla ya {count}",
"chat_with": "Piga gumzo na",
"today_realtime_chat_logs": "Leo • Kumbukumbu za Gumzo la Wakati Halisi",
"just_now": "Sasa Hivi",
"direct_push_sent": "Arifa ya Moja kwa Moja ya Push ya Simu imetumwa!",
"popped_up_instantly_desc": "Imetokea papo hapo kwenye kifaa cha mkononi cha {name}.",
"auto_reply_text": "Asante kwa jibu lako! Nimepitia pendekezo lako la toleo na ninatarajia mahojiano yetu ya video.",
"new_message_from": "Ujumbe mpya kutoka kwa {name}!",
"document_attached": "Hati imeambatishwa kwa mafanikio!",
"document_attached_msg": "Hati Imeambatishwa",
"today": "Leo",
"chip_interview": "Je, unapatikana kwa mahojiano ya video leo?",
"chip_salary": "Mshahara wako wa mwisho unaotarajiwa ni upupi?",
"chip_visa": "Je, unaweza kuhamisha visa yako mara moja?",
"type_message_placeholder": "Andika ujumbe unaotii usalama...",
"compliance_profile": "Wasifu wa Utiifu",
"transferable": "Inayohamishika",
"cleared": "Imepitishwa",
"attach_sponsor_documents": "Ambatanisha Nyaraka Zilizothibitishwa za Mfadhili",
"attach_documents_desc": "Pakia karatasi za mfadhili, makubaliano ya ajira, au maelezo ya kazi ili kukagua kwa usalama.",
"sponsor_reviews_star_ratings": "Mapitio ya Wafadhili & Ukadiriaji vya Nyota",
"reviews_posted_by_sponsors_desc": "Ukadiriaji unaweza tu kuchapishwa na wafadhili waliothibitishwa ambao walikamilisha ajira ya moja kwa moja iliyothibitishwa.",
"aed": "AED",
"mo": "mwezi",
"hired_under_sponsorship_desc": "{name} amefaulu kuandikishwa kazi chini ya ufadhili wako! Ulinganifu huu wa moja kwa moja unalingana kikamilifu na Hatua ya 4 ya mtiririko wetu wa MOHRE UAE bila madalali.",
"next_step_post_hire_review": "Hatua Inayofuata: Hatua ya 5 Mapitio ya Baada ya Kuajiri",
"help_community_post_review": "Saidia jamii ya UAE kuajiri kwa usalama kwa kuchapisha mapitio yasiyojulikana yanayoelezea ulezi wa watoto, kupika, kuendesha gari, au ujuzi wa nyumbani wa {name}.",
"back_to_worker_directory": "Rudi kwenye Orodha ya Wafanyakazi",
"report_abuse_violation": "Ripoti Unyanyasaji wa Uhakiki / Ukiukaji wa Masharti",
"zero_tolerance_abuse_desc": "Tunasimamia kutovumilia kabisa nyaraka za kughushi, waajiri wa kujitegemea wanaofanya biashara kwa pesa taslimu, au maelezo yasiyo sahihi ya mawasiliano.",
"additional_context_details": "Maelezo ya ziada ya muktadha",
"provide_specifics_placeholder": "Toa maelezo ya kina ya kile kilichotokea...",
"submit_compliance_report": "Wasilisha Ripoti ya Utiifu",
"submit_performance_review": "Wasilisha Mapitio ya Utendaji Yaliyothibitishwa",
"feedback_helps_sponsors_desc": "Maoni yako yanasaidia wafadhili wengine kufanya maamuzi salama na ya moja kwa moja ya kuajiri.",
"share_your_experience": "Shiriki Uzoefu Wako",
"share_experience_placeholder": "Waambie wafadhili wengine kuhusu ujuzi wa kulelea watoto, kusafisha, mtindo wa kupika, usalama wa kuendesha gari, n.k...",
"post_trust_review_action": "Chapisha Mapitio ya Uaminifu"
}

426
resources/js/lang/ta.json Normal file
View File

@ -0,0 +1,426 @@
{
"dashboard": "டாஷ்போர்டு",
"find_workers": "பணியாளர்களைக் கண்டறியவும்",
"shortlist": "சுருக்கப்பட்டியல்",
"candidates": "வேட்பாளர்கள்",
"messages": "செய்திகள்",
"charity_events": "அறக்கட்டளை நிகழ்வுகள்",
"subscription": "சந்தா",
"my_profile": "எனது சுயவிவரம்",
"search": "தேடல்",
"profile": "சுயவிவரம்",
"sub_warning": "பணியாளர்களைத் தொடர்பு கொள்ள உங்களுக்கு செயலில் உள்ள சந்தா தேவை.",
"subscribe_now": "இப்போதே குழுசேரவும்",
"employer_portal": "முதலாளி போர்டல்",
"active_until": "வரை செயலில் உள்ளது",
"expired_renew": "காலாவதியானது - இப்போதே புதுப்பிக்கவும்",
"overview": "கண்ணோட்டம்",
"my_account": "எனது கணக்கு",
"profile_settings": "சுயவிவர அமைப்புகள்",
"sign_out": "வெளியேறு",
"employer_account": "முதலாளி கணக்கு",
"welcome_title": "சந்தைக்கு வரவேற்கிறோம்!",
"welcome_desc": "உங்கள் முதலாளி சுயவிவரம் சரிபார்க்கப்பட்டு, 30 நாட்களுக்கான பிரீமியம் அணுகலுடன் செயலில் உள்ளது.",
"control_center": "சந்தாதாரர் கட்டுப்பாட்டு மையம்",
"dashboard_title": "சந்தாதாரர் டாஷ்போர்டு - சரிபார்க்கப்பட்ட யுஏஇ வீட்டுப் பணியாளர்கள்",
"expired_pass_title": "உங்கள் சந்தாதாரர் சந்தா பாஸ் காலாவதியாகிவிட்டது!",
"expired_pass_desc": "நேரடித் தொடர்பு, வேட்பாளர் சுயவிவரங்கள் மற்றும் செய்தி அனுப்புதல் ஆகியவை முடக்கப்பட்டுள்ளன. மீண்டும் பணியமர்த்த உங்கள் வருடாந்திர சந்தாவை இப்போதே புதுப்பிக்கவும்.",
"renew_sub": "சந்தாவை புதுப்பிக்கவும்",
"expiring_pass_title": "உங்கள் பிரீமியம் சந்தாதாரர் பாஸ் விரைவில் காலாவதியாகிறது!",
"expiring_pass_desc": "இன்னும் {days} நாட்கே உள்ளன. 500+ சரிபார்க்கப்பட்ட வேட்பாளர்களைத் தொடர்பு கொள்ளும் வாய்ப்பை இழப்பதைத் தவிர்க்க இப்போதே புதுப்பிக்கவும்.",
"renew_now": "இப்போதே புதுப்பிக்கவும்",
"sub_status": "சந்தா நிலை",
"days_left": "நாட்கள் மீதமுள்ளன",
"welcome_back": "மீண்டும் வருக",
"welcome_desc_dash": "எந்தவொரு இடைத்தரகர் கமிஷனும் இல்லாமல் நேரடியாக, MOHRE-இணக்கமான வீட்டுப் பணியாளர்களை நியமிக்கவும். OCR பாஸ்போர்ட் சரிபார்ப்புகளுடன் புதுப்பிக்கப்பட்ட வேட்பாளர்களின் தரவுத்தளத்தை உலாவவும்.",
"browse_workers": "500+ சரிபார்க்கப்பட்ட பணியாளர்களை உலாவவும்",
"sponsor_pass_tier": "சந்தா பாஸ் அடுக்கு",
"renews": "புதுப்பிக்கப்படும் நாள்",
"manage_billing": "பில்லிங் மற்றும் இன்வாய்ஸ்கள் நிர்வாகம்",
"pending_job_offers": "நிலுவையிலுள்ள வேலை சலுகைகள்",
"direct_recruitment": "நேரடி வேலை வாய்ப்பு திட்டங்கள்",
"view_hiring": "பணியமர்த்தல் பணிப்பாய்வுகளைக் காண்க",
"total_hired_workers": "மொத்தமாக பணியமர்த்தப்பட்டவர்கள்",
"direct_contracts": "தொடங்கப்பட்ட நேரடி ஒப்பந்தங்கள்",
"track_active_staff": "செயலில் உள்ள ஊழியர்களைக் கண்காணிக்கவும்",
"shortlisted_candidates": "சுருக்கப்பட்டியலிடப்பட்ட வேட்பாளர்கள்",
"bookmark_list": "நேர்காணல்களுக்கான புக்மார்க் பட்டியல்",
"open_shortlist": "சுருக்கப்பட்டியல் புத்தகத்தைத் திற",
"discover_insights": "சந்தை புள்ளிவிவரங்கள் & நுண்ணறிவுகளைக் கண்டறியவும்",
"dubai_insights": "துபாய் பொதுச் சந்தை நுண்ணறிவு",
"hired_dubai": "துபாயில் செயலியைப் பயன்படுத்தி பணியமர்த்தப்பட்டவர்கள்",
"cooking_care": "சமையல், பராமரிப்பு, வாகனம் ஓட்டுதல்",
"top_skills": "அதிகம் பணியமர்த்தப்பட்ட திறன்கள்",
"turnover_rate": "பணியாளர் வருவாய் விகிதம்",
"sponsor_activity": "உங்கள் சந்தாதாரர் செயல்பாடு புள்ளிவிவரங்கள்",
"workers_contacted": "தொடர்பு கொள்ளப்பட்ட பணியாளர்கள்",
"secure_hires": "பாதுகாப்பான பணியமர்த்தல்கள்",
"quick_actions": "விரைவான செயல்கள்",
"speed_up": "உங்கள் சந்தா செயல்முறையை விரைவுபடுத்துங்கள்.",
"find_nannies": "குழந்தை பராமரிப்பு & செவிலியர்களைக் கண்டறியவும்",
"browse_nannies": "பிரீமியம் சரிபார்க்கப்பட்ட செவிலியர்களை உலாவவும்",
"whatsapp_support": "நேரடி வாட்ஸ்அப் ஆதரவு",
"chat_manager": "பணியமர்த்தல் மேலாளருடன் அரட்டையடிக்கவும்",
"legal_platform": "100% சட்டபூர்வமான யுஏஇ ஏஜென்சி இல்லாத தளம்",
"recommended_for_you": "உங்களுக்காக பரிந்துரைக்கப்படுபவை",
"browse_all": "அனைத்தையும் உலாவவும்",
"view_profile": "சுயவிவரத்தைப் பார்",
"no_recommended": "தற்போது பரிந்துரைக்கப்பட்ட பணியாளர்கள் யாரும் இல்லை. சுயவிவர விவரங்களை புதுப்பிக்கவும்.",
"active_shortlist": "செயலில் உள்ள சுருக்கப்பட்டியல்",
"view_book": "புத்தகத்தைக் காண்க",
"category": "பிரிவு",
"availability": "இருப்பு நிலை",
"open_profile": "சுயவிவரத்தைத் திற",
"shortlist_candidates_desc": "ஆவணங்களை அருகருகே ஒப்பிட்டுப் பார்க்க வேட்பாளர்களை சுருக்கப்பட்டியலிடவும்",
"recent_chats": "சமீபத்திய அரட்டைகள்",
"all_channels": "அனைத்து சேனல்களும்",
"no_chats": "சமீபத்திய அரட்டை பதிவுகள் எதுவும் இல்லை. அரட்டையைத் தொடங்க பணியாளர்களைக் கண்டறியவும்.",
"charity_drives": "சமூக அறக்கட்டளை இயக்கங்கள்",
"live_events": "நேரடி நிகழ்வுகள்",
"charity_drive": "அறக்கட்டளை இயக்கம்",
"provided_items": "வழங்கப்பட்ட பொருட்கள்",
"event_date": "நிகழ்வு தேதி",
"open_maps": "கூகுள் மேப்ஸ் இருப்பிடப் பின்னைத் திற",
"mohre_compliant": "யுஏஇ தத்பீர் & MOHRE இணக்கமானது",
"mohre_desc": "எங்கள் நேரடி ஒப்பந்த முறை மனிதவள மற்றும் எமிரேடிசேஷன் அமைச்சகத்தின் வழிகாட்டுதல்களுடன் தானாகவே ஒத்துப்போகிறது. முழு சட்டப்பூர்வமானது, பூஜ்ஜிய ஏஜென்ட் கட்டணம், முழுமையான வெளிப்படைத்தன்மை.",
"visit_mohre": "MOHRE UAE வலைத்தளத்தைப் பார்வையிடவும்",
"my_shortlist": "எனது சுருக்கப்பட்டியல்",
"candidates_saved": "மதிப்பாய்விற்காக {count} வேட்பாளர்களை சேமித்துள்ளீர்கள்",
"browse_more": "மேலும் பணியாளர்களை உலாவுக",
"verified": "சரிபார்க்கப்பட்டது",
"warning": "எச்சரிக்கை",
"platform_skills": "தள திறன்கள்",
"languages_spoken": "பேசப்படும் மொழிகள்",
"quick_preview": "விரைவான முன்னோட்டம்",
"compare_candidate": "வேட்பாளரை ஒப்பிடுக",
"comparing_active": "ஒப்பிடுதல் செயலில் உள்ளது ✓",
"message": "செய்தி அனுப்பு",
"shortlist_empty": "உங்கள் சுருக்கப்பட்டியல் காலியாக உள்ளது",
"shortlist_empty_desc": "வேட்பாளர் சுயவிவரங்களை ஆராய்ந்து அவற்றை உங்கள் சேமித்த சுருக்கப்பட்டியலில் சேர்க்கவும்.",
"find_workers_now": "இப்போது பணியாளர்களைக் கண்டறியவும்",
"comparing_workers": "பணியாளர்களை ஒப்பிடுதல்",
"clear_all": "அனைத்தையும் அழி",
"remove_shortlist": "சுருக்கப்பட்டியலை நீக்கு",
"view_full_details": "முழு விவரங்களையும் காண்க",
"no_bio_provided": "சுயசரிதை விவரங்கள் எதுவும் வழங்கப்படவில்லை.",
"expectations": "எதிர்பார்ப்புகள்",
"languages": "மொழிகள்",
"availability_status_label": "இருப்பு நிலை",
"job_preference": "வேலை முன்னுரிமை",
"remove_from_shortlist": "சுருக்கப்பட்டியலில் இருந்து நீக்கு",
"max_compare_alert": "அதிகபட்சமாக 3 வேட்பாளர்களை மட்டுமே ஒப்பிட முடியும்.",
"sponsor_pass_billing": "சந்தா பாஸ் & பில்லிங்",
"subscription_billing_title": "சந்தா பில்லிங் & இன்வாய்ஸ்கள் - முதலாளி போர்டல்",
"recurrent_billing_failed": "உங்கள் வழக்கமான சந்தா பில்லிங் தோல்வியடைந்தது!",
"recurrent_billing_failed_desc": "போதிய நிதி இல்லாததால் அட்டை புதுப்பித்தல் தோல்வியடைந்தது. கணக்கு முடக்கப்படுவதைத் தவிர்க்க PayTabs ஐப் பயன்படுத்தி மீண்டும் முயற்சிக்கவும்.",
"retry_payment_now": "இப்போதே பில்லிங் மீண்டும் முயற்சி செய்",
"active_plan_pass": "செயலில் உள்ள திட்ட பாஸ்",
"renewing_auto_payment_on": "தானியங்கி முறையில் புதுப்பிக்கப்படும் நாள்",
"simulate_billing_failure": "பில்லிங் தோல்வியை உருவகப்படுத்து",
"verified_sponsor_status": "சரிபார்க்கப்பட்ட முதலாளி நிலை",
"sponsor_pass_updated": "முதலாளி பாஸ் வெற்றிகரமாக புதுப்பிக்கப்பட்டது! PayTabs பரிவர்த்தனை பதிவு செய்யப்பட்டது.",
"available_subscription_tiers": "கிடைக்கக்கூடிய சந்தா அடுக்குகள்",
"available_subscription_tiers_desc": "எப்போது வேண்டுமானாலும் மேம்படுத்தலாம் அல்லது ரத்து செய்யலாம். அனைத்து ஒப்பந்தங்களும் யுஏஇ தத்பீர் MOHRE வழிகாட்டுதல்களுக்கு இணங்கின.",
"most_popular_tier": "மிகவும் பிரபலமான அடுக்கு",
"current_active_tier": "தற்போதைய செயலில் உள்ள அடுக்கு ✓",
"select_plan_tier": "திட்ட அடுக்கைத் தேர்வுசெய்",
"billing_payment_receipts": "பில்லிங் கட்டண ரசீதுகள்",
"tax_compliant_invoices": "வரிக்கு உட்பட்ட இன்வாய்ஸ்கள்",
"corporate_details": "கார்ப்பரேட் விவரங்கள்",
"update_tax_invoicing": "வரி இன்வாய்ஸ் விருப்பங்களைப் புதுப்பிக்கவும்.",
"sponsor_email_address": "முதலாளி மின்னஞ்சல் முகவரி",
"billing_vat_id": "பில்லிங் VAT பதிவு ஐடி (விருப்பத்திற்குரியது)",
"save_billing_profile": "பில்லிங் சுயவிவரத்தைச் சேமி",
"paytabs_secured_checkout": "PayTabs பாதுகாப்பான கட்டணம்",
"gateway_version": "கட்டண நுழைவாயில் v4.0",
"order_description": "ஆர்டர் விளக்கம்",
"total_amount": "மொத்த தொகை",
"cardholder_name": "அட்டைதாரர் பெயர்",
"card_number": "அட்டை எண்",
"expiry_date": "காலாவதி தேதி (MM/YY)",
"security_code": "பாதுகாப்புக் குறியீடு (CVV)",
"pci_dss_cryptography": "256-பிட் PCI DSS கிரிப்டோகிராபி பாதுகாக்கப்பட்டது",
"authorize_payment": "கட்டணத்தை அங்கீகரிக்கவும்",
"simulated_billing_failure_triggered": "உருவகப்படுத்தப்பட்ட பில்லிங் தோல்வி தூண்டப்பட்டது!",
"simulated_billing_failure_desc": "தானியங்கி கணினி எச்சரிக்கை இப்போது கட்டண மறுமுயற்சி விருப்பங்களைக் கோரும்.",
"payment_approved": "PayTabs மூலம் கட்டணம் அங்கீகரிக்கப்பட்டது!",
"successfully_subscribed_desc": "{plan}க்கு வெற்றிகரமாக குழுசேரப்பட்டது. பிரீமியம் அணுகல் வரம்புகள் உடனடியாக புதுப்பிக்கப்பட்டன.",
"invoice_generated": "இன்வாய்ஸ் {id} உருவாக்கப்பட்டது",
"invoice_download_desc": "நேரடி MOHRE முதலாளி ரசீது PDF வடிவத்தில் வெற்றிகரமாக பதிவிறக்கம் செய்யப்பட்டது.",
"corporate_billing_updated": "கார்ப்பரேட் பில்லிங் விவரங்கள் புதுப்பிக்கப்பட்டன.",
"invalid_card_format": "தவறான அட்டை எண் வடிவம்",
"candidates_pipeline": "வேட்பாளர்கள்",
"candidates_pipeline_desc": "உங்கள் பணியாளர் நியமனக் குழாயை நிர்வகிக்கவும்",
"total_candidates": "மொத்த வேட்பாளர்கள்",
"reviewing": "மதிப்பாய்வு செய்யப்படுகிறது",
"offer_sent": "சலுகை அனுப்பப்பட்டது",
"hired": "பணியமர்த்தப்பட்டார்",
"rejected": "நிராகரிக்கப்பட்டது",
"search_by_name": "பெயர் மூலம் தேடுக...",
"candidate_header": "வேட்பாளர்",
"selected_header": "தேர்ந்தெடுக்கப்பட்டது",
"category_header": "பிரிவு",
"salary_header": "சம்பளம்",
"status_header": "நிலை",
"actions_header": "செயல்கள்",
"change_status_label": "நிலையை மாற்று",
"no_candidates_found": "வேட்பாளர்கள் யாரும் இல்லை",
"showing_candidates": "மொத்த {total} வேட்பாளர்களில் {start} முதல் {end} வரை காட்டுகிறது",
"account_settings": "கணக்கு அமைப்புகள்",
"profile_employer_portal": "சுயவிவரம் - முதலாளி போர்டல்",
"profile_updated_successfully": "சுயவிவரம் வெற்றிகரமாக புதுப்பிக்கப்பட்டது",
"profile_updated_successfully_desc": "வீட்டு சந்தாதாரர் விருப்பங்களும் சரிபார்க்கப்பட்ட சான்றுகளும் வெற்றிகரமாக ஒத்திசைக்கப்பட்டன.",
"profile_update_failed": "சுயவிவரத்தைப் புதுப்பிக்க முடியவில்லை",
"check_form_fields": "படிவ புலங்களை சரிபார்க்கவும்.",
"tab_personal": "தனிப்பட்ட",
"tab_security": "பாதுகாப்பு & கடவுச்சொல்",
"tab_billing": "பில்லிங் & ரசீதுகள்",
"tab_notifications": "அறிவிப்பு மையம்",
"emirates_id_vetted": "எமிரேட்ஸ் ஐடி சரிபார்க்கப்பட்டது",
"direct_sponsor_portal": "நேரடி முதலாளி போர்டல்",
"personal_details_header": "தனிப்பட்ட விவரங்கள்",
"personal_details_desc": "முதலாளி சுயவிவரம் மற்றும் சான்றுகளை நிர்வகிக்கவும்",
"full_sponsor_name": "முழு முதலாளி பெயர்",
"invoicing_email": "பில்லிங் மின்னஞ்சல்",
"uae_mobile_contact": "யுஏஇ மொபைல் தொடர்பு",
"sponsor_nationality": "முதலாளி குடியுரிமை",
"select_nationality": "குடியுரிமையைத் தேர்ந்தெடுக்கவும்",
"uae_national": "யுஏஇ தேசியவாதி",
"expat_uk_europe": "வெளிநாட்டவர் (யுகே / ஐரோப்பா)",
"expat_usa_canada": "வெளிநாட்டவர் (அமெரிக்கா / கனடா)",
"expat_asia_gcc": "வெளிநாட்டவர் (ஆசியா / ஜிசிசி)",
"family_members_size": "குடும்ப உறுப்பினர்களின் எண்ணிக்கை",
"select_family_size": "குடும்ப அளவைத் தேர்ந்தெடுக்கவும்",
"family_1_2": "1-2 உறுப்பினர்கள்",
"family_3_4": "3-4 உறுப்பினர்கள்",
"family_5_plus": "5+ உறுப்பினர்கள்",
"accommodation_residence": "தங்குமிட வகை",
"select_accommodation": "தங்குமிடத்தைத் தேர்ந்தெடுக்கவும்",
"villa": "வில்லா",
"penthouse": "அபார்ட்மெண்ட் (பென்ட்ஹவுஸ்)",
"apartment_1_3": "அபார்ட்மெண்ட் (1-3 படுக்கையறை)",
"city_district_area": "நகர மாவட்டம் / பகுதி",
"emirates_id_verification_header": "எமிரேட்ஸ் ஐடி சரிபார்ப்பு",
"emirates_id_verification_desc": "ஒழுங்குமுறை இணக்க சான்றுகள்",
"emirates_id_verified_status": "எமிரேட்ஸ் ஐடி சரிபார்க்கப்பட்டது",
"mohre_guidelines": "MOHRE வழிகாட்டுதல்களின் கீழ் சரிபார்க்கப்பட்டது",
"emirates_id_verified_desc": "உங்கள் எமிரேட்ஸ் ஐடி வெற்றிகரமாக சரிபார்க்கப்பட்டது. நேரடி பணியமர்த்தலுக்கு உங்கள் கணக்கு செயலில் உள்ளது.",
"verification_pending_status": "சரிபார்ப்பு தணிக்கைக்காக காத்திருக்கிறது",
"audit_queue": "தணிக்கை வரிசை",
"verification_pending_desc": "நீங்கள் பதிவேற்றிய எமிரேட்ஸ் ஐடி ஆவணங்கள் தற்போது தணிக்கையில் உள்ளன. பொதுவாக 24 மணி நேரத்திற்குள் சரிபார்க்கப்படும்.",
"verification_required_status": "எமிரேட்ஸ் ஐடி சரிபார்ப்பு தேவை",
"action_needed": "செயல் தேவை",
"verification_required_desc": "உங்கள் அடையாளத்தை சரிபார்க்கவும் முழு பணியமர்த்தல் அம்சங்களை செயல்படுத்தவும் உங்கள் எமிரேட்ஸ் ஐடியின் வண்ண ஸ்கேன்களை பதிவேற்றவும்.",
"emirates_id_front_side": "எமிரேட்ஸ் ஐடி (முன்பக்கம்)",
"emirates_id_back_side": "எமிரேட்ஸ் ஐடி (பின்பக்கம்)",
"uploaded_credentials_scans": "பதிவேற்றப்பட்ட சான்றுகளின் ஸ்கேன்கள்",
"view_scan": "ஸ்கேனைக் காண்க",
"security_password_header": "பாதுகாப்பு & கடவுச்சொல்",
"security_password_desc": "உங்கள் முதலாளி கணக்கை பாதுகாப்பாக வைத்திருங்கள்",
"current_password": "தற்போதைய கடவுச்சொல்",
"new_password": "புதிய கடவுச்சொல்",
"confirm_new_password": "புதிய கடவுச்சொல்லை உறுதிப்படுத்தவும்",
"current_plan": "தற்போதைய திட்டம்",
"active_status": "செயலில் உள்ளது",
"next_payment": "அடுத்த கட்டணம்",
"recent_transactions": "சமீபத்திய பரிவர்த்தனைகள்",
"date_header": "தேதி",
"description_header": "விளக்கம்",
"amount_header": "தொகை",
"receipt_header": "ரசீது",
"notification_settings_hub": "அறிவிப்பு அமைப்புகள் மையம்",
"notification_settings_desc": "அறிவிப்புகளை எவ்வாறு பெற விரும்புகிறீர்கள் என்பதைத் தேர்வுசெய்க",
"email_alerts": "மின்னஞ்சல் எச்சரிக்கைகள்",
"email_alerts_desc": "சரிபார்க்கப்பட்ட பணியாளர் பரிந்துரைகள் மற்றும் விசா புதுப்பிப்புகளைப் பெறுங்கள்.",
"sms_alerts": "எஸ்எம்எஸ் உடனடி ரசீதுகள்",
"sms_alerts_desc": "நேர்காணல் அட்டவணைகளுக்கான எஸ்எம்எஸ் அறிவிப்புகளைப் பெறுங்கள்.",
"push_alerts": "புஷ் அறிவிப்புகள்",
"push_alerts_desc": "புதிய நேரடி செய்திகளுக்கான டெஸ்க்டாப் ஒலி அறிவிப்புகளைப் பெறுங்கள்.",
"changes_saved": "மாற்றங்கள் வெற்றிகரமாக சேமிக்கப்பட்டன",
"emirates_id_reverification_notice": "சில புதுப்பிப்புகளுக்கு எமிரேட்ஸ் ஐடி மறுசரிபார்ப்பு தேவைப்படலாம்.",
"update_settings": "அமைப்புகளைப் புதுப்பி",
"charity_events_support_drives": "அறக்கட்டளை நிகழ்வுகள் & ஆதரவு இயக்கங்கள்",
"community_charity_events_sponsor_hub": "சமூக அறக்கட்டளை நிகழ்வுகள் - முதலாளி மையம்",
"community_charity_event_posted": "சமூக அறக்கட்டளை நிகழ்வு வெளியிடப்பட்டது!",
"community_charity_event_posted_desc": "துபாயில் உள்ள அனைத்து பணியாளர்களுக்கும் உடனடி புஷ் அறிவிப்பு அனுப்பப்பட்டது! நிகழ்வு காலையிலேயே நினைவூட்டல் வெற்றிகரமாக திட்டமிடப்பட்டது.",
"dubai_community_support_drives": "துபாய் சமூக ஆதரவு இயக்கங்கள்",
"free_medical_checks_title": "இலவச மருத்துவ பரிசோதனைகள், உணவு இயக்கங்கள் & ஆதரவு சேவைகள்",
"free_medical_checks_desc": "ஆதரவு திட்டத்தை ஏற்பாடு செய்கிறீர்களா? சமூக பிரச்சாரங்களை நேரடியாக பகிரவும். தளம் தானாகவே பணியாளர்களுக்கு உடனடி புஷ் அறிவிப்பை அனுப்பும், அதைத் தொடர்ந்து வருகையை வலுவாக வைத்திருக்க நிகழ்வு காலையில் நினைவூட்டல் அனுப்பப்படும்.",
"search_charity_events_placeholder": "அறக்கட்டளை நிகழ்வுகள் & இயக்கங்களை தேடுக...",
"post_charity_event": "அறக்கட்டளை நிகழ்வை வெளியிடு",
"broadcast_support_program_desc": "பணியாளர் சமூகத்திற்கு ஒரு ஆதரவு திட்டம், மருத்துவ முகாம் அல்லது விநியோக இயக்கத்தை ஒளிபரப்பவும்.",
"charity_drive_metadata": "அறக்கட்டளை இயக்க மெட்டாடேட்டா (துபாய் ஆதரவு)",
"event_time_placeholder": "உதாரணமாக 9:00 முற்பகல் - 4:00 பிற்பகல்",
"what_is_provided": "வழங்கப்படுவது என்ன",
"provided_items_placeholder": "உதாரணமாக இலவச மருத்துவ பரிசோதனை, உணவுப் பெட்டிகள், பொருட்கள்",
"location_details_pin": "இட விவரங்கள் & கூகுள் மேப் இணைப்பு",
"location_details_placeholder": "உதாரணமாக அல் கூஸ் சமூக மையம், துபாய்",
"maps_pin_link_placeholder": "கூகுள் மேப்ஸ் இருப்பிட இணைப்பு (உதாரணமாக https://maps.app.goo.gl/xyz)",
"title_label": "தலைப்பு",
"title_placeholder": "உதாரணமாக எமிரேட்ஸ் அறக்கட்டளையின் இலவச பல் பரிசோதனை",
"event_desc_instructions": "நிகழ்வு விளக்கம் & வழிமுறைகள்",
"event_desc_placeholder": "அறக்கட்டளை நிகழ்வின் விவரங்களை இங்கே உள்ளிடவும்...",
"publish_charity_event": "அறக்கட்டளை நிகழ்வை வெளியிடு",
"no_announcements_title": "அறிவிப்புகள் ஏதுமில்லை",
"no_announcements_desc": "நீங்கள் இன்னும் எந்த அறிவிப்பையும் வெளியிடவில்லை",
"community_charity_drive": "சமூக அறக்கட்டளை இயக்கம்",
"push_reminder_scheduled": "புஷ் & நினைவூட்டல் திட்டமிடப்பட்டது",
"provided_packages": "வழங்கப்பட்ட தொகுப்புகள்",
"event_timing": "நிகழ்வு நேரம்",
"event_location_address": "நிகழ்வு நடைபெறும் இடம்",
"view_map_location_pin": "வரைபடத்தில் இருப்பிடத்தைக் காண்க",
"find_vetted_workers": "சரிபார்க்கப்பட்ட வீட்டுப் பணியாளர்களைக் கண்டறியவும்",
"find_workers_platform": "பணியாளர்களைக் கண்டறியவும் - வீட்டுப் பணியாளர் தளம்",
"no_middlemen_platform": "இடைத்தரகர் இல்லாத தளம்",
"find_verified_candidates": "சரிபார்க்கப்பட்ட வேட்பாளர்களைக் கண்டறியவும்",
"connect_vetted_workers_desc": "யுஏஇ சரிபார்க்கப்பட்ட, பின்னணி தணிக்கை செய்யப்பட்ட வீட்டுப் பணியாளர்களுடன் உடனடியாக இணைக்கவும்.",
"search_by_name_skills_bio": "பெயர், திறன்கள், சுயசரிதை மூலம் தேடுக (உதாரணமாக சமையல், குழந்தை பராமரிப்பு, தோட்டம், ஓட்டுநர்)...",
"default_match": "இயல்புநிலை பொருத்தம்",
"salary_low_to_high": "சம்பளம்: குறைந்த அளவிலிருந்து அதிக அளவு",
"salary_high_to_low": "சம்பளம்: அதிக அளவிலிருந்து குறைந்த அளவு",
"rating_high_to_low": "மதிப்பீடு: அதிக மதிப்பிலிருந்து குறைந்த மதிப்பு",
"experience_level": "அனுபவ நிலை",
"reset": "மீட்டமை",
"nationality": "குடியுரிமை",
"select_skills": "திறன்களைத் தேர்ந்தெடு",
"select_languages": "மொழிகளைத் தேர்ந்தெடு",
"select_visa_status": "விசா நிலையைத் தேர்ந்தெடு",
"found_workers_matching": "தேடலுக்குப் பொருத்தமான {count} வீட்டுப் பணியாளர்கள் கண்டறியப்பட்டனர்",
"direct_sponsoring_active": "MOHRE யுஏஇ நேரடி ஸ்பான்சர்ஷிப் செயலில் உள்ளது",
"load_more_workers": "மேலும் பணியாளர்களைக் காட்டு",
"no_candidates_matching": "உங்கள் வடிகட்டிகளுடன் பொருந்தும் வேட்பாளர்கள் யாரும் இல்லை",
"adjust_filters_desc": "உங்கள் சம்பள வரம்பை சரிசெய்யவும், கூடுதல் மொழிகளைச் சேர்க்கவும் அல்லது குடியுரிமை விருப்பங்களை விரிவுபடுத்தவும்.",
"reset_filters": "வடிகட்டிகளை மீட்டமை",
"comparing_workers_count": "பணியாளர்களை ஒப்பிடுதல் ({count} இல் 3)",
"expected": "எதிர்பார்க்கப்படும்",
"region": "பிராந்தியம்",
"visa_transfer": "விசா பரிமாற்றம்",
"medical_status": "மருத்துவ நிலை",
"passport_ocr": "பாஸ்போர்ட் OCR",
"open_worker_profile": "பணியாளர் சுயவிவரத்தைத் திறக்கவும்",
"attach_verified_sponsor_docs": "சரிபார்க்கப்பட்ட ஸ்பான்சர் ஆவணங்களை இணைக்கவும்",
"upload_sponsor_papers_desc": "பாதுகாப்பாக மதிப்பாய்வு செய்ய ஸ்பான்சர் ஆவணங்கள், வேலை ஒப்பந்தங்கள் அல்லது பணி விளக்கங்களை பதிவேற்றவும்.",
"select_files_drag": "கோப்புகளைத் தேர்ந்தெடுக்கவும் அல்லது இங்கே இழுக்கவும்",
"max_file_size": "PDF, JPG, PNG (அதிகபட்சம் 5MB)",
"close": "மூடு",
"chat_with_worker": "{name} உடன் அரட்டையடிக்கவும் - செய்திகள்",
"messages_hub": "செய்தி மையம்",
"ssl_secure": "SSL பாதுகாப்பானது",
"active_now": "இப்போது செயலில் உள்ளார்",
"whatsapp_bridge": "வாட்ஸ்அப் இணைப்பு",
"toggle_context_sidebar": "பக்கவாட்டு சுயவிவரப் பலகையை மாற்று",
"today_realtime_chat": "இன்று • நிகழ்நேர அரட்டைப் பதிவுகள்",
"read": "படிக்கப்பட்டது",
"type_compliant_message": "பாதுகாப்பான செய்தியைத் தட்டச்சு செய்யவும்...",
"conversation_messages": "வேட்பாளர் செய்திகள்",
"messages_employer_portal": "செய்திகள் - முதலாளி போர்டல்",
"search_conversations": "அரட்டைகளைத் தேடுக...",
"new_conversation": "புதிய அரட்டை",
"active_threads": "செயலில் உள்ள அரட்டைகள்",
"total_conversations": "மொத்தம் {count}",
"no_active_messages": "செயலில் உள்ள செய்திகள் எதுவும் இல்லை",
"no_active_messages_desc": "நீங்கள் பணியாளர்களுக்கு செய்தி அனுப்பும்போது அல்லது நேர்காணல்களை திட்டமிடும்போது, உங்கள் அரட்டைப் பதிவுகள் இங்கே தோன்றும்.",
"candidate_profile_detail": "வேட்பாளர் சுயவிவர விவரம்",
"back_to_find_workers": "பணியாளர் தேடலுக்குத் திரும்பு",
"share_profile": "சுயவிவரத்தைப் பகிர்",
"report_worker": "பணியாளர் குறித்து புகார் செய்",
"sponsorship_details": "ஸ்பான்சர்ஷிப் விவரங்கள்",
"salary_expectations": "சம்பள எதிர்பார்ப்புகள்",
"work_experience": "வேலை அனுபவம்",
"emirates_id_vetting": "எமிரேட்ஸ் ஐடி தணிக்கை",
"medical_health_test": "மருத்துவ சுகாதார சோதனை",
"passed_certified": "தேர்ச்சி பெற்றது சரிபார்க்கப்பட்டது",
"professional_summary": "தொழில்முறை சுருக்கம்",
"verified_skills_competencies": "சரிபார்க்கப்பட்ட திறன்கள் & தகுதிகள்",
"verified_legal_documents": "சரிபார்க்கப்பட்ட சட்ட ஆவணங்கள் (யுஏஇ MOHRE அங்கீகரித்தது)",
"passport_verified": "பாஸ்போர்ட் (சரிபார்க்கப்பட்டது)",
"click_zoom": "பெரிதாக்க கிளிக் செய்க",
"document_id": "ஆவண ஐடி",
"issue": "வழங்கப்பட்ட நாள்",
"expiry": "காலாவதி நாள்",
"ocr_match": "OCR பொருத்தம்",
"emirates_id_pdpl": "எமிரேட்ஸ் ஐடி (PDPL இணக்கமானது)",
"scan_purged": "ஸ்கேன் நீக்கப்பட்டது",
"uae_pdpl_compliant": "யுஏஇ PDPL இணக்கமானது",
"verification_type": "சரிபார்ப்பு வகை",
"physical_scan_storage": "உடல் ரீதியான ஸ்கேன் சேமிப்பு",
"permanently_purged": "நிரந்தரமாக நீக்கப்பட்டது",
"entry_visa_verified": "நுழைவு விசா (சரிபார்க்கப்பட்டது)",
"visa_category": "விசா வகை",
"vetting_status": "சரிபார்ப்பு நிலை",
"transfer_required": "பரிமாற்றம் தேவை",
"needs_regularization": "விசா சரிசெய்தல் தேவை",
"clear_records": "தெளிவான பதிவுகள்",
"sponsor_reviews_ratings": "முதலாளி மதிப்புரைகள் & நட்சத்திர மதிப்பீடுகள்",
"ratings_policy_desc": "மதிப்பீடுகளை சரிபார்க்கப்பட்ட நேரடி பணியமர்த்தலை முடித்த சரிபார்க்கப்பட்ட முதலாளிகள் மட்டுமே வெளியிட முடியும்.",
"post_trust_review": "மதிப்பாய்வை வெளியிடு",
"similar_recommended_workers": "இதே போன்ற பரிந்துரைக்கப்பட்ட பணியாளர்கள்",
"direct_sponsoring_finalized": "நேரடி ஸ்பான்சர்ஷிப் முடிந்தது!",
"hired_stage4_desc": "உங்கள் ஸ்பான்சர்ஷிப்பின் கீழ் {name} வெற்றிகரமாக பணியமர்த்தப்பட்டார்! இந்த நேரடி பொருத்தம் எங்களது யுஏஇ MOHRE இடைத்தரகர் இல்லாத முறையின் 4-வது கட்டத்திற்கு முற்றிலும் இணங்குகிறது.",
"next_step_stage5": "அடுத்த கட்டம்: கட்டம் 5 பணியமர்த்திய பின் மதிப்புரை",
"post_hire_review_desc": "{name}-இன் குழந்தைகள் பராமரிப்பு, சமையல், ஓட்டுநர் அல்லது வீட்டுத் திறன்களைப் விவரிக்கும் ஒரு அநாமதேய மதிப்புரையை வெளியிடுவதன் மூலம் யுஏஇ சமூகம் பாதுகாப்பாக பணியமர்த்த உதவுங்கள்.",
"leave_trust_review": "மதிப்புரையை வழங்கு",
"back_to_directory": "பணியாளர் அடைவுக்குத் திரும்பு",
"report_abuse_title": "சரிபார்ப்பு முறைகேடு / விதிமுறை மீறல் குறித்து புகார் செய்",
"report_abuse_desc": "போலி ஆவணங்கள், பணம் வாங்கி வேலை தரும் தனிநபர் முகவர்கள் அல்லது தவறான தொடர்பு விவரங்கள் ஆகியவற்றை நாங்கள் முற்றிலும் அனுமதிப்பதில்லை.",
"reason": "காரணம்",
"select_reason": "ஒரு காரணத்தைத் தேர்ந்தெடுக்கவும்...",
"reason_fees": "பணியாளர் / முகவர் பணியமர்த்தல் கமிஷன் கட்டணம் கேட்டார்",
"reason_profile": "சுயவிவர விவரங்கள் / பாஸ்போர்ட் உண்மையான நபருடன் பொருந்தவில்லை",
"reason_contact": "தவறான தொலைபேசி எண் / தொடர்பு கொள்ள முடியவில்லை",
"reason_other": "இதர விதிமுறை மீறல்கள்",
"additional_context": "கூடுதல் விவரங்கள்",
"provide_specifics": "என்ன நடந்தது என்பதை விரிவாக விவரிக்கவும்...",
"cancel": "ரத்துசெய்",
"submit_report": "புகாரைச் சமர்ப்பி",
"submit_verified_review": "சரிபார்க்கப்பட்ட செயல்திறன் மதிப்புரையைச் சமர்ப்பி",
"review_help_desc": "உங்கள் கருத்து மற்ற முதலாளிகளுக்கு பாதுகாப்பான மற்றும் நேரடி பணியமர்த்தல் முடிவுகளை எடுக்க உதவுகிறது.",
"star_rating": "நட்சத்திர மதிப்பீடு",
"share_experience": "உங்கள் அனுபவத்தைப் பகிர்ந்து கொள்ளுங்கள்",
"review_textarea_placeholder": "குழந்தை பராமரிப்பு திறன்கள், சுத்தம் செய்தல், சமையல் நடைமுறை, ஓட்டுநர் பாதுகாப்பு போன்றவற்றைப் பற்றி மற்ற முதலாளிகளுக்குத் தெரியப்படுத்துங்கள்...",
"post_trust_review_btn": "மதிப்புரையை வெளியிடு",
"start_direct_chat": "நேரடி அரட்டையைத் தொடங்கு",
"mark_hired": "பணியமர்த்தப்பட்டார் என குறி",
"selected": "தேர்ந்தெடுக்கப்பட்டது",
"total": "மொத்தம்",
"candidate_messages": "வேட்பாளர் செய்திகள்",
"search_conversations_placeholder": "அரட்டைகளைத் தேடுக...",
"total_count": "மொத்தம் {count}",
"chat_with": "உடன் அரட்டையடி",
"today_realtime_chat_logs": "இன்று • நிகழ்நேர அரட்டைப் பதிவுகள்",
"just_now": "இப்போது தான்",
"direct_push_sent": "நேரடி மொபைல் புஷ் அறிவிப்பு அனுப்பப்பட்டது!",
"popped_up_instantly_desc": "{name}-இன் மொபைல் சாதனத்தில் உடனடியாகத் தோன்றியது.",
"auto_reply_text": "உங்கள் பதிலுக்கு நன்றி! உங்கள் முன்மொழிவை நான் மதிப்பாய்வு செய்துள்ளேன், நமது வீடியோ நேர்காணலை எதிர்நோக்கியுள்ளேன்.",
"new_message_from": "{name}-இடமிருந்து புதிய செய்தி!",
"document_attached": "ஆவணம் வெற்றிகரமாக இணைக்கப்பட்டது!",
"document_attached_msg": "ஆவணம் இணைக்கப்பட்டது",
"today": "இன்று",
"chip_interview": "இன்று வீடியோ நேர்காணலுக்கு நீங்கள் தயாரா?",
"chip_salary": "உங்களது இறுதி எதிர்பார்க்கும் சம்பளம் என்ன?",
"chip_visa": "உங்கள் விசாவை உடனடியாக மாற்ற முடியுமா?",
"type_message_placeholder": "பாதுகாப்பான செய்தியைத் தட்டச்சு செய்யவும்...",
"compliance_profile": "விதிமுறை இணக்க சுயவிவரம்",
"transferable": "மாற்றக்கூடியது",
"cleared": "தேர்ச்சி பெற்றது சரிபார்க்கப்பட்டது",
"attach_sponsor_documents": "சரிபார்க்கப்பட்ட ஸ்பான்சர் ஆவணங்களை இணைக்கவும்",
"attach_documents_desc": "பாதுகாப்பாக மதிப்பாய்வு செய்ய ஸ்பான்சர் ஆவணங்கள், வேலை ஒப்பந்தங்கள் அல்லது பணி விளக்கங்களை பதிவேற்றவும்.",
"sponsor_reviews_star_ratings": "முதலாளி மதிப்புரைகள் & நட்சத்திர மதிப்பீடுகள்",
"reviews_posted_by_sponsors_desc": "மதிப்பீடுகளை சரிபார்க்கப்பட்ட நேரடி பணியமர்த்தலை முடித்த சரிபார்க்கப்பட்ட முதலாளிகள் மட்டுமே வெளியிட முடியும்.",
"aed": "AED",
"mo": "மாதம்",
"hired_under_sponsorship_desc": "உங்கள் ஸ்பான்சர்ஷிப்பின் கீழ் {name} வெற்றிகரமாக பணியமர்த்தப்பட்டார்! இந்த நேரடி பொருத்தம் எங்களது யுஏஇ MOHRE இடைத்தரகர் இல்லாத முறையின் 4-வது கட்டத்திற்கு முற்றிலும் இணங்குகிறது.",
"next_step_post_hire_review": "அடுத்த கட்டம்: கட்டம் 5 பணியமர்த்திய பின் மதிப்புரை",
"help_community_post_review": "{name}-இன் குழந்தைகள் பராமரிப்பு, சமையல், ஓட்டுநர் அல்லது வீட்டுத் திறன்களைப் விவரிக்கும் ஒரு அநாமதேய மதிப்புரையை வெளியிடுவதன் மூலம் யுஏஇ சமூகம் பாதுகாப்பாக பணியமர்த்த உதவுங்கள்.",
"back_to_worker_directory": "பணியாளர் அடைவுக்குத் திரும்பு",
"report_abuse_violation": "சரிபார்ப்பு முறைகேடு / விதிமுறை மீறல் குறித்து புகார் செய்",
"zero_tolerance_abuse_desc": "போலி ஆவணங்கள், பணம் வாங்கி வேலை தரும் தனிநபர் முகவர்கள் அல்லது தவறான தொடர்பு விவரங்கள் ஆகியவற்றை நாங்கள் முற்றிலும் அனுமதிப்பதில்லை.",
"additional_context_details": "கூடுதல் விவரங்கள்",
"provide_specifics_placeholder": "என்ன நடந்தது என்பதை விரிவாக விவரிக்கவும்...",
"submit_compliance_report": "புகாரைச் சமர்ப்பி",
"submit_performance_review": "சரிபார்க்கப்பட்ட செயல்திறன் மதிப்புரையைச் சமர்ப்பி",
"feedback_helps_sponsors_desc": "உங்கள் கருத்து மற்ற முதலாளிகளுக்கு பாதுகாப்பான மற்றும் நேரடி பணியமர்த்தல் முடிவுகளை எடுக்க உதவுகிறது.",
"share_your_experience": "உங்கள் அனுபவத்தைப் பகிர்ந்து கொள்ளுங்கள்",
"share_experience_placeholder": "குழந்தை பராமரிப்பு திறன்கள், சுத்தம் செய்தல், சமையல் நடைமுறை, ஓட்டுநர் பாதுகாப்பு போன்றவற்றைப் பற்றி மற்ற முதலாளிகளுக்குத் தெரியப்படுத்துங்கள்...",
"post_trust_review_action": "மதிப்புரையை வெளியிடு"
}

426
resources/js/lang/tl.json Normal file
View File

@ -0,0 +1,426 @@
{
"dashboard": "Dashboard",
"find_workers": "Maghanap ng mga Manggagawa",
"shortlist": "Shortlist",
"candidates": "Mga Kandidato",
"messages": "Mga Mensahe",
"charity_events": "Mga Kaganapang Kawanggawa",
"subscription": "Susunod",
"my_profile": "Aking Profile",
"search": "Maghanap",
"profile": "Profile",
"sub_warning": "Kailangan mo ng aktibong subscription upang makipag-ugnayan sa mga manggagawa.",
"subscribe_now": "Mag-subscribe ngayon",
"employer_portal": "Portal ng Employer",
"active_until": "Aktibo hanggang",
"expired_renew": "Expired — Mag-renew ngayon",
"overview": "Pangkalahatang-ideya",
"my_account": "Aking Account",
"profile_settings": "Mga Setting ng Profile",
"sign_out": "Mag-sign Out",
"employer_account": "Account ng Employer",
"welcome_title": "Maligayang pagdating sa Marketplace!",
"welcome_desc": "Ang iyong profile bilang employer ay na-verify at aktibo na may 30 araw na Premium Access.",
"control_center": "Control Center ng Sponsor",
"dashboard_title": "Dashboard ng Sponsor - Mga Beripikadong Kasambahay sa UAE",
"expired_pass_title": "Ang iyong Sponsor Subscription Pass ay Expired na!",
"expired_pass_desc": "Naka-lock ang direktang komunikasyon, mga profile ng kandidato, at pagmemensahe. Mag-renew ng iyong taunang sponsor subscription ngayon upang ipagpatuloy ang pag-hire.",
"renew_sub": "Mag-renew ng Subscription",
"expiring_pass_title": "Ang iyong Premium Sponsor Pass ay malapit nang ma-expire!",
"expiring_pass_desc": "Mayroon na lamang {days} araw na natitira. Mag-renew ngayon upang maiwasang mawalan ng access sa 500+ na beripikadong kandidato.",
"renew_now": "Mag-renew Ngayon",
"sub_status": "Status ng Subscription",
"days_left": "Mga Araw na Natitira",
"welcome_back": "Maligayang Pagbabalik",
"welcome_desc_dash": "Direktang mag-hire ng mga kasambahay na sumusunod sa MOHRE nang walang komisyon sa ahente. I-browse ang aming updated na database ng mga kandidatong may OCR passport check.",
"browse_workers": "Mag-browse ng 500+ na Beripikadong Manggagawa",
"sponsor_pass_tier": "Antas ng Sponsor Pass",
"renews": "Magre-renew sa",
"manage_billing": "Pamahalaan ang billing at mga invoice",
"pending_job_offers": "Mga Nakabinbing Alok sa Trabaho",
"direct_recruitment": "Direktang mga panukala sa pag-hire",
"view_hiring": "Tingnan ang proseso ng pag-hire",
"total_hired_workers": "Kabuuang Na-hire na Manggagawa",
"direct_contracts": "Direktang mga kontratang nasimulan",
"track_active_staff": "Subaybayan ang aktibong staff",
"shortlisted_candidates": "Mga Shortlisted na Kandidato",
"bookmark_list": "I-save ang listahan para sa mga interview",
"open_shortlist": "Buksan ang shortlist book",
"discover_insights": "Tuklasin ang mga Insight at Stats sa Merkado",
"dubai_insights": "Mga Pangkalahatang Insight sa Merkado sa Dubai",
"hired_dubai": "Na-hire gamit ang app sa Dubai",
"cooking_care": "Pagluluto, Pag-aalaga, Pagmamaneho",
"top_skills": "Mga Pangunahing Kasanayang Na-hire",
"turnover_rate": "Turnover rate",
"sponsor_activity": "Mga Stat sa Aktibidad ng Iyong Sponsor",
"workers_contacted": "Mga Manggagawang Nakontak",
"secure_hires": "Mga Ligtas na Pag-hire",
"quick_actions": "Mabilisang Aksyon",
"speed_up": "Bilisang ang iyong proseso ng sponsorship.",
"find_nannies": "Maghangad ng Pag-aalaga sa Bata at mga Nanny",
"browse_nannies": "Mag-browse ng mga premium na beripikadong nanny",
"whatsapp_support": "Direktang Suporta sa WhatsApp",
"chat_manager": "Kausapin ang recruitment manager",
"legal_platform": "100% Legal na Platform sa UAE na Walang Ahensya",
"recommended_for_you": "Inirerekomenda para sa Iyo",
"browse_all": "I-browse lahat",
"view_profile": "Tingnan ang Profile",
"no_recommended": "Walang mga inirerekomendang manggagawa sa kasalukuyan. I-update ang mga detalye ng profile.",
"active_shortlist": "Aktibong Shortlist",
"view_book": "Tingnan ang aklat",
"category": "Kategorya",
"availability": "Kakayahang Magtrabaho",
"open_profile": "Buksan ang Profile",
"shortlist_candidates_desc": "I-shortlist ang mga kandidato upang mapaghambing ang kanilang mga dokumento nang magkatabi",
"recent_chats": "Mga Kamakailang Chat",
"all_channels": "Lahat ng channel",
"no_chats": "Walang nahanap na kamakailang chat logs. Maghanap ng mga manggagawa upang simulan ang pag-uusap.",
"charity_drives": "Mga Kawanggawa sa Komunidad",
"live_events": "Mga Live na Kaganapan",
"charity_drive": "Kaganapang Kawanggawa",
"provided_items": "Mga Ipinamahaging Item",
"event_date": "Petsa ng Kaganapan",
"open_maps": "Buksan ang Location Pin sa Google Maps",
"mohre_compliant": "Sumusunod sa UAE Tadbeer at MOHRE",
"mohre_desc": "Ang aming direktang sistema ng kontrata ay awtomatikong umaayon sa mga alituntunin ng Ministri ng Yamang Tao at Emiratisasyon. Ganap na legal, walang bayad sa ahente, kumpletong transparency.",
"visit_mohre": "Bisitahin ang website ng MOHRE UAE",
"my_shortlist": "Aking Shortlist",
"candidates_saved": "Mayroon kang {count} na kandidatong naka-save para sa pagsusuri",
"browse_more": "Mag-browse pa ng mga manggagawa",
"verified": "Na-verify",
"warning": "Babala",
"platform_skills": "Mga Kasanayan sa Platform",
"languages_spoken": "Mga Wikang Sinasalita",
"quick_preview": "Mabilisang Preview",
"compare_candidate": "Ihambing ang Kandidato",
"comparing_active": "Inihahambing ✓",
"message": "Mensahe",
"shortlist_empty": "Walang laman ang iyong shortlist",
"shortlist_empty_desc": "Tuklasin ang mga profile ng kandidato at idaragdag sila sa iyong naka-save na shortlist.",
"find_workers_now": "Magmaghanap ng Manggagawa Ngayon",
"comparing_workers": "Paghahambing ng mga Manggagawa",
"clear_all": "I-clear lahat",
"remove_shortlist": "Alisin sa Shortlist",
"view_full_details": "Tingnan ang Buong Detalye",
"no_bio_provided": "Walang ibinigay na bio details.",
"expectations": "Mga Inaasahan",
"languages": "Mga Wika",
"availability_status_label": "Katayuan ng Availability",
"job_preference": "Kagustuhan sa Trabaho",
"remove_from_shortlist": "Alisin sa shortlist",
"max_compare_alert": "Maaari mong ihambing ang maximum na 3 kandidato.",
"sponsor_pass_billing": "Sponsor Pass at Invoicing",
"subscription_billing_title": "Billing ng Subscription at Mga Invoice - Portal ng Employer",
"recurrent_billing_failed": "Nabigo ang iyong recurrent na billing sa subscription!",
"recurrent_billing_failed_desc": "Nabigo ang pag-renew ng card dahil sa kulang na pondo. Subukan ulit gamit ang PayTabs upang maiwasan ang pagkaka-lockout ng profile.",
"retry_payment_now": "Subukan ang Pagbabayad Ngayon",
"active_plan_pass": "Aktibong Plan Pass",
"renewing_auto_payment_on": "Awtomatikong magre-renew sa pamamagitan ng auto-payment sa",
"simulate_billing_failure": "Simulan ang Billing Failure",
"verified_sponsor_status": "Beripikadong Katayuan ng Sponsor",
"sponsor_pass_updated": "Matagumpay na na-update ang Sponsor Pass! Nairehistro ang transaksyon sa PayTabs.",
"available_subscription_tiers": "Mga Magagamit na Antas ng Subscription",
"available_subscription_tiers_desc": "Mag-upgrade o mag-cancel anumang oras. Lahat ng kontrata ay sumusunod sa mga patnubay ng UAE Tadbeer MOHRE.",
"most_popular_tier": "Pinakasikat na Antas",
"current_active_tier": "Kasalukuyang Aktibong Antas ✓",
"select_plan_tier": "Pumili ng Antas ng Plano",
"billing_payment_receipts": "Mga Resibo ng Pagbabayad sa Billing",
"tax_compliant_invoices": "Mga Invoiceng Sumusunod sa Buwis",
"corporate_details": "Mga Detalye ng Kumpanya",
"update_tax_invoicing": "I-update ang mga opsyon sa tax invoicing.",
"sponsor_email_address": "Email Address ng Sponsor",
"billing_vat_id": "VAT Registry ID ng Invoicing (Opsyonal)",
"save_billing_profile": "I-save ang Profile sa Billing",
"paytabs_secured_checkout": "Secured Checkout ng PayTabs",
"gateway_version": "Payment Gateway v4.0",
"order_description": "Deskripsyon ng Order",
"total_amount": "Kabuuang Halaga",
"cardholder_name": "Pangalan ng May-ari ng Card",
"card_number": "Numero ng Card",
"expiry_date": "Petsa ng Expiry (MM/YY)",
"security_code": "Security Code (CVV)",
"pci_dss_cryptography": "Protektado ng 256-bit PCI DSS Cryptography",
"authorize_payment": "Pahintulutan ang Pagbabayad",
"simulated_billing_failure_triggered": "Na-trigger ang simulated billing failure!",
"simulated_billing_failure_desc": "Hihilingin ngayon ng babala ng system ang mga opsyon sa muling pagsubok sa pagbabayad.",
"payment_approved": "Inaprubahan ang Pagbabayad ng PayTabs!",
"successfully_subscribed_desc": "Matagumpay na naka-subscribe sa {plan}. Agad na na-update ang mga limitasyon sa premium access.",
"invoice_generated": "Nagawa ang Invoice {id}",
"invoice_download_desc": "Matagumpay na na-download ang direktang resibo ng MOHRE Sponsor sa format na PDF.",
"corporate_billing_updated": "Na-update ang mga detalye ng billing ng kumpanya.",
"invalid_card_format": "Maling format ng numero ng card",
"candidates_pipeline": "Mga Kandidato",
"candidates_pipeline_desc": "Pamahalaan ang iyong pipeline ng pangangalap ng mga tauhan",
"total_candidates": "Kabuuang mga Kandidato",
"reviewing": "Sinusuri",
"offer_sent": "Naipadala na ang Alok",
"hired": "Na-hire",
"rejected": "Tinanggihan",
"search_by_name": "Maghanap sa pangalan...",
"candidate_header": "Kandidato",
"selected_header": "Napili",
"category_header": "Kategorya",
"salary_header": "Sahod",
"status_header": "Katayuan",
"actions_header": "Mga Aksyon",
"change_status_label": "Baguhin ang Katayuan",
"no_candidates_found": "Walang nahanap na mga kandidato",
"showing_candidates": "Ipinapakita ang {start} hanggang {end} ng {total} na mga kandidato",
"account_settings": "Mga Setting ng Account",
"profile_employer_portal": "Profile - Portal ng Employer",
"profile_updated_successfully": "Matagumpay na na-update ang profile",
"profile_updated_successfully_desc": "Matagumpay na na-synchronize ang mga kagustuhan ng sponsor ng sambahayan at mga vetted credentials.",
"profile_update_failed": "Bigo sa pag-update ng profile",
"check_form_fields": "Pakisuri ang mga patlang ng form.",
"tab_personal": "Personal",
"tab_security": "Seguridad at Password",
"tab_billing": "Billing at mga Resibo",
"tab_notifications": "Sentro ng Notification",
"emirates_id_vetted": "Na-vet na Emirates ID",
"direct_sponsor_portal": "Direktang Portal ng Sponsor",
"personal_details_header": "Mga personal na detalye",
"personal_details_desc": "Pamahalaan ang bio at mga kredensyal ng sponsor",
"full_sponsor_name": "Buong Pangalan ng Sponsor",
"invoicing_email": "Email sa Invoicing",
"uae_mobile_contact": "Contact sa Mobile sa UAE",
"sponsor_nationality": "Nasyonalidad ng Sponsor",
"select_nationality": "Pumili ng Nasyonalidad",
"uae_national": "UAE National",
"expat_uk_europe": "Expat (UK / Europe)",
"expat_usa_canada": "Expat (USA / Canada)",
"expat_asia_gcc": "Expat (Asia / GCC)",
"family_members_size": "Laki ng mga Kasapi ng Pamilya",
"select_family_size": "Pumili ng Laki ng Pamilya",
"family_1_2": "1-2 Kasapi",
"family_3_4": "3-4 na Kasapi",
"family_5_plus": "5+ na Kasapi",
"accommodation_residence": "Tirahan na Matutuluyan",
"select_accommodation": "Pumili ng Tirahan",
"villa": "Villa",
"penthouse": "Apartment (Penthouse)",
"apartment_1_3": "Apartment (1-3 Bed)",
"city_district_area": "Distrito / Lugar ng Lungsod",
"emirates_id_verification_header": "Pagpapatunay ng Emirates ID",
"emirates_id_verification_desc": "Mga kredensyal sa pagsunod sa regulasyon",
"emirates_id_verified_status": "Na-verify na Emirates ID",
"mohre_guidelines": "Na-vet sa ilalim ng Mga Alituntunin ng MOHRE",
"emirates_id_verified_desc": "Matagumpay na na-verify ang iyong Emirates ID. Aktibo ang iyong account para sa direktang pag-hire.",
"verification_pending_status": "Nakabinbing Pagpapatunay sa Audit",
"audit_queue": "Queue ng Audit",
"verification_pending_desc": "Kasalukuyang sinusuri ang iyong mga pag-upload ng dokumento ng Emirates ID. Karaniwang natatapos ang mga audit sa loob ng 24 oras.",
"verification_required_status": "Kinakailangan ang Pagpapatunay ng Emirates ID",
"action_needed": "Kailangan ng Aksyon",
"verification_required_desc": "Mangyaring mag-upload ng mataas na resolution na kulay na scan ng iyong Emirates ID upang ma-verify ang iyong pagkakakilanlan at i-activate ang buong tampok sa pag-hire.",
"emirates_id_front_side": "Emirates ID (Harapang Bahagi)",
"emirates_id_back_side": "Emirates ID (Likurang Bahagi)",
"uploaded_credentials_scans": "Mga Na-upload na Scan ng Kredensyal",
"view_scan": "Tingnan ang Scan",
"security_password_header": "Seguridad at Password",
"security_password_desc": "Panatilihing secure ang iyong sponsor account",
"current_password": "Kasalukuyang Password",
"new_password": "Bagong Password",
"confirm_new_password": "Kumpirmahin ang Bagong Password",
"current_plan": "Kasalukuyang Plano",
"active_status": "Aktibo",
"next_payment": "Susunod na Pagbabayad",
"recent_transactions": "Mga Kamakailang Transaksyon",
"date_header": "Petsa",
"description_header": "Deskripsyon",
"amount_header": "Halaga",
"receipt_header": "Resibo",
"notification_settings_hub": "Sentro ng mga Setting ng Notification",
"notification_settings_desc": "Pumili kung paano mo gustong makatanggap ng mga alerto",
"email_alerts": "Mga Alerto sa Email",
"email_alerts_desc": "Makatanggap ng mga inirerekomendang manggagawa at mga update sa visa.",
"sms_alerts": "Mga Instant na Resibo sa SMS",
"sms_alerts_desc": "Kumuha ng mga abiso sa SMS para sa mga iskedyul ng interview.",
"push_alerts": "Mga Push Notification",
"push_alerts_desc": "Kumuha ng desktop sound alerts para sa mga bagong direktang mensahe.",
"changes_saved": "Matagumpay na na-save ang mga pagbabago",
"emirates_id_reverification_notice": "Ang ilang mga update ay maaaring mangailangan ng muling pagpapatunay ng Emirates ID.",
"update_settings": "I-update ang mga Setting",
"charity_events_support_drives": "Mga Kaganapang Kawanggawa & Kampanya sa Usaid",
"community_charity_events_sponsor_hub": "Mga Kaganapang Kawanggawa sa Komunidad - Kituo ng Sponsor",
"community_charity_event_posted": "NAI-POST NA ANG CHARITY EVENT NG KOMUNIDAD!",
"community_charity_event_posted_desc": "Agad na nagpadala ng push notification sa lahat ng manggagawa sa Dubai! Matagumpay na nai-schedule ang umagang paalala.",
"dubai_community_support_drives": "Mga Kampanya sa Suporta ng Komunidad sa Dubai",
"free_medical_checks_title": "Libreng Ugnayan sa Kalusugan, Pamamahagi ng Pagkain & mga Serbisyo sa Suporta",
"free_medical_checks_desc": "Nag-oorganisa ng programang suporta? Ibahagi ang mga kampanya ng komunidad nang direkta. Awtomatikong magpapadala ng push notification ang platform sa mga manggagawa, na susundan ng paalala sa umaga ng kaganapan.",
"search_charity_events_placeholder": "Maghanap ng mga kawanggawa & kampanya...",
"post_charity_event": "I-post ang Charity Event",
"broadcast_support_program_desc": "Ipalaganap ang programang suporta, medical camp, o pamamahagi sa komunidad ng mga manggagawa.",
"charity_drive_metadata": "Metadata ng Charity Drive (Suporta sa Dubai)",
"event_time_placeholder": "hal. 9:00 AM - 4:00 PM",
"what_is_provided": "Ano ang Ipinapamahagi",
"provided_items_placeholder": "hal. Libreng Dental Check, Kahon ng Pagkain, mga Kagamitan",
"location_details_pin": "Mga Detalye ng Lokasyon & Pin Link",
"location_details_placeholder": "hal. Al Quoz Community Center, Dubai",
"maps_pin_link_placeholder": "Link ng Google Maps (hal. https://maps.app.goo.gl/xyz)",
"title_label": "Pamagat",
"title_placeholder": "hal. Libreng Dental Checkup ng Emirates Charity",
"event_desc_instructions": "Deskripsyon ng Kaganapan & mga Tagubilin",
"event_desc_placeholder": "Ilagay ang mga detalye ng kawanggawa dito...",
"publish_charity_event": "I-publish ang Charity Event",
"no_announcements_title": "Walang mga Anunsyo",
"no_announcements_desc": "Hindi ka pa nagpo-post ng anumang mga anunsyo",
"community_charity_drive": "KAMPANYANG KAWANGGAWA NG KOMUNIDAD",
"push_reminder_scheduled": "Nai-schedule ang Push & Paalala",
"provided_packages": "Ipinamahaging Packages",
"event_timing": "Oras ng Kaganapan",
"event_location_address": "Address ng Lokasyon ng Kaganapan",
"view_map_location_pin": "Tingnan ang Lokasyon sa Mapa",
"find_vetted_workers": "Maghanap ng mga Vetted na Kasambahay",
"find_workers_platform": "Maghanap ng mga Manggagawa - Platform ng Kasambahay",
"no_middlemen_platform": "Platform na Walang Ahente o Middlemen",
"find_verified_candidates": "Maghanap ng mga Verified na Kandidato",
"connect_vetted_workers_desc": "Agad na makipag-ugnayan sa mga background-checked at vetted na kasambahay sa UAE.",
"search_by_name_skills_bio": "Maghanap ayon sa pangalan, kasanayan, bio (hal. Cooking, Childcare, Gardening, Driving)...",
"default_match": "Default na Tugma",
"salary_low_to_high": "Sahod: Mababa hanggang Mataas",
"salary_high_to_low": "Sahod: Mataas hanggang Mababa",
"rating_high_to_low": "Rating: Mataas hanggang Mababa",
"experience_level": "Antas ng Karanasan",
"reset": "I-reset",
"nationality": "Nasyonalidad",
"select_skills": "Pumili ng mga Kasanayan",
"select_languages": "Pumili ng mga Wika",
"select_visa_status": "Pumili ng Hali ng Visa",
"found_workers_matching": "Nakahanap ng {count} na kasambahay na tumutugma sa iyong paghahanap",
"direct_sponsoring_active": "Aktibo ang Direktang Sponsor ng MOHRE UAE",
"load_more_workers": "Mag-load ng Higit Pang Manggagawa",
"no_candidates_matching": "Walang mga kandidatong tumutugma sa iyong mga filter",
"adjust_filters_desc": "Subukang i-adjust ang iyong limitasyon sa sahod, magdagdag ng mga karagdagdang wika, o palawakin ang mga kagustuhan sa nasyonalidad.",
"reset_filters": "I-reset ang mga Filter",
"comparing_workers_count": "Inihahambing ang mga Manggagawa ({count} sa 3)",
"expected": "Inaasahan",
"region": "Rehiyon",
"visa_transfer": "Paglipat ng Visa",
"medical_status": "Katayuan ng Kalusugan",
"passport_ocr": "OCR ng Pasaporte",
"open_worker_profile": "Buksan ang Profile ng Manggagawa",
"attach_verified_sponsor_docs": "I-attach ang Verified na Dokumento ng Sponsor",
"upload_sponsor_papers_desc": "Mag-upload ng mga papel ng sponsor, kasunduan sa trabaho, o mga paglalarawan ng trabaho upang suriin nang ligtas.",
"select_files_drag": "Pumili ng mga file o i-drag dito",
"max_file_size": "PDF, JPG, PNG (Max 5MB)",
"close": "Isara",
"chat_with_worker": "Makipag-chat kay {name} - Mga Mensahe",
"messages_hub": "Hub ng Mensahe",
"ssl_secure": "SSL SECURE",
"active_now": "Aktibo Ngayon",
"whatsapp_bridge": "Koneksyon sa WhatsApp",
"toggle_context_sidebar": "I-toggle ang Sidebar ng Profile",
"today_realtime_chat": "Ngayong Araw • Realtime na Log ng Chat",
"read": "Nabasang Mensahe",
"type_compliant_message": "Mag-type ng ligtas na mensahe...",
"conversation_messages": "Mga Mensahe ng Kandidato",
"messages_employer_portal": "Mga Mensahe - Portal ng Sponsor",
"search_conversations": "Maghanap ng mga pag-uusap...",
"new_conversation": "Bagong Pag-uusap",
"active_threads": "Mga Aktibong Chat",
"total_conversations": "Kabuuan: {count}",
"no_active_messages": "Walang aktibong mensahe",
"no_active_messages_desc": "Kapag nagpadala ka ng mensahe sa mga manggagawa o nag-iskedyul ng mga panayam, lalabas ang iyong mga chat thread dito.",
"candidate_profile_detail": "Detalye ng Profile ng Kandidato",
"back_to_find_workers": "BUMALIK SA PAGHAHANAP NG MANGGAGAWA",
"share_profile": "Ibahagi ang Profile",
"report_worker": "Iulat ang Manggagawa",
"sponsorship_details": "Mga Detalye ng Sponsorship",
"salary_expectations": "Inaasahang Sahod",
"work_experience": "Karanasan sa Trabaho",
"emirates_id_vetting": "Pagsusuri ng Emirates ID",
"medical_health_test": "Medikal at Kalusugan na Pagsusuri",
"passed_certified": "PASADO AT VERIFIED",
"professional_summary": "Propesyonal na Buod",
"verified_skills_competencies": "Mga Kasanayan at Kakayahang Na-verify",
"verified_legal_documents": "Mga Na-verify na Legal na Dokumento (MOHRE UAE Vetted)",
"passport_verified": "Pasaporte (Na-verify)",
"click_zoom": "I-click para i-zoom",
"document_id": "ID ng Dokumento",
"issue": "Araw ng Paglabas",
"expiry": "Araw ng Pagkapaso",
"ocr_match": "Tugma sa OCR",
"emirates_id_pdpl": "Emirates ID (PDPL Compliant)",
"scan_purged": "Scan ay Tinanggal na",
"uae_pdpl_compliant": "Sumusunod sa UAE PDPL",
"verification_type": "Uri ng Pag-verify",
"physical_scan_storage": "Imbakan ng Pisikal na Scan",
"permanently_purged": "Permanenteng Tinanggal",
"entry_visa_verified": "Entry Visa (Na-verify)",
"visa_category": "Kategorya ng Visa",
"vetting_status": "Katayuan ng Pagsusuri",
"transfer_required": "Kailangang Ilipat",
"needs_regularization": "Kailangang Ayusin ang Visa",
"clear_records": "Malinis ang Rekord",
"sponsor_reviews_ratings": "Mga Review at Star Rating ng Sponsor",
"ratings_policy_desc": "Ang mga rating ay maaari lamang mai-post ng mga na-verify na sponsor na nakakumpleto ng verified na direktang pag-hire.",
"post_trust_review": "Mag-post ng Review ng Tiwala",
"similar_recommended_workers": "Katulad na Inirerekomendang Manggagawa",
"direct_sponsoring_finalized": "Direktang Sponsorship ay Tapos Na!",
"hired_stage4_desc": "Matagumpay na minarkahan si {name} bilang Hired sa ilalim ng iyong sponsorship! Ang direktang pagtutugma na ito ay sumusunod sa Stage 4 ng aming UAE MOHRE zero-middlemen flow.",
"next_step_stage5": "Susunod na Hakbang: Stage 5 Review Pagkatapos ng Pag-hire",
"post_hire_review_desc": "Tulungan ang komunidad sa UAE na mag-hire nang ligtas sa pamamagitan ng pag-post ng isang hindi kilalang review na naglalarawan sa childcare, cooking, driving, o domestic skills ni {name}.",
"leave_trust_review": "Mag-iwan ng Review ng Tiwala",
"back_to_directory": "Bumalik sa Direktoryo ng Manggagawa",
"report_abuse_title": "Iulat ang Pag-abuso sa Pagsusuri / Paglabag sa Mga Tuntunin",
"report_abuse_desc": "Pinapanatili namin ang zero-tolerance para sa mga pekeng dokumento, mga independiyenteng recruiter na nagbebenta ng cash, o maling detalye ng pakikipag-ugnayan.",
"reason": "Dahilan",
"select_reason": "Pumili ng dahilan...",
"reason_fees": "Humingi ng bayad sa komisyon sa pag-hire ang manggagawa / ahente",
"reason_profile": "Ang mga detalye ng profile / pasaporte ay hindi tumutugma sa aktwal na tao",
"reason_contact": "Hindi wastong numero ng telepono / hindi maabot",
"reason_other": "Iba pang paglabag sa pagsunod",
"additional_context": "Karagdagang detalye ng konteksto",
"provide_specifics": "Magbigay ng detalyadong specifics ng nangyari...",
"cancel": "Kanselahin",
"submit_report": "Isumite the Ulat ng Pagsunod",
"submit_verified_review": "Isumite ang Na-verify na Review sa Pagganap",
"review_help_desc": "Ang iyong puna ay tumutulong sa iba pang mga sponsor na gumawa ng ligtas at direktang mga desisyon sa pag-hire.",
"star_rating": "Star Rating",
"share_experience": "Ibahagi ang Iyong Karanasan",
"review_textarea_placeholder": "Sabihin sa iba pang mga sponsor ang tungkol sa mga kasanayan sa childcare, paglilinis, estilo ng pagluluto, kaligtasan sa pagmamaneho, atbp...",
"post_trust_review_btn": "Mag-post ng Review ng Tiwala",
"start_direct_chat": "Magsimula ng Direktang Chat",
"mark_hired": "Minarkahang Hired",
"selected": "Napili",
"total": "Kabuuan",
"candidate_messages": "Mga Mensahe ng Kandidato",
"search_conversations_placeholder": "Maghanap ng mga pag-uusap...",
"total_count": "Kabuuan: {count}",
"chat_with": "Makipag-chat kay",
"today_realtime_chat_logs": "Ngayong Araw • Realtime na Log ng Chat",
"just_now": "Ngayon Lang",
"direct_push_sent": "Direktang Mobile Push Notification ay naipadala na!",
"popped_up_instantly_desc": "Agad na lumitaw sa mobile device ni {name}.",
"auto_reply_text": "Salamat sa iyong tugon! Sinuri ko ang iyong alok na panukala at inaabangan ko ang ating panayam sa video.",
"new_message_from": "Bagong mensahe mula kay {name}!",
"document_attached": "Matagumpay na nailakip ang dokumento!",
"document_attached_msg": "Nailakip ang Dokumento",
"today": "Ngayong Araw",
"chip_interview": "Available ka ba para sa isang panayam sa video ngayon?",
"chip_salary": "Magkano ang iyong inaasahang huling sahod?",
"chip_visa": "Maaari mo bang ilipat ang iyong visa kaagad?",
"type_message_placeholder": "Mag-type ng ligtas na mensahe...",
"compliance_profile": "Profile ng Pagsunod",
"transferable": "Maaaring Ilipat",
"cleared": "Ligtas / Pasado",
"attach_sponsor_documents": "I-attach ang Verified na Dokumento ng Sponsor",
"attach_documents_desc": "Mag-upload ng mga papel ng sponsor, kasunduan sa trabaho, o mga paglalarawan ng trabaho upang suriin nang ligtas.",
"sponsor_reviews_star_ratings": "Mga Review at Star Rating ng Sponsor",
"reviews_posted_by_sponsors_desc": "Ang mga rating ay maaari lamang mai-post ng mga na-verify na sponsor na nakakumpleto ng verified na direktang pag-hire.",
"aed": "AED",
"mo": "buwan",
"hired_under_sponsorship_desc": "Matagumpay na minarkahan si {name} bilang Hired sa ilalim ng iyong sponsorship! Ang direktang pagtutugma na ito ay sumusunod sa Stage 4 ng aming UAE MOHRE zero-middlemen flow.",
"next_step_post_hire_review": "Susunod na Hakbang: Stage 5 Review Pagkatapos ng Pag-hire",
"help_community_post_review": "Tulungan ang komunidad sa UAE na mag-hire nang ligtas sa pamamagitan ng pag-post ng isang hindi kilalang review na naglalarawan sa childcare, cooking, driving, o domestic skills ni {name}.",
"back_to_worker_directory": "Bumalik sa Direktoryo ng Manggagawa",
"report_abuse_violation": "I-report ang Pag-abuso sa Pagsusuri / Paglabag sa Mga Tuntunin",
"zero_tolerance_abuse_desc": "Pinapanatili namin ang zero-tolerance para sa mga pekeng dokumento, mga independiyenteng recruiter na nagbebenta ng cash, o maling detalye ng pakikipag-ugnayan.",
"additional_context_details": "Karagdagang detalye ng konteksto",
"provide_specifics_placeholder": "Magbigay ng detalyadong specifics ng nangyari...",
"submit_compliance_report": "Isumite ang Ulat ng Pagsunod",
"submit_performance_review": "Isumite ang Na-verify na Review sa Pagganap",
"feedback_helps_sponsors_desc": "Ang iyong puna ay tumutulong sa iba pang mga sponsor na gumawa ng ligtas at direktang mga desisyon sa pag-hire.",
"share_your_experience": "Ibahagi ang Iyong Karanasan",
"share_experience_placeholder": "Sabihin sa iba pang mga sponsor ang tungkol sa mga kasanayan sa childcare, paglilinis, estilo ng pagluluto, kaligtasan sa pagmamaneho, atbp...",
"post_trust_review_action": "Mag-post ng Review ng Tiwala"
}

View File

@ -0,0 +1,50 @@
import React, { createContext, useContext, useState, useEffect } from 'react';
// Import translation JSON files directly
import en from '../lang/en.json';
import hi from '../lang/hi.json';
import sw from '../lang/sw.json';
import tl from '../lang/tl.json';
import ta from '../lang/ta.json';
const LanguageContext = createContext();
const translations = { en, hi, sw, tl, ta };
export const languages = [
{ code: 'en', name: 'English', nativeName: 'English', flag: '🇬🇧' },
{ code: 'hi', name: 'Hindi', nativeName: 'हिन्दी', flag: '🇮🇳' },
{ code: 'sw', name: 'Swahili', nativeName: 'Kiswahili', flag: '🇰🇪' },
{ code: 'tl', name: 'Tagalog', nativeName: 'Tagalog', flag: '🇵🇭' },
{ code: 'ta', name: 'Tamil', nativeName: 'தமிழ்', flag: '🇮🇳' }
];
export function LanguageProvider({ children }) {
const [locale, setLocale] = useState(() => {
return localStorage.getItem('app_locale') || 'en';
});
useEffect(() => {
localStorage.setItem('app_locale', locale);
document.documentElement.lang = locale;
}, [locale]);
const t = (key, fallback = '') => {
const langData = translations[locale] || translations['en'];
return langData[key] || translations['en'][key] || fallback || key;
};
return (
<LanguageContext.Provider value={{ locale, setLocale, t, languages }}>
{children}
</LanguageContext.Provider>
);
}
export function useTranslation() {
const context = useContext(LanguageContext);
if (!context) {
throw new Error('useTranslation must be used within a LanguageProvider');
}
return context;
}

View File

@ -81,4 +81,10 @@
Route::get('/employers/announcements', [EmployerAnnouncementController::class, 'getAnnouncements']);
Route::post('/employers/announcements', [EmployerAnnouncementController::class, 'createAnnouncement']);
Route::delete('/employers/announcements/{id}', [EmployerAnnouncementController::class, 'deleteAnnouncement']);
// Worker and Candidate Pipeline Management
Route::get('/employers/workers', [\App\Http\Controllers\Api\EmployerWorkerController::class, 'getWorkers']);
Route::get('/employers/candidates', [\App\Http\Controllers\Api\EmployerWorkerController::class, 'getCandidates']);
Route::post('/employers/candidates/{id}/hire', [\App\Http\Controllers\Api\EmployerWorkerController::class, 'hireCandidate']);
Route::post('/employers/candidates/hire', [\App\Http\Controllers\Api\EmployerWorkerController::class, 'hireCandidate']);
});

View File

@ -110,6 +110,7 @@
return Inertia::render('Employer/Hiring/Confirm', ['worker' => $workerData]);
})->name('employer.hiring.confirm');
Route::post('/workers/{id}/hire', [\App\Http\Controllers\Employer\WorkerController::class, 'sendOffer'])->name('employer.workers.send-offer');
Route::post('/workers/{id}/mark-hired', [\App\Http\Controllers\Employer\WorkerController::class, 'markHired'])->name('employer.workers.mark-hired');
Route::get('/workers/{id}/hire/success', function ($id) {
$worker = \App\Models\Worker::findOrFail($id);
$workerData = [

View File

@ -1,5 +1,6 @@
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';
import { bunny } from 'laravel-vite-plugin/fonts';
import tailwindcss from '@tailwindcss/vite';
@ -14,9 +15,11 @@ export default defineConfig({
}),
],
}),
react(),
tailwindcss(),
],
server: {
host: 'localhost',
watch: {
ignored: ['**/storage/framework/views/**'],
},