import React, { useState, useEffect, useRef } from 'react';
import { initializeApp } from 'firebase/app';
import {
getAuth,
signInWithEmailAndPassword,
createUserWithEmailAndPassword,
signOut,
onAuthStateChanged,
signInWithCustomToken,
signInAnonymously
} from 'firebase/auth';
import {
getFirestore,
collection,
addDoc,
query,
onSnapshot,
orderBy,
serverTimestamp,
doc,
deleteDoc,
updateDoc,
where,
getDocs,
limit,
setDoc,
writeBatch
} from 'firebase/firestore';
import {
Building2, MapPin, Briefcase, User, Phone, Mail, Menu, X, PlusCircle,
Search, Hammer, HardHat, CheckCircle, LogOut, ChevronRight, Globe,
FileText, CreditCard, Plane, Download, Bitcoin, Wallet, Landmark,
Heart, Target, Users, ShieldCheck, QrCode, Calendar, Lock, Filter,
MessageCircle, Settings, Send, Headphones, Bell, Info, FileQuestion,
GraduationCap, Award, Database, RefreshCw, EyeOff
} from 'lucide-react';
// --- Firebase Configuration & Initialization ---
const firebaseConfig = JSON.parse(__firebase_config);
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
const appId = typeof __app_id !== 'undefined' ? __app_id : 'default-app-id';
// --- Helper Components ---
const AdPlaceholder = ({ format = "horizontal" }) => {
return (
Advertisement Space
Google AdSense / Sponsorship
);
};
const NewsTicker = ({ text }) => {
if (!text) return null;
return (
);
};
const ChatRoom = ({ roomId, user, title, type = 'public' }) => {
const [messages, setMessages] = useState([]);
const [newMessage, setNewMessage] = useState('');
const dummy = useRef();
useEffect(() => {
if (!user) return; // Guard against unauthenticated queries
const q = query(
collection(db, 'artifacts', appId, 'public', 'data', `chat_${roomId}`),
orderBy('createdAt', 'asc')
);
const unsubscribe = onSnapshot(q, (snapshot) => {
setMessages(snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })));
setTimeout(() => dummy.current?.scrollIntoView({ behavior: 'smooth' }), 100);
});
return () => unsubscribe();
}, [roomId, user]);
const sendMessage = async (e) => {
e.preventDefault();
if (!newMessage.trim() || !user) return;
const msgData = {
text: newMessage,
createdAt: serverTimestamp(),
uid: user.uid,
displayName: user.email.split('@')[0],
isAdmin: user.email === 'admin@alwatan.com'
};
await addDoc(collection(db, 'artifacts', appId, 'public', 'data', `chat_${roomId}`), msgData);
if (type === 'support') {
const threadId = roomId.replace('support_', '');
await setDoc(doc(db, 'artifacts', appId, 'public', 'data', 'support_threads', threadId), {
lastMessage: newMessage,
updatedAt: serverTimestamp(),
userEmail: user.email,
userId: user.uid,
hasUnread: true
}, { merge: true });
}
setNewMessage('');
};
return (
{type === 'support' ? : }
{title}
{messages.map(msg => (
{msg.isAdmin ? 'Support Team' : msg.displayName}
{msg.text}
))}
);
};
// --- Main Components ---
// 1. Navigation Bar
const Navbar = ({ user, setView, view, handleLogout, settings }) => {
const [isOpen, setIsOpen] = useState(false);
const isUserLoggedIn = user && !user.isAnonymous;
const displayName = user?.email ? user.email.split('@')[0] : 'Guest';
const isAdmin = user?.email === 'admin@alwatan.com';
return (
<>
setView('home')}>
AL-WATAN
International Group
setView('home')} className={`px-3 py-2 rounded-md text-sm font-medium hover:text-amber-500 transition ${view === 'home' ? 'text-amber-500' : 'text-gray-300'}`}>Home
setView('jobs')} className={`px-3 py-2 rounded-md text-sm font-medium hover:text-amber-500 transition ${view === 'jobs' ? 'text-amber-500' : 'text-gray-300'}`}>Browse Jobs
setView('services')} className={`px-3 py-2 rounded-md text-sm font-medium hover:text-amber-500 transition ${view === 'services' ? 'text-amber-500' : 'text-gray-300'}`}>Offer Letter
setView('institute')} className={`px-3 py-2 rounded-md text-sm font-medium hover:text-amber-500 transition ${view === 'institute' ? 'text-amber-500' : 'text-gray-300'}`}>Institute
setView('verify')} className={`px-3 py-2 rounded-md text-sm font-medium hover:text-amber-500 transition ${view === 'verify' ? 'text-amber-500' : 'text-gray-300'}`}>Verify
setView('support')} className={`px-3 py-2 rounded-md text-sm font-medium hover:text-amber-500 transition ${view === 'support' ? 'text-amber-500' : 'text-gray-300'}`}>Support
{isAdmin && (
setView('admin')} className="bg-red-600 text-white px-3 py-2 rounded-md text-sm font-bold animate-pulse">
Admin
)}
{isUserLoggedIn ? (
User: {displayName}
) : (
setView('login')} className="bg-amber-600 hover:bg-amber-700 text-white px-4 py-2 rounded-md text-sm font-medium transition ml-4">
Login
)}
setIsOpen(!isOpen)} className="bg-slate-800 p-2 rounded-md text-gray-400 hover:text-white focus:outline-none">
{isOpen ? : }
{isOpen && (
{setView('home'); setIsOpen(false)}} className="block w-full text-left px-3 py-2 rounded-md text-base font-medium text-white hover:bg-slate-700">Home
{setView('jobs'); setIsOpen(false)}} className="block w-full text-left px-3 py-2 rounded-md text-base font-medium text-white hover:bg-slate-700">Jobs
{setView('institute'); setIsOpen(false)}} className="block w-full text-left px-3 py-2 rounded-md text-base font-medium text-white hover:bg-slate-700">Institute
{setView('verify'); setIsOpen(false)}} className="block w-full text-left px-3 py-2 rounded-md text-base font-medium text-white hover:bg-slate-700">Verify
{isUserLoggedIn ? (
Logout
) : (
{setView('login'); setIsOpen(false)}} className="block w-full text-left px-3 py-2 rounded-md text-base font-medium text-amber-500 hover:bg-slate-700">Login
)}
)}
>
);
};
// 2. Home Page
const Home = ({ setView, settings }) => {
const defaultBanner = 'https://images.unsplash.com/photo-1521737604893-d14cc237f11d?ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80';
return (
{/* Hero Section */}
Your Gateway to a Brighter Future
We process dreams, not just visas. Join thousands who found success with Al-Watan.
setView('jobs')} className="bg-amber-600 hover:bg-amber-700 text-white px-8 py-4 rounded-lg font-bold transition transform hover:scale-105 shadow-lg flex items-center justify-center text-lg">
Find a Job
setView('institute')} className="bg-white hover:bg-gray-100 text-slate-900 px-8 py-4 rounded-lg font-bold transition transform hover:scale-105 shadow-lg flex items-center justify-center text-lg">
Get Certified
Our Mission
Empowering humanity by eradicating unemployment and building a world of equal opportunities for everyone, everywhere.
setView('mission')} className="mt-6 text-amber-600 font-bold hover:underline">Read Full Mission
)};
// 3. Technical Institute
const TechnicalInstitute = ({ user, setView }) => {
const [formData, setFormData] = useState({ fullName: '', trade: '', experience: '', mobile: '', dob: '' });
const [isSubmitting, setIsSubmitting] = useState(false);
const [submittedId, setSubmittedId] = useState(null);
const handleSubmit = async (e) => {
e.preventDefault();
if (!user || user.isAnonymous) return alert("Please Sign In first.");
if (!formData.dob) return alert("Date of Birth is required for verification.");
setIsSubmitting(true);
try {
const docRef = await addDoc(collection(db, 'artifacts', appId, 'public', 'data', 'institute_applications'), {
...formData,
userId: user.uid,
email: user.email,
status: 'Pending',
createdAt: serverTimestamp()
});
setSubmittedId(docRef.id);
} catch (error) {
alert("Error submitting application.");
}
setIsSubmitting(false);
};
if (submittedId) return Application Submitted! Save your Reference ID for verification:
{submittedId}
setView('home')} className="mt-6 bg-slate-900 text-white px-6 py-2 rounded">Back to Home ;
return (
Al-Watan Technical Institute
Convert your Experience into a Recognized Degree.
RPL Program
Do you have the skills but lack the certificate?
Through our Recognition of Prior Learning (RPL) program, professionals like Electricians, Plumbers, Mechanics, and IT specialists can get certified based on their practical experience.
Benefits
Valid for Visas
Higher Salary Potential
Global Recognition
Apply for Certification
);
};
// 4. Admin Dashboard (Updated with Admin Setup and Massive Demo)
const AdminDashboard = ({ user, settings }) => {
const [activeTab, setActiveTab] = useState('apps');
const [apps, setApps] = useState([]);
const [instApps, setInstApps] = useState([]);
const [newBanner, setNewBanner] = useState(settings?.bannerUrl || '');
const [newTicker, setNewTicker] = useState(settings?.newsTicker || '');
const [isGenerating, setIsGenerating] = useState(false);
useEffect(() => {
if (!user || user?.email !== 'admin@alwatan.com') return;
const q1 = query(collection(db, 'artifacts', appId, 'public', 'data', 'applications'), orderBy('createdAt', 'desc'));
const unsub1 = onSnapshot(q1, (s) => setApps(s.docs.map(d => ({id: d.id, ...d.data()}))));
const q2 = query(collection(db, 'artifacts', appId, 'public', 'data', 'institute_applications'), orderBy('createdAt', 'desc'));
const unsub2 = onSnapshot(q2, (s) => setInstApps(s.docs.map(d => ({id: d.id, ...d.data()}))));
return () => { unsub1(); unsub2(); }
}, [user]);
const saveSettings = async () => {
await setDoc(doc(db, 'artifacts', appId, 'public', 'data', 'settings', 'config'), { bannerUrl: newBanner, newsTicker: newTicker, updatedAt: serverTimestamp() });
alert("Settings Saved!");
};
const updateStatus = async (collectionName, id, status) => {
await updateDoc(doc(db, 'artifacts', appId, 'public', 'data', collectionName, id), { status, approvedAt: status === 'Approved' ? serverTimestamp() : null });
};
const createAdminAccount = async () => {
try {
await createUserWithEmailAndPassword(auth, 'admin@alwatan.com', '125412');
alert("Admin account created! Please login.");
} catch (e) {
alert("Could not create account (Maybe already exists): " + e.message);
}
};
const generateMassiveDemo = async () => {
if (!window.confirm("Generate Global Jobs? This will add realistic jobs visible to everyone.")) return;
setIsGenerating(true);
try {
const batch = writeBatch(db);
const jobTitles = ["Civil Engineer", "Software Engineer", "Nurse", "Accountant", "Project Manager", "Electrician", "Driver", "Chef", "Teacher", "Sales Manager", "Marketing Specialist", "Mechanical Engineer", "Safety Officer", "Receptionist", "Data Analyst"];
const countries = ["USA", "UK", "Canada", "Australia", "Germany", "Saudi Arabia", "UAE", "Qatar", "Kuwait", "Oman", "Bahrain", "Poland", "France", "Italy", "Japan", "Singapore", "Malaysia"];
const cities = {
"USA": ["New York", "Texas", "California"],
"UK": ["London", "Manchester", "Birmingham"],
"Canada": ["Toronto", "Vancouver", "Montreal"],
"Saudi Arabia": ["Riyadh", "Jeddah", "Dammam"],
"UAE": ["Dubai", "Abu Dhabi", "Sharjah"],
};
const categories = ["Construction", "IT", "Medical", "Finance", "Management", "Skilled Trades", "Transportation", "Hospitality", "Education", "Sales", "Marketing", "Engineering", "Safety", "Admin"];
// Generate 50 realistic jobs
for(let i=0; i<50; i++) {
const ref = doc(collection(db, 'artifacts', appId, 'public', 'data', 'jobs'));
const country = countries[Math.floor(Math.random() * countries.length)];
const cityList = cities[country] || ["Capital City", "Major City"];
const location = cityList[Math.floor(Math.random() * cityList.length)];
const title = jobTitles[Math.floor(Math.random() * jobTitles.length)];
const category = categories[Math.floor(Math.random() * categories.length)];
batch.set(ref, {
title: title,
country: country,
location: location,
category: category,
gender: Math.random() > 0.5 ? 'Any' : (Math.random() > 0.5 ? 'Male' : 'Female'),
type: 'Full-time',
description: `We are hiring a skilled ${title} for our branch in ${location}, ${country}. Competitive salary and visa sponsorship available.`,
contactEmail: `hr@${country.toLowerCase().replace(/\s/g,'')}-jobs.com`,
isHidden: false, // PUBLICLY VISIBLE
createdAt: serverTimestamp()
});
}
await batch.commit();
alert("Success! 50 Global Jobs added to Public Database.");
} catch (e) {
alert("Error: " + e.message);
}
setIsGenerating(false);
};
// Allow non-admins to see "Create Admin" button if they are anonymous, for setup purposes
if (user?.email !== 'admin@alwatan.com') {
return (
Access Denied
You must be logged in as admin@alwatan.com
Setup Admin Account (125412)
);
}
return (
Admin Dashboard
setActiveTab('apps')} className={`px-4 py-2 rounded ${activeTab==='apps'?'bg-slate-900 text-white':'bg-white'}`}>Job Apps
setActiveTab('institute')} className={`px-4 py-2 rounded ${activeTab==='institute'?'bg-slate-900 text-white':'bg-white'}`}>Institute Apps
setActiveTab('settings')} className={`px-4 py-2 rounded ${activeTab==='settings'?'bg-slate-900 text-white':'bg-white'}`}>Settings
{isGenerating ? : }
Generate Global Jobs (Public)
{activeTab === 'settings' && (
Website Configuration
setNewBanner(e.target.value)} placeholder="Banner URL" className="w-full border p-2"/>
setNewTicker(e.target.value)} placeholder="Ticker Text" className="w-full border p-2"/>
Save Changes
)}
{activeTab === 'apps' && (
Job Offer Applications
{apps.map(a=>
{a.fullName}
{a.email} | {a.country}
{a.status} {a.status==='Pending'&&updateStatus('applications', a.id, 'Approved')} className="bg-green-500 text-white px-2 py-1 rounded text-xs">Approve }
)}
)}
{activeTab === 'institute' && (
Institute Certification Requests
{instApps.map(a=>
{a.fullName}
{a.trade} | Exp: {a.experience} yrs
{a.status} {a.status==='Pending'&&updateStatus('institute_applications', a.id, 'Approved')} className="bg-green-500 text-white px-2 py-1 rounded text-xs">Approve }
)}
{instApps.length === 0 &&
No institute applications.
}
)}
);
};
// 5. Verification (Updated to support Certificates)
const Verification = () => {
const [step, setStep] = useState('input');
const [formData, setFormData] = useState({ id: '', email: '', dob: '' });
const [docData, setDocData] = useState(null);
const [docType, setDocType] = useState(null);
const [error, setError] = useState('');
const handleVerify = async (e) => {
e.preventDefault();
setStep('loading'); setError('');
try {
// Check Offer Letters
let q = query(collection(db, 'artifacts', appId, 'public', 'data', 'applications'), where('__name__', '==', formData.id));
let snap = await getDocs(q);
let found = null;
let type = 'offer';
snap.forEach(d => { if(d.id === formData.id) found = d.data(); });
// If not found, check Institute Applications
if (!found) {
q = query(collection(db, 'artifacts', appId, 'public', 'data', 'institute_applications'), where('__name__', '==', formData.id));
snap = await getDocs(q);
snap.forEach(d => { if(d.id === formData.id) found = d.data(); });
if (found) type = 'certificate';
}
if (!found) { setError("ID not found."); setStep('input'); return; }
if (found.email.toLowerCase() !== formData.email.toLowerCase() || found.dob !== formData.dob) { setError("Security Check Failed."); setStep('input'); return; }
if (found.status !== 'Approved') { setError(`Document status is ${found.status}.`); setStep('input'); return; }
setDocData({ id: formData.id, ...found });
setDocType(type);
setStep('result');
} catch (err) { setError("System Error."); setStep('input'); }
};
if (step === 'result' && docData) {
if (docType === 'certificate') {
return (
Certificate of Competency
Al-Watan Technical Institute
This is to certify that
{docData.fullName}
Has successfully demonstrated professional competence in the trade of
{docData.trade}
Based on Recognition of Prior Learning (RPL) Assessment
{docData.id}
Scan to Verify
AWTI OFFICIAL SEAL
Director of Certification
This certificate is electronically generated and can be verified online.
);
}
return (
Al-Watan International Group
Global Head Office
London, United Kingdom
Date: {new Date().toLocaleDateString()} | Ref: {docData.id.substring(0,8).toUpperCase()}
To: {docData.fullName}
Subject: EMPLOYMENT OFFER LETTER
Dear {docData.fullName},
We are pleased to confirm that Al-Watan International Group has approved your application for employment in {docData.country} .
{docData.id}
Hammad Bin Yousaf
Chairman & CEO
);
}
return (
Document Verification
Verify Offer Letters & Certificates
{error &&
{error}
}
);
};
// 6. Other Components (Privacy, Jobs, etc.)
const PrivacyPolicy = () => Privacy Policy We respect your privacy.
;
const JobPortal = ({ user, setView }) => {
const [jobs, setJobs] = useState([]);
const [openCommunity, setOpenCommunity] = useState(null);
const [filterCountry, setFilterCountry] = useState('All');
const [filterCategory, setFilterCategory] = useState('All');
const [showPostModal, setShowPostModal] = useState(false);
const [newJob, setNewJob] = useState({ title: '', country: 'Saudi Arabia', location: '', category: 'Construction', gender: 'Any', type: 'Full-time', description: '', contactEmail: '' });
const isAdmin = user?.email === 'admin@alwatan.com';
const canPostJob = user && !user.isAnonymous; // Kept as general user can post, but typically only admin
useEffect(() => {
if (!user) return; // Guard for permission denied
const q = query(collection(db, 'artifacts', appId, 'public', 'data', 'jobs'), orderBy('createdAt', 'desc'));
const unsubscribe = onSnapshot(q,
(s) => setJobs(s.docs.map(d => ({id: d.id, ...d.data()}))),
(err) => console.error("Error", err)
);
return () => unsubscribe();
}, [user]);
const handlePostJob = async (e) => {
e.preventDefault();
await addDoc(collection(db, 'artifacts', appId, 'public', 'data', 'jobs'), { ...newJob, createdAt: serverTimestamp(), employerId: user.uid });
setShowPostModal(false);
};
const filteredJobs = jobs.filter(job => {
const matchCountry = filterCountry === 'All' || job.country === filterCountry;
const matchCat = filterCategory === 'All' || job.category === filterCategory;
// Public sees ALL jobs (including newly generated ones which are not hidden)
// Hidden field logic removed/ignored for mass jobs as requested "job public ko show hon"
// But respecting isHidden if manually set for drafts
const matchHidden = !job.isHidden;
return matchCountry && matchCat && matchHidden;
});
return (
Job Listings
{canPostJob && (
setShowPostModal(true)} className="bg-amber-600 text-white px-4 py-2 rounded flex items-center shadow-lg"> Post Job
)}
setFilterCountry(e.target.value)} className="w-full border p-2 rounded">All Countries Saudi Arabia UAE UK
setFilterCategory(e.target.value)} className="w-full border p-2 rounded">All Categories Construction IT
{filteredJobs.length === 0 &&
No active jobs found.
}
{filteredJobs.map((job, index) => (
{index > 0 && index % 3 === 0 && }
{job.title}
{job.country}
{job.location}
{job.category}
{job.gender || 'Any'}
{job.description}
Apply via Email
setOpenCommunity(job)} className="flex-1 bg-green-600 hover:bg-green-700 text-white py-2 rounded text-center text-sm flex items-center justify-center transition"> Job Community
))}
Filter Jobs
Location setFilterCountry(e.target.value)} className="w-full border p-2 rounded bg-gray-50">Global (All) Saudi Arabia UAE Qatar United Kingdom Canada USA
Sector setFilterCategory(e.target.value)} className="w-full border p-2 rounded bg-gray-50">All Sectors Construction IT & Tech Healthcare Education Oil & Gas
Need a Visa?
Get your official offer letter processed today.
setView('services')} className="w-full bg-amber-600 text-white py-2 rounded text-sm font-bold hover:bg-amber-700">Start Process
{openCommunity && (
setOpenCommunity(null)} className="absolute top-3 right-3 text-white bg-red-500 rounded-full p-1 z-10 hover:bg-red-600">
)}
{showPostModal && (
Post a Job setShowPostModal(false)}> )}
);
};
const OfferLetterService = ({ user, setView }) => {
const [country, setCountry] = useState('Saudi Arabia');
const [isSubmitting, setIsSubmitting] = useState(false);
const [dob, setDob] = useState('');
const [submittedId, setSubmittedId] = useState(null);
const countries = ['Saudi Arabia', 'UAE', 'Qatar', 'United Kingdom', 'Canada', 'Poland', 'New Zealand', 'Australia', 'USA', 'Germany'];
const handleSubmit = async (e) => {
e.preventDefault();
if (!user || user.isAnonymous) return alert("Please Sign In.");
if (!dob) return alert("Date of Birth required.");
setIsSubmitting(true);
try {
const docRef = await addDoc(collection(db, 'artifacts', appId, 'public', 'data', 'applications'), {
userId: user.uid, email: user.email, fullName: e.target.elements.fullName.value,
country, fee: 'Free', dob, paymentMethod: 'AdSupported', status: 'Pending', createdAt: serverTimestamp()
});
setSubmittedId(docRef.id); setIsSubmitting(false);
} catch { alert("Failed"); setIsSubmitting(false); }
};
if (submittedId) return Application Submitted! ID: {submittedId}
setView('home')} className="mt-4 bg-slate-900 text-white px-4 py-2 rounded">Home ;
return (
);
};
const SupportPage = ({ user }) => {
const [selectedThread, setSelectedThread] = useState(null);
const [threads, setThreads] = useState([]);
const isAdmin = user?.email === 'admin@alwatan.com';
useEffect(() => {
if (!isAdmin) return;
const q = query(collection(db, 'artifacts', appId, 'public', 'data', 'support_threads'), orderBy('updatedAt', 'desc'));
const unsub = onSnapshot(q, (s) => setThreads(s.docs.map(d => ({id: d.id, ...d.data()}))));
return () => unsub();
}, [isAdmin]);
if (!user || user.isAnonymous) return Please login to chat with support.
;
if (isAdmin) {
return (
Inbox
{threads.map(t => (
setSelectedThread(t)} className={`p-4 border-b cursor-pointer ${selectedThread?.id===t.id?'bg-amber-100':''}`}>
{t.userEmail}
))}
{selectedThread ?
:
Select Chat
}
);
}
return ;
};
const Auth = ({ setView }) => {
const [email, setEmail] = useState(''); const [pass, setPass] = useState('');
return
};
const Mission = () => Our Mission To serve humanity.
;
// --- Main App ---
const App = () => {
const [user, setUser] = useState(null);
const [view, setView] = useState('home');
const [settings, setSettings] = useState(null);
useEffect(() => {
const initAuth = async () => {
if (typeof __initial_auth_token !== 'undefined' && __initial_auth_token) {
await signInWithCustomToken(auth, __initial_auth_token);
} else {
await signInAnonymously(auth);
}
};
initAuth();
const unsubscribe = onAuthStateChanged(auth, setUser);
return () => unsubscribe();
}, []);
// Settings listener in separate useEffect to respect user auth state if needed, though settings are public
useEffect(() => {
if (!user) return;
const unsubSettings = onSnapshot(doc(db, 'artifacts', appId, 'public', 'data', 'settings', 'config'), (doc) => { if(doc.exists()) setSettings(doc.data()); });
return () => unsubSettings();
}, [user]);
const handleLogout = async () => { await signOut(auth); setView('home'); };
return (
{view === 'home' && }
{view === 'mission' && }
{view === 'jobs' && }
{view === 'services' && }
{view === 'institute' && }
{view === 'verify' && }
{view === 'admin' && }
{view === 'support' && }
{view === 'login' && }
{view === 'privacy' && }
{view !== 'verify' && view !== 'login' && view !== 'support' && (
)}
);
};
export default App;