adding landing page
This commit is contained in:
parent
62880bf4e0
commit
901729e1db
BIN
ipi-survey-platform/public/assets/images/FCSCLogo.png
Normal file
BIN
ipi-survey-platform/public/assets/images/FCSCLogo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
ipi-survey-platform/public/assets/images/lock.jpg
Normal file
BIN
ipi-survey-platform/public/assets/images/lock.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
ipi-survey-platform/public/assets/images/product-image.jpg
Normal file
BIN
ipi-survey-platform/public/assets/images/product-image.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
BIN
ipi-survey-platform/public/assets/images/timeline-image.jpg
Normal file
BIN
ipi-survey-platform/public/assets/images/timeline-image.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@ -14,7 +14,7 @@ import ChangePassword from '@/pages/ChangePassword/ChangePassword';
|
||||
import ForgotPassword from '@/pages/ForgotPassword/ForgotPassword';
|
||||
import PublicContactForm from '@/pages/PublicContactForm';
|
||||
import EditCompanyProfile from '@/pages/Admin/configuration/EditCompanyProfile';
|
||||
|
||||
import Navbar from './pages/LandingPage/component/Navbar';
|
||||
const RequireRole = ({ allowedRoles = [], children }) => {
|
||||
let role;
|
||||
let token;
|
||||
@ -37,7 +37,8 @@ const RequireRole = ({ allowedRoles = [], children }) => {
|
||||
return children;
|
||||
}
|
||||
|
||||
return <Navigate to="/login" replace />;
|
||||
// return <Navigate to="/login" replace />;
|
||||
return <Navigate to="/index" replace />
|
||||
};
|
||||
|
||||
const SessionWarningModal = ({ show, remainingTime, onExtend, onLogout }) => {
|
||||
@ -295,6 +296,9 @@ function App() {
|
||||
<Route path="/forgot-password" element={<ForgotPassword />} />
|
||||
<Route path="/reset-password" element={<PublicContactForm />} />
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
{/* landingpage */}
|
||||
|
||||
<Route path="/index" element={<Navbar />} />
|
||||
</Routes>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -51,14 +51,9 @@ const AdminDashboard = () => {
|
||||
setLoading(true);
|
||||
const params = new URLSearchParams();
|
||||
|
||||
// Only add quarter and year to params if they are not 'All'
|
||||
if (quarter && quarter !== 'All') {
|
||||
params.append('quarter', quarter);
|
||||
}
|
||||
|
||||
if (year && year !== 'All') {
|
||||
params.append('year', year);
|
||||
}
|
||||
// Always send both quarter and year, but use 'All' if not specified
|
||||
params.append('quarter', quarter || 'All');
|
||||
params.append('year', year || 'All');
|
||||
|
||||
const response = await apiClient.get(`/admin_dashboard?${params.toString()}`);
|
||||
|
||||
|
||||
@ -118,7 +118,7 @@ const ResetPasswordModal = ({
|
||||
onClick={() => setShowOldPassword(!showOldPassword)}
|
||||
disabled={loading}
|
||||
>
|
||||
{showOldPassword ? <EyeOff className="w-5 h-5 text-[#B68A35]" /> : <Eye className="w-5 h-5 text-[#B68A35]" />}
|
||||
{showOldPassword ? <Eye className="w-5 h-5 text-[#B68A35]" /> : <EyeOff className="w-5 h-5 text-[#B68A35]" />}
|
||||
|
||||
</button>
|
||||
</div>
|
||||
@ -152,7 +152,7 @@ const ResetPasswordModal = ({
|
||||
onClick={() => setShowNewPassword(!showNewPassword)}
|
||||
disabled={loading}
|
||||
>
|
||||
{showNewPassword ? <EyeOff className="w-5 h-5 text-[#B68A35]" /> : <Eye className="w-5 h-5 text-[#B68A35]" />}
|
||||
{showNewPassword ? <Eye className="w-5 h-5 text-[#B68A35]" /> : <EyeOff className="w-5 h-5 text-[#B68A35]" />}
|
||||
|
||||
</button>
|
||||
</div>
|
||||
@ -186,7 +186,7 @@ const ResetPasswordModal = ({
|
||||
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
|
||||
disabled={loading}
|
||||
>
|
||||
{showConfirmPassword ? <EyeOff className="w-5 h-5 text-[#B68A35]" /> : <Eye className="w-5 h-5 text-[#B68A35]" />}
|
||||
{showConfirmPassword ? <Eye className="w-5 h-5 text-[#B68A35]" /> : <EyeOff className="w-5 h-5 text-[#B68A35]" />}
|
||||
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -132,20 +132,23 @@ const ImportModal = ({ isOpen, onClose, onImport }) => {
|
||||
let errorMsg = response.message || 'Import failed';
|
||||
|
||||
// Add duplicate HS codes to the error message if they exist
|
||||
if (response.duplicate_hs_codes_in_system?.length > 0) {
|
||||
errorMsg += `\nDuplicate HS codes found: ${response.duplicate_hs_codes_in_system.join(', ')}`;
|
||||
}
|
||||
// if (response.duplicate_hs_codes_in_system?.length > 0) {
|
||||
// errorMsg += `\nDuplicate HS codes found: ${response.duplicate_hs_codes_in_system.join(', ')}`;
|
||||
// }
|
||||
|
||||
// Show error summary if available
|
||||
if (response.summary) {
|
||||
errorMsg += `\nTotal records: ${response.summary.total_records}`;
|
||||
errorMsg += `\nImported: ${response.summary.imported}`;
|
||||
errorMsg += `\nSkipped: ${response.summary.skipped}`;
|
||||
// // Show error summary if available
|
||||
// if (response.summary) {
|
||||
// errorMsg += `\nTotal records: ${response.summary.total_records}`;
|
||||
// errorMsg += `\nImported: ${response.summary.imported}`;
|
||||
// errorMsg += `\nSkipped: ${response.summary.skipped}`;
|
||||
|
||||
if (response.summary.errors?.length > 0) {
|
||||
errorMsg += `\n\nErrors:\n${response.summary.errors.join('\n')}`;
|
||||
errorMsg += '\n\nErrors:';
|
||||
response.summary.errors.forEach(err => {
|
||||
errorMsg += `\nRow ${err.row}: ${err.error}`;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setError(errorMsg);
|
||||
return;
|
||||
@ -159,7 +162,24 @@ const ImportModal = ({ isOpen, onClose, onImport }) => {
|
||||
onClose();
|
||||
} catch (err) {
|
||||
console.error('Error uploading CSV:', err);
|
||||
const errorMessage = err.response?.data?.message || 'Failed to import file. Please try again.';
|
||||
let errorMessage = 'Failed to import file. Please try again.';
|
||||
|
||||
// Handle different error response formats
|
||||
if (err.response?.data) {
|
||||
if (typeof err.response.data === 'string') {
|
||||
errorMessage = err.response.data;
|
||||
} else if (err.response.data.message) {
|
||||
errorMessage = err.response.data.message;
|
||||
} else if (err.response.data.error) {
|
||||
errorMessage = err.response.data.error;
|
||||
} else {
|
||||
// Stringify the entire response if it's an object
|
||||
errorMessage = JSON.stringify(err.response.data, null, 2);
|
||||
}
|
||||
} else if (err.message) {
|
||||
errorMessage = err.message;
|
||||
}
|
||||
|
||||
setError(errorMessage);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
@ -175,12 +195,9 @@ const ImportModal = ({ isOpen, onClose, onImport }) => {
|
||||
|
||||
const downloadSampleCSV = () => {
|
||||
const sampleData = [
|
||||
['HS Code', 'Product Name', 'Unit', 'Description', 'Status'],
|
||||
['0101', 'Live Horses', 'kg', 'Live pure-bred breeding horses', 'Active'],
|
||||
['0102', 'Live Bovine Animals', 'kg', 'Live bovine animals', 'Active'],
|
||||
['0103', 'Live Swine', 'kg', 'Live swine', 'Active'],
|
||||
['0104', 'Live Sheep And Goats', 'kg', 'Live sheep and goats', 'Active'],
|
||||
['0105', 'Live Poultry', 'kg', 'Live poultry', 'Active']
|
||||
['HS Code', 'Product Name', 'Unit'],
|
||||
['0101', 'Live Horses', 'kg'],
|
||||
['0102', 'Live Bovine Animals', 'kg'],
|
||||
];
|
||||
|
||||
const csvContent = sampleData.map(row =>
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
import React from "react";
|
||||
|
||||
const Banner = () => {
|
||||
return (
|
||||
<section className="w-full py-8 md:py-14 lg:py-14 -mt-4 md:-mt-4 bg-gradient-to-b from-[#F2ECCF] to-[#F2ECCF] flex flex-col items-center justify-center text-center px-4">
|
||||
{/* Tagline */}
|
||||
<div className=" inline-block bg-white border border-gray-200 text-gray-700 text-sm px-4 py-2 rounded-full mb-6 shadow-sm">
|
||||
Official survey by{" "}
|
||||
<span className="font-medium text-[#4b5563]">
|
||||
Federal Competitiveness and Statistics Centre (FCSC)
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<h1 className="text-2xl md:text-3xl font-semibold text-gray-800 mb-6">
|
||||
Industrial Production Index (IPI) Survey – UAE
|
||||
</h1>
|
||||
|
||||
{/* Description */}
|
||||
<p className="text-gray-700 text-[15px] max-w-2xl mx-auto leading-relaxed mb-10">
|
||||
A secure <span className="font-semibold">quarterly survey</span> for manufacturing establishments — with{" "}
|
||||
<span className="font-semibold">monthly breakdowns</span> inside each quarter.
|
||||
Your data powers official national indicators.
|
||||
</p>
|
||||
|
||||
{/* Buttons */}
|
||||
<div className="flex flex-col md:flex-row justify-center gap-4">
|
||||
<button className="bg-[#92722A] w-48 text-white text-md px-5 py-2 rounded-md hover:bg-[#a07f30] transition-all shadow-sm">
|
||||
Sign in to submit
|
||||
</button>
|
||||
<button className="border-2 border-[#92722A] text-[#92722A] text-md px-5 py-2 rounded-md hover:bg-[#f9f6ec] transition-all shadow-sm">
|
||||
How the survey works
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Banner;
|
||||
@ -0,0 +1,75 @@
|
||||
import React from "react";
|
||||
|
||||
const steps = [
|
||||
{
|
||||
number: 1,
|
||||
title: "Notification",
|
||||
description: "You receive an email/SMS when a new quarter opens.",
|
||||
},
|
||||
{
|
||||
number: 2,
|
||||
title: "Sign in",
|
||||
description:
|
||||
"Use your FCSC-provided account. If needed, use Forgot password.",
|
||||
},
|
||||
{
|
||||
number: 3,
|
||||
title: "Enter data",
|
||||
description:
|
||||
"Provide monthly quantities and values for each product in the open quarter (e.g., Jan, Feb, Mar for Q1).",
|
||||
},
|
||||
{
|
||||
number: 4,
|
||||
title: "Validate",
|
||||
description:
|
||||
"Inline checks highlight missing or unusual values across months.",
|
||||
},
|
||||
{
|
||||
number: 5,
|
||||
title: "Submit",
|
||||
description:
|
||||
"Certify accuracy for the quarter and submit.",
|
||||
},
|
||||
{
|
||||
number: 6,
|
||||
title: "Review",
|
||||
description:
|
||||
"FCSC may contact you for clarifications or revisions.",
|
||||
},
|
||||
];
|
||||
|
||||
const Cards = () => {
|
||||
return (
|
||||
<section className="bg-gray-50 py-6 md:py-8 lg:py-10 px-6 md:px-12 lg:px-24">
|
||||
<div className="mb-8">
|
||||
<h2 className="text-2xl font-semibold text-gray-900">How the survey works</h2>
|
||||
<p className="text-gray-500 mt-1">A simple quarterly cycle</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{steps.map((step) => (
|
||||
<div
|
||||
key={step.number}
|
||||
className="bg-white rounded-xl shadow-sm border border-gray-200 p-6 hover:shadow-md transition"
|
||||
>
|
||||
<div className="flex items-center mb-3">
|
||||
<div className="w-8 h-8 flex items-center justify-center rounded-full border border-gray-400 text-gray-700 font-medium mr-3">
|
||||
{step.number}
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-gray-800">
|
||||
{step.title}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-gray-600 text-sm leading-relaxed">{step.description}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="text-xs text-gray-500 mt-10">
|
||||
Accounts are issued by FCSC. There is no self-registration.
|
||||
</p>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Cards;
|
||||
@ -0,0 +1,47 @@
|
||||
import React from "react";
|
||||
|
||||
const Collect = () => {
|
||||
return (
|
||||
<section className="mx-auto flex flex-col md:flex-row justify-between px-6 md:px-10 lg:px-24 py-6 md:py-12 gap-10">
|
||||
{/* Left Section */}
|
||||
<div className=" flex flex-col item-cemter justify-center md:w-1/2">
|
||||
<h2 className="text-2xl font-semibold text-gray-900 mb-4">
|
||||
Why we collect this data
|
||||
</h2>
|
||||
<ul className="space-y-2 text-gray-700">
|
||||
<li>
|
||||
To produce timely and reliable statistics on manufacturing trends.
|
||||
</li>
|
||||
<li>
|
||||
To support evidence-based decisions by public and private stakeholders.
|
||||
</li>
|
||||
<li>
|
||||
To contribute to national accounts and short-term economic indicators.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Right Section */}
|
||||
<div className="md:w-1/2 bg-[#F1EBCF] rounded-2xl border border-gray-200 p-8 flex items-center justify-center">
|
||||
<div className="grid grid-cols-2 gap-6">
|
||||
{[
|
||||
{ q: "Q1", period: "Jan–Mar" },
|
||||
{ q: "Q2", period: "Apr–Jun" },
|
||||
{ q: "Q3", period: "Jul–Sep" },
|
||||
{ q: "Q4", period: "Oct–Dec" },
|
||||
].map((item) => (
|
||||
<div
|
||||
key={item.q}
|
||||
className="bg-white shadow-sm border border-gray-100 rounded-xl px-6 lg:px-18 py-6 text-center"
|
||||
>
|
||||
<p className="font-semibold text-gray-900">{item.q}</p>
|
||||
<p className="text-sm text-gray-600">{item.period}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Collect;
|
||||
35
ipi-survey-platform/src/pages/LandingPage/component/Cta.jsx
Normal file
35
ipi-survey-platform/src/pages/LandingPage/component/Cta.jsx
Normal file
@ -0,0 +1,35 @@
|
||||
import React from "react";
|
||||
|
||||
const Cta = () => {
|
||||
return (
|
||||
<div className=" md:px-10 lg:px-24 mx-auto my-10 px-6">
|
||||
<div className="flex flex-col md:flex-row items-start md:items-center justify-between bg-white border border-gray-200 rounded-2xl shadow-sm p-8 md:p-10">
|
||||
{/* Left content */}
|
||||
<div>
|
||||
<h3 className="text-2xl font-semibold text-gray-900 mb-2">
|
||||
We’re here to help
|
||||
</h3>
|
||||
<p className="text-gray-700 mb-1">
|
||||
Our support team can assist with access, questions, or clarifications.
|
||||
</p>
|
||||
<p className="text-sm text-gray-500">
|
||||
Support hours: Sun–Thu, 8:00–16:00 GST
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Buttons */}
|
||||
<div className="flex flex-col sm:flex-row gap-3 mt-6 md:mt-0">
|
||||
<button className="bg-[#92722A] w-42 text-white text-md px-5 py-2 rounded-md hover:bg-[#a07f30] transition-all shadow-sm">
|
||||
|
||||
Contact Support
|
||||
</button>
|
||||
<button className="border-2 border-[#92722A] text-[#92722A] text-md px-5 py-2 rounded-md hover:bg-[#f9f6ec] transition-all shadow-sm">
|
||||
Read the guidance
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Cta;
|
||||
97
ipi-survey-platform/src/pages/LandingPage/component/Faq.jsx
Normal file
97
ipi-survey-platform/src/pages/LandingPage/component/Faq.jsx
Normal file
@ -0,0 +1,97 @@
|
||||
import React, { useState } from "react";
|
||||
import { ChevronDown, ChevronUp } from "lucide-react"; // ✅ Up/Down icons
|
||||
|
||||
const Faq = () => {
|
||||
const [openIndex, setOpenIndex] = useState(null);
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
question: "Do I need an account to respond?",
|
||||
answer:
|
||||
"Yes. FCSC provisions accounts to selected establishments. Use Login to access the survey.",
|
||||
},
|
||||
{
|
||||
question: "Can I register myself?",
|
||||
answer:
|
||||
"No. There is no self-registration. If you were contacted but can’t access your account, use Forgot password or Contact support.",
|
||||
},
|
||||
{
|
||||
question: "Is my data public?",
|
||||
answer: "No. Results are published only in aggregate form.",
|
||||
},
|
||||
{
|
||||
question: "What if production was zero in a month?",
|
||||
answer: "Enter 0 for the month and provide a reason when prompted.",
|
||||
},
|
||||
{
|
||||
question: "Can I update after submission?",
|
||||
answer:
|
||||
"Yes, if a revision window is open or if FCSC requests a correction.",
|
||||
},
|
||||
{
|
||||
question: "Which browser is supported?",
|
||||
answer: "Latest Chrome, Edge, Safari.",
|
||||
},
|
||||
{
|
||||
question: "How long does it take?",
|
||||
answer:
|
||||
"Most respondents complete within minutes each quarter, depending on product lines.",
|
||||
},
|
||||
{
|
||||
question: "Who can I contact?",
|
||||
answer: "See Need help below.",
|
||||
},
|
||||
];
|
||||
|
||||
const toggleFaq = (index) => {
|
||||
setOpenIndex(openIndex === index ? null : index);
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="bg-[#fafafa] py-12 px-6 md:px-16 lg:px-24">
|
||||
<h2 className="text-2xl font-semibold text-gray-900 mb-8">
|
||||
Frequently asked questions
|
||||
</h2>
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
{faqs.map((faq, index) => {
|
||||
const isOpen = openIndex === index;
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className={`border rounded-xl p-5 shadow-sm transition-all duration-300 bg-white ${
|
||||
isOpen ? "border-gray-200" : "border-gray-200"
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
onClick={() => toggleFaq(index)}
|
||||
className="w-full flex justify-between items-center text-left"
|
||||
>
|
||||
<span
|
||||
className={`font-medium ${
|
||||
isOpen ? "text-yellow-800" : "text-gray-900"
|
||||
}`}
|
||||
>
|
||||
{faq.question}
|
||||
</span>
|
||||
{isOpen ? (
|
||||
<ChevronUp size={22} className="text-yellow-700" /> // ⬆️ when open
|
||||
) : (
|
||||
<ChevronDown size={22} className="text-gray-600" /> // ⬇️ when closed
|
||||
)}
|
||||
</button>
|
||||
|
||||
{isOpen && (
|
||||
<p className="mt-3 text-gray-700 text-sm leading-relaxed">
|
||||
{faq.answer}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Faq;
|
||||
@ -0,0 +1,99 @@
|
||||
import React from "react";
|
||||
import logo from "/assets/images/FCSCLogo.png";
|
||||
|
||||
import {
|
||||
Phone,
|
||||
PhoneCall,
|
||||
Facebook,
|
||||
Instagram,
|
||||
Linkedin,
|
||||
Youtube,
|
||||
Mail,
|
||||
} from "lucide-react";
|
||||
|
||||
const Footer = () => {
|
||||
return (
|
||||
<footer className="bg-white border-t-3 border-[#92722A]">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 px-6 md:px-12 lg:px-24 py-8 md:py-10 lg:py-12">
|
||||
{/* Column 1 */}
|
||||
<div>
|
||||
<h4 className="text-[#92722A] font-semibold mb-3">
|
||||
The Ministry
|
||||
</h4>
|
||||
<ul className="space-y-2 text-gray-700 text-sm">
|
||||
<p>The Federal Competitiveness and Statistics Centre (FCSC) provides reliable data and insights to enhance the UAE’s competitiveness and support sustainable national development.</p>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Column 2 */}
|
||||
<div>
|
||||
<h4 className="text-[#92722A] font-semibold mb-3">
|
||||
Using the website
|
||||
</h4>
|
||||
<ul className="space-y-2 text-gray-700 text-sm">
|
||||
<li><a >Disclaimer</a></li>
|
||||
<li><a >Privacy policy</a></li>
|
||||
<li><a >Terms and conditions</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Column 3 */}
|
||||
<div>
|
||||
<h4 className="text-[#92722A] font-semibold mb-3">
|
||||
Information and support
|
||||
</h4>
|
||||
<ul className="space-y-2 text-gray-700 text-sm">
|
||||
<li><a >Contact us</a></li>
|
||||
<li><a >FAQ’s</a></li>
|
||||
<li><a >Feedback and complaints</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Column 4 – Logo & Contact */}
|
||||
<div className="flex flex-col items-start space-y-2">
|
||||
<img
|
||||
src={logo}
|
||||
alt="Tawasol Logo"
|
||||
className="w-44 "
|
||||
/>
|
||||
<div className=" mt-2 text-gray-700 text-sm space-y-2">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Phone className="w-4 h-4 text-green-600" />
|
||||
<span>+971 4 608 0000</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<PhoneCall className="w-4 h-4 text-green-600" />
|
||||
<span>+971 4 327 3535</span>
|
||||
</div>
|
||||
<p className="text-xs text-gray-600">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Mail className="w-4 h-4 text-green-600" />
|
||||
<span>
|
||||
info@fcsc.gov.ae</span>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-gray-200 mt-6">
|
||||
<div className="max-w-7xl mx-auto px-6 py-4 flex flex-col md:flex-row justify-between items-center text-sm text-gray-600">
|
||||
<p>
|
||||
Copyright © 2025 Federal Competitiveness and Statistics Centre, All Rights Reserved{" "}
|
||||
{/* <span className="font-medium">All rights reserved.</span> Last updated on 24/04/2023 at 15:45 */}
|
||||
</p>
|
||||
|
||||
{/* Social Icons */}
|
||||
<div className="flex space-x-4 mt-3 md:mt-0">
|
||||
{/* <a href="#"><Facebook size={18} /></a>
|
||||
<a href="#"><Instagram size={18} /></a>
|
||||
<a href="#"><Linkedin size={18} /></a>
|
||||
<a href="#"><Youtube size={18} /></a> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
@ -0,0 +1,49 @@
|
||||
import React from "react";
|
||||
|
||||
const Industrial = () => {
|
||||
return (
|
||||
<section className="mx-auto px-6 md:px-10 lg:px-24 py-6 md:py-10 lg:py-14 grid md:grid-cols-2 gap-6 md:gap-8 lg:gap-12 items-start">
|
||||
{/* Left Side: Content */}
|
||||
<div>
|
||||
<h2 className="text-2xl font-semibold text-gray-900 mb-4">
|
||||
What is the Industrial Production Index (IPI)?
|
||||
</h2>
|
||||
<p className="text-gray-700 leading-relaxed text-justify">
|
||||
The Industrial Production Index (IPI) measures changes in the volume
|
||||
of industrial output over time. It tracks production across
|
||||
manufacturing activities classified by ISIC and is a key official
|
||||
indicator used to monitor economic activity and inform policy.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Right Side: Quick Facts Box */}
|
||||
<div className="bg-white shadow-sm border border-gray-200 rounded-2xl p-6">
|
||||
<h3 className="text-lg font-semibold text-gray-900 mb-4">
|
||||
Quick facts
|
||||
</h3>
|
||||
<ul className="space-y-3 text-gray-700">
|
||||
<li>
|
||||
<strong>Frequency:</strong> Quarterly (enter monthly figures for the
|
||||
quarter)
|
||||
</li>
|
||||
<li>
|
||||
<strong>Reference area:</strong> United Arab Emirates
|
||||
</li>
|
||||
<li>
|
||||
<strong>Respondents:</strong> Registered manufacturing establishments
|
||||
</li>
|
||||
<li>
|
||||
<strong>Classification:</strong> ISIC Rev.4
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div className="mt-6 bg-gray-100 border border-gray-100 rounded-lg p-4 text-sm text-gray-600">
|
||||
<strong>Tip:</strong> Keep monthly records ready (e.g., invoices, ERP
|
||||
extracts).
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Industrial;
|
||||
146
ipi-survey-platform/src/pages/LandingPage/component/Navbar.jsx
Normal file
146
ipi-survey-platform/src/pages/LandingPage/component/Navbar.jsx
Normal file
@ -0,0 +1,146 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Menu, X } from "lucide-react";
|
||||
import logo from "/assets/images/FCSCLogo.png";
|
||||
import Banner from "./Banner";
|
||||
import Industrial from "./Industrial";
|
||||
import Collect from "./Collect";
|
||||
import Survey from "./Survey";
|
||||
import Cards from "./Cards";
|
||||
import Protected from "./Protected";
|
||||
import Participation from "./Participation";
|
||||
import Timeline from "./Timeline";
|
||||
import Faq from "./Faq";
|
||||
import Footer from "./Footer";
|
||||
import Resources from "./Resources";
|
||||
import Cta from "./Cta";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
const Navbar = () => {
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const [activeSection, setActiveSection] = useState("about-ipi");
|
||||
|
||||
const closeMenu = () => setMenuOpen(false);
|
||||
|
||||
// Scroll detection for active section
|
||||
useEffect(() => {
|
||||
const sections = document.querySelectorAll("section[id]");
|
||||
const options = {
|
||||
root: null,
|
||||
threshold: 0.5,
|
||||
};
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
setActiveSection(entry.target.id);
|
||||
}
|
||||
});
|
||||
}, options);
|
||||
|
||||
sections.forEach((section) => observer.observe(section));
|
||||
return () => sections.forEach((section) => observer.unobserve(section));
|
||||
}, []);
|
||||
|
||||
// Active & hover styling
|
||||
const linkClass = (id) =>
|
||||
`relative pb-1 transition-all duration-300 ${
|
||||
activeSection === id
|
||||
? "text-[#b9933b] after:content-[''] after:absolute after:left-0 after:bottom-0 after:w-full after:h-[2px] after:bg-[#b9933b]"
|
||||
: "text-gray-800 hover:text-[#b9933b]"
|
||||
}`;
|
||||
|
||||
// Scroll and highlight on click
|
||||
const handleClick = (id) => {
|
||||
setActiveSection(id);
|
||||
closeMenu();
|
||||
const section = document.getElementById(id);
|
||||
if (section) {
|
||||
section.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Navbar */}
|
||||
<header className="w-full border-t-4 border-[#b9933b] bg-white shadow-sm fixed top-0 left-0 z-50">
|
||||
<div className="flex items-center justify-between px-4 md:px-10 py-3">
|
||||
<img src={logo} alt="FCSC Logo" className="h-10 w-auto" />
|
||||
|
||||
{/* Desktop Menu */}
|
||||
<nav className="hidden md:flex items-center space-x-8 text-[15px] font-medium">
|
||||
<button onClick={() => handleClick("about-ipi")} className={linkClass("about-ipi")}>
|
||||
About IPI
|
||||
</button>
|
||||
<button onClick={() => handleClick("how-it-works")} className={linkClass("how-it-works")}>
|
||||
How it works
|
||||
</button>
|
||||
<button onClick={() => handleClick("eligibility")} className={linkClass("eligibility")}>
|
||||
Eligibility
|
||||
</button>
|
||||
<button onClick={() => handleClick("faqs")} className={linkClass("faqs")}>
|
||||
FAQs
|
||||
</button>
|
||||
<button onClick={() => handleClick("resources")} className={linkClass("resources")}>
|
||||
Resources
|
||||
</button>
|
||||
<Link
|
||||
to="/login"
|
||||
className="bg-[#b9933b] text-white text-sm px-5 py-1.5 rounded-md hover:bg-[#a07f30] transition-all"
|
||||
>
|
||||
Login
|
||||
</Link>
|
||||
</nav>
|
||||
|
||||
{/* Mobile Menu Toggle */}
|
||||
<button
|
||||
className="md:hidden text-[#b9933b]"
|
||||
onClick={() => setMenuOpen(!menuOpen)}
|
||||
>
|
||||
{menuOpen ? <X size={24} /> : <Menu size={24} />}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu */}
|
||||
{menuOpen && (
|
||||
<div className="md:hidden bg-gray-50 border-t border-gray-200 px-6 py-4 space-y-3 text-gray-800">
|
||||
{["about-ipi", "how-it-works", "eligibility", "faqs", "resources"].map((id) => (
|
||||
<button
|
||||
key={id}
|
||||
onClick={() => handleClick(id)}
|
||||
className={`${linkClass(id)} block w-full text-left`}
|
||||
>
|
||||
{id === "about-ipi" && "About IPI"}
|
||||
{id === "how-it-works" && "How it works"}
|
||||
{id === "eligibility" && "Eligibility"}
|
||||
{id === "faqs" && "FAQs"}
|
||||
{id === "resources" && "Resources"}
|
||||
</button>
|
||||
))}
|
||||
<Link
|
||||
to="/login" className="w-full bg-[#b9933b] text-white text-sm px-5 py-1.5 rounded-md hover:bg-[#a07f30] transition-all">
|
||||
Login
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
|
||||
{/* Sections */}
|
||||
<div className="pt-20 scroll-smooth">
|
||||
<Banner />
|
||||
<section id="about-ipi"><Industrial /></section>
|
||||
<section id="how-it-works"><Cards /></section>
|
||||
<section id="eligibility"><Survey /></section>
|
||||
<Collect />
|
||||
<Protected />
|
||||
<Participation />
|
||||
<Timeline />
|
||||
<section id="resources"><Resources /></section>
|
||||
<section id="faqs"><Faq /></section>
|
||||
<Cta/>
|
||||
<Footer />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navbar;
|
||||
@ -0,0 +1,40 @@
|
||||
import React from "react";
|
||||
import sampleForm from "/assets/images/product-image.jpg";
|
||||
|
||||
const Participation = () => {
|
||||
return (
|
||||
|
||||
<section className="bg-white py-12 px-6 md:px-12 lg:px-20">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-10 items-center">
|
||||
{/* Left Side - Image / Form Box */}
|
||||
<div className="flex justify-center">
|
||||
<div className="border border-gray-200 rounded-2xl shadow-sm bg-gradient-to-br from-gray-50 to-white p-4">
|
||||
<img
|
||||
src={sampleForm}
|
||||
alt="Participation form example"
|
||||
className="rounded-xl w-full h-auto object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Side - Text Content */}
|
||||
<div>
|
||||
<h2 className="text-2xl font-semibold text-gray-900 mb-4">
|
||||
Why your <span className="text-gray-900 font-bold">participation</span> matters
|
||||
</h2>
|
||||
|
||||
<ul className="list-disc pl-6 text-gray-700 space-y-2">
|
||||
<li>Accurate indicators help calibrate policies that affect industry.</li>
|
||||
<li>Timely inputs reduce follow-up calls and queries.</li>
|
||||
<li>Access to historical submissions and receipts for your records.</li>
|
||||
<li>
|
||||
Contributes to a complete national picture of manufacturing performance.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Participation;
|
||||
@ -0,0 +1,88 @@
|
||||
import React from "react";
|
||||
import Lock from "/assets/images/lock.jpg"
|
||||
|
||||
|
||||
const Protected = () => {
|
||||
return (
|
||||
<section className="bg-gray-50 py-6 md:py-8 lg:py-12 px-6 md:px-12 lg:px-24">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-10 items-center">
|
||||
|
||||
{/* Left Side - Text Content */}
|
||||
<div>
|
||||
<h2 className="text-2xl font-semibold text-gray-900 mb-4">
|
||||
How your data is protected and used
|
||||
</h2>
|
||||
|
||||
<div className="space-y-5 text-gray-700">
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-800 mb-1">Confidentiality</h3>
|
||||
<p className="text-justify">
|
||||
Your establishment’s data is confidential and used only for official
|
||||
statistics. Published results are aggregated; no individual
|
||||
establishment’s data is disclosed.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-800 mb-1">Legal basis</h3>
|
||||
<p className="text-justify">
|
||||
|
||||
Collected under the national statistics mandate to compile official
|
||||
indicators. Participation is compulsory for selected establishments
|
||||
under applicable statistical regulations.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-800 mb-1">Data security</h3>
|
||||
<p className="text-justify">
|
||||
|
||||
Role-based access, encryption in transit and at rest, and monitored
|
||||
environments. Regular audits and adherence to government security
|
||||
guidelines.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-800 mb-1">Retention</h3>
|
||||
<p className="text-justify">
|
||||
|
||||
Data is retained only as long as necessary for statistical purposes per
|
||||
policy.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-gray-500 mt-6">
|
||||
See{" "}
|
||||
<a href="#" className="text-blue-600 hover:underline">
|
||||
Privacy Policy
|
||||
</a>
|
||||
,{" "}
|
||||
<a href="#" className="text-blue-600 hover:underline">
|
||||
Terms of Use
|
||||
</a>{" "}
|
||||
and{" "}
|
||||
<a href="#" className="text-blue-600 hover:underline">
|
||||
Data Protection
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Right Side - Image / Icon Box */}
|
||||
<div className="bg-white from-yellow-50 to-gray-50 rounded-2xl flex justify-center items-center border border-gray-200 shadow-sm">
|
||||
<div className="bg-[#F1EBCF]">
|
||||
<img
|
||||
src={Lock}
|
||||
alt="Data Protection Illustration"
|
||||
className=" h-[380px] object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Protected;
|
||||
@ -0,0 +1,37 @@
|
||||
import React from "react";
|
||||
|
||||
const Resources = () => {
|
||||
const resources = [
|
||||
{ title: "FCSC – Official website", link: "#" },
|
||||
{ title: "Sample questionnaire (PDF)", link: "#" },
|
||||
{ title: "Item classification guide (ISIC) (PDF)", link: "#" },
|
||||
{ title: "Data definitions & unit guidelines (PDF)", link: "#" },
|
||||
{ title: "Browser and system requirements", link: "#" },
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="bg-white py-12 px-6 md:px-16 lg:px-24">
|
||||
<div className="mx-auto">
|
||||
<h2 className="text-2xl font-semibold text-gray-900 mb-6">
|
||||
Resources & downloads
|
||||
</h2>
|
||||
<ul className="space-y-3">
|
||||
{resources.map((item, index) => (
|
||||
<li key={index}>
|
||||
<a
|
||||
href={item.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-700 hover:underline text-[16px]"
|
||||
>
|
||||
{item.title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Resources;
|
||||
@ -0,0 +1,35 @@
|
||||
import React from "react";
|
||||
|
||||
const Survey = () => {
|
||||
return (
|
||||
<section className="mx-auto px-6 md:px-10 lg:px-24 py-12">
|
||||
{/* Heading */}
|
||||
<h2 className="text-2xl font-semibold text-gray-900 mb-4">
|
||||
Who should complete the IPI <span className="text-gray-900">survey</span>?
|
||||
</h2>
|
||||
|
||||
{/* Content */}
|
||||
<div className="text-gray-700 space-y-3 leading-relaxed">
|
||||
<p>
|
||||
Manufacturing establishments operating in the UAE that are selected/notified by FCSC.
|
||||
</p>
|
||||
<p>
|
||||
The survey is address-based: if your establishment is contacted, you are required
|
||||
to respond for the reference quarter.
|
||||
</p>
|
||||
<p>
|
||||
If your activities paused or changed, you must still complete the survey and indicate
|
||||
reasons where relevant.
|
||||
</p>
|
||||
<p className="text-sm text-gray-600">
|
||||
If you believe you were contacted in error, please see{" "}
|
||||
<a href="#" className="text-blue-600 underline hover:text-blue-800">
|
||||
Contact
|
||||
</a>.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Survey;
|
||||
@ -0,0 +1,54 @@
|
||||
import React from "react";
|
||||
import timelineImage from "/assets/images/timeline-image.jpg";
|
||||
|
||||
const Timeline = () => {
|
||||
return (
|
||||
<section className="bg-white py-12 px-6 md:px-12 lg:px-20">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-10 items-center">
|
||||
|
||||
{/* Left Side - Text Content */}
|
||||
<div>
|
||||
<h2 className="text-2xl font-semibold text-gray-900 mb-4">
|
||||
Key dates & timeline
|
||||
</h2>
|
||||
|
||||
<div className="space-y-3 text-gray-700">
|
||||
<p>
|
||||
<strong>Survey frequency: Quarterly</strong> — each survey collects{" "}
|
||||
<em>monthly</em> figures for the months in that quarter.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Quarter mapping:</strong> Q1 (Jan–Mar), Q2 (Apr–Jun), Q3 (Jul–Sep),
|
||||
Q4 (Oct–Dec).
|
||||
</p>
|
||||
<p>
|
||||
<strong>Windows:</strong> Open and deadline dates are communicated in
|
||||
notifications; a short grace period may apply.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Revisions:</strong> If requested, please update promptly; indices are
|
||||
re-computed when revisions arrive.
|
||||
</p>
|
||||
<p className="text-sm text-gray-600">
|
||||
<strong>Tip:</strong> Keep your monthly records ready; you can save drafts
|
||||
before final submission.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Side - Image / Timeline Box */}
|
||||
<div className="flex justify-center">
|
||||
<div className="border border-gray-200 rounded-2xl shadow-sm bg-gradient-to-br from-gray-50 to-white p-4">
|
||||
<img
|
||||
src={timelineImage}
|
||||
alt="Participation form example"
|
||||
className="rounded-xl w-full h-auto md:h-60 object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Timeline;
|
||||
Loading…
Reference in New Issue
Block a user