Apply Limelite dark crimson theme to the application
This commit is contained in:
@@ -102,7 +102,7 @@ const AnalysisResultPage = () => {
|
||||
if (!score && score !== 0) return 'bg-gray-600';
|
||||
if (score >= 70) return 'bg-emerald-500';
|
||||
if (score >= 40) return 'bg-yellow-500';
|
||||
return 'bg-[#0097C3]';
|
||||
return 'bg-[limelite-red]';
|
||||
};
|
||||
|
||||
const getMetricDisplayName = (metricKey) => {
|
||||
@@ -469,7 +469,7 @@ const AnalysisResultPage = () => {
|
||||
if (isLoading) return (
|
||||
<div className="min-h-screen flex items-center justify-center">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="w-12 h-12 border-4 border-white/10 border-t-[#0097C3] rounded-full animate-spin"></div>
|
||||
<div className="w-12 h-12 border-4 border-white/10 border-t-[limelite-red] rounded-full animate-spin"></div>
|
||||
<p className="text-gray-300 animate-pulse">Analyzing skin profile...</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -478,12 +478,12 @@ const AnalysisResultPage = () => {
|
||||
if (error) return (
|
||||
<div className="min-h-screen flex items-center justify-center p-4">
|
||||
<div className="glass-panel p-8 rounded-none shadow-xl max-w-md w-full text-center border border-white/10">
|
||||
<div className="w-16 h-16 bg-[#0097C3]/20 rounded-none flex items-center justify-center mx-auto mb-4">
|
||||
<svg className="w-8 h-8 text-[#0097C3]" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
|
||||
<div className="w-16 h-16 bg-[limelite-red]/20 rounded-none flex items-center justify-center mx-auto mb-4">
|
||||
<svg className="w-8 h-8 text-[limelite-red]" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
|
||||
</div>
|
||||
<h2 className="text-xl font-bold text-white mb-2">Analysis Failed</h2>
|
||||
<p className="text-gray-300 mb-6">{errorDescriptions[error] || error}</p>
|
||||
<button onClick={handleNewAnalysis} className="w-full py-3 bg-[#0097C3] hover:bg-[#007ba0] text-white rounded-none font-bold transition-colors shadow-lg shadow-[#0097C3]/30">
|
||||
<button onClick={handleNewAnalysis} className="w-full py-3 bg-[limelite-red] hover:bg-[limelite-maroon] text-white rounded-none font-bold transition-colors shadow-lg shadow-[limelite-red]/30">
|
||||
Try Again
|
||||
</button>
|
||||
</div>
|
||||
@@ -494,7 +494,7 @@ const AnalysisResultPage = () => {
|
||||
<div className="min-h-screen flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<p className="text-gray-300 mb-4">No analysis data available.</p>
|
||||
<button onClick={handleNewAnalysis} className="px-6 py-2 bg-[#0097C3] text-white rounded-none shadow-lg">Start New Analysis</button>
|
||||
<button onClick={handleNewAnalysis} className="px-6 py-2 bg-[limelite-red] text-white rounded-none shadow-lg">Start New Analysis</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -530,7 +530,7 @@ const AnalysisResultPage = () => {
|
||||
<div className="h-screen overflow-hidden bg-[#18181b] font-sans relative flex flex-col">
|
||||
|
||||
{/* Header (Matching App.js) */}
|
||||
<header className="fixed top-0 left-0 right-0 z-50 py-4 px-6 flex items-center justify-between bg-[#0097C3] shadow-lg">
|
||||
<header className="fixed top-0 left-0 right-0 z-50 py-4 px-6 flex items-center justify-between bg-[limelite-red] shadow-lg">
|
||||
<div className="flex items-center gap-4">
|
||||
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="Limelite Logo" className="h-12 md:h-16 w-auto brightness-0 invert" />
|
||||
</div>
|
||||
@@ -574,7 +574,7 @@ const AnalysisResultPage = () => {
|
||||
{activeMask && (
|
||||
<button
|
||||
onClick={handleClearMask}
|
||||
className="text-white hover:text-[#0097C3] transition-colors flex items-center mb-2"
|
||||
className="text-white hover:text-[limelite-red] transition-colors flex items-center mb-2"
|
||||
title="Show original image"
|
||||
>
|
||||
<svg className="w-7 h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@@ -608,7 +608,7 @@ const AnalysisResultPage = () => {
|
||||
{/* Badge */}
|
||||
<div className={`px-3 py-1 rounded-full text-[11px] font-bold uppercase min-w-[65px] text-center ${metric.ui_score >= 70 ? 'bg-emerald-500/20 text-[#4ade80] border border-emerald-500/30' :
|
||||
metric.ui_score >= 40 ? 'bg-amber-500/20 text-[#fbbf24] border border-amber-500/30' :
|
||||
'bg-[#0097C3]/20 text-[#0097C3] border border-[#0097C3]/30'
|
||||
'bg-[limelite-red]/20 text-[limelite-red] border border-[limelite-red]/30'
|
||||
}`}>
|
||||
{metric.ui_score >= 70 ? 'Good' : metric.ui_score >= 40 ? 'Average' : 'Bad'}
|
||||
</div>
|
||||
@@ -631,7 +631,7 @@ const AnalysisResultPage = () => {
|
||||
<div className="bg-[#18181b] px-5 py-6 flex flex-col gap-4 relative z-30 shrink-0 border-t border-white/10">
|
||||
<button
|
||||
onClick={() => setShowSignupModal(true)}
|
||||
className="w-full bg-[#0097C3] hover:bg-[#007ba0] text-white h-14 rounded-none font-bold text-lg shadow-sm flex items-center justify-center gap-3 transition-all transform active:scale-95 relative"
|
||||
className="w-full bg-[limelite-red] hover:bg-[limelite-maroon] text-white h-14 rounded-none font-bold text-lg shadow-sm flex items-center justify-center gap-3 transition-all transform active:scale-95 relative"
|
||||
>
|
||||
<span className="text-[1.1rem]">Access Full Report</span>
|
||||
<div className="w-6 h-6 bg-white/20 rounded-full flex items-center justify-center">
|
||||
@@ -646,7 +646,7 @@ const AnalysisResultPage = () => {
|
||||
<div className="bg-[#18181b] px-5 py-6 flex flex-col gap-4 relative z-30 shrink-0 border-t border-white/10">
|
||||
<button
|
||||
onClick={handleDownloadPDF}
|
||||
className="w-full bg-[#0097C3] hover:bg-[#007ba0] text-white h-14 rounded-none font-bold text-lg shadow-sm flex items-center justify-center gap-3 transition-all transform active:scale-95 relative"
|
||||
className="w-full bg-[limelite-red] hover:bg-[limelite-maroon] text-white h-14 rounded-none font-bold text-lg shadow-sm flex items-center justify-center gap-3 transition-all transform active:scale-95 relative"
|
||||
>
|
||||
<span className="text-[1.1rem]">Download Report</span>
|
||||
<div className="w-6 h-6 bg-white/20 rounded-full flex items-center justify-center">
|
||||
@@ -680,36 +680,36 @@ const AnalysisResultPage = () => {
|
||||
<div className="flex flex-col gap-6">
|
||||
<div>
|
||||
<label className="block text-gray-700 text-sm font-medium mb-1">
|
||||
Full Name<span className="text-[#0097C3]">*</span>
|
||||
Full Name<span className="text-[limelite-red]">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Enter your First Name"
|
||||
value={formData.name}
|
||||
onChange={handleNameChange}
|
||||
className={`w-full border-b border-dashed py-2 text-base text-black placeholder-gray-400 focus:outline-none transition-colors bg-transparent ${formErrors.name ? 'border-[#0097C3]' : 'border-gray-400 focus:border-[#0097C3]'}`}
|
||||
className={`w-full border-b border-dashed py-2 text-base text-black placeholder-gray-400 focus:outline-none transition-colors bg-transparent ${formErrors.name ? 'border-[limelite-red]' : 'border-gray-400 focus:border-[limelite-red]'}`}
|
||||
/>
|
||||
{formErrors.name && <p className="text-[#0097C3] text-xs mt-1">{formErrors.name}</p>}
|
||||
{formErrors.name && <p className="text-[limelite-red] text-xs mt-1">{formErrors.name}</p>}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-gray-700 text-sm font-medium mb-1">
|
||||
Whatsapp Number<span className="text-[#0097C3]">*</span>
|
||||
Whatsapp Number<span className="text-[limelite-red]">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="tel"
|
||||
placeholder="Enter your Whatsapp Number"
|
||||
value={formData.phone}
|
||||
onChange={handlePhoneChange}
|
||||
className={`w-full border-b border-dashed py-2 text-base text-black placeholder-gray-400 focus:outline-none transition-colors bg-transparent ${formErrors.phone ? 'border-[#0097C3]' : 'border-gray-400 focus:border-[#0097C3]'}`}
|
||||
className={`w-full border-b border-dashed py-2 text-base text-black placeholder-gray-400 focus:outline-none transition-colors bg-transparent ${formErrors.phone ? 'border-[limelite-red]' : 'border-gray-400 focus:border-[limelite-red]'}`}
|
||||
/>
|
||||
{formErrors.phone && <p className="text-[#0097C3] text-[13px] mt-2 font-medium leading-tight">{formErrors.phone}</p>}
|
||||
{formErrors.phone && <p className="text-[limelite-red] text-[13px] mt-2 font-medium leading-tight">{formErrors.phone}</p>}
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={handleSignupSubmit}
|
||||
disabled={isSubmittingSignup}
|
||||
className="w-full bg-[#0097C3] hover:bg-[#007ba0] text-white py-3 font-semibold text-lg mt-4 transition-colors disabled:opacity-70 flex items-center justify-center h-14"
|
||||
className="w-full bg-[limelite-red] hover:bg-[limelite-maroon] text-white py-3 font-semibold text-lg mt-4 transition-colors disabled:opacity-70 flex items-center justify-center h-14"
|
||||
>
|
||||
{isSubmittingSignup ? (
|
||||
<div className="flex items-center gap-3">
|
||||
@@ -748,7 +748,7 @@ const AnalysisResultPage = () => {
|
||||
<div className="flex justify-between gap-2 mb-8">
|
||||
{otp.map((data, index) => (
|
||||
<input
|
||||
className="w-11 h-11 border border-gray-300 rounded-md text-center text-xl focus:border-[#0097C3] focus:outline-none font-medium text-black"
|
||||
className="w-11 h-11 border border-gray-300 rounded-md text-center text-xl focus:border-[limelite-red] focus:outline-none font-medium text-black"
|
||||
type="text"
|
||||
name="otp"
|
||||
maxLength="1"
|
||||
@@ -760,12 +760,12 @@ const AnalysisResultPage = () => {
|
||||
))}
|
||||
</div>
|
||||
|
||||
{otpError && <p className="text-[#0097C3] text-sm mb-4 text-center">{otpError}</p>}
|
||||
{otpError && <p className="text-[limelite-red] text-sm mb-4 text-center">{otpError}</p>}
|
||||
|
||||
<button
|
||||
onClick={handleVerifyOtp}
|
||||
disabled={isVerifying}
|
||||
className="w-full bg-[#0097C3] hover:bg-[#007ba0] text-white py-4 font-semibold text-lg transition-colors disabled:opacity-70 flex items-center justify-center"
|
||||
className="w-full bg-[limelite-red] hover:bg-[limelite-maroon] text-white py-4 font-semibold text-lg transition-colors disabled:opacity-70 flex items-center justify-center"
|
||||
>
|
||||
{isVerifying ? (
|
||||
<div className="w-6 h-6 border-2 border-white/30 border-t-white rounded-full animate-spin"></div>
|
||||
@@ -813,9 +813,9 @@ const AnalysisResultPage = () => {
|
||||
{/* Toast Notification */}
|
||||
{toast.show && (
|
||||
<div className="fixed top-24 right-6 z-[200] animate-[fadeIn_0.3s_ease-out]">
|
||||
<div className="bg-white text-[#0097C3] px-6 py-4 shadow-[0_10px_40px_rgba(0,0,0,0.15)] flex items-center gap-3 border-l-4 border-[#0097C3]">
|
||||
<div className="bg-[#0097C3]/10 p-1.5 rounded-full">
|
||||
<svg className="w-5 h-5 text-[#0097C3]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<div className="bg-white text-[limelite-red] px-6 py-4 shadow-[0_10px_40px_rgba(0,0,0,0.15)] flex items-center gap-3 border-l-4 border-[limelite-red]">
|
||||
<div className="bg-[limelite-red]/10 p-1.5 rounded-full">
|
||||
<svg className="w-5 h-5 text-[limelite-red]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</div>
|
||||
@@ -844,13 +844,13 @@ const AnalysisResultPage = () => {
|
||||
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} style={{ height: '45px', objectFit: 'contain' }} alt="Logo" />
|
||||
</div>
|
||||
<div style={{ flex: 1, textAlign: 'center' }}>
|
||||
<h1 style={{ fontSize: '28px', fontWeight: '900', margin: 0, textTransform: 'uppercase', letterSpacing: '0.02em', color: '#0097C3', fontFamily: "'Playfair Display', serif" }}>Face Analysis Report</h1>
|
||||
<h1 style={{ fontSize: '28px', fontWeight: '900', margin: 0, textTransform: 'uppercase', letterSpacing: '0.02em', color: 'limelite-red', fontFamily: "'Playfair Display', serif" }}>Face Analysis Report</h1>
|
||||
</div>
|
||||
<div style={{ width: '120px' }}></div>
|
||||
</div>
|
||||
|
||||
{/* Accent Line */}
|
||||
<div style={{ height: '2px', backgroundColor: '#0097C3', marginBottom: '25px' }}></div>
|
||||
<div style={{ height: '2px', backgroundColor: 'limelite-red', marginBottom: '25px' }}></div>
|
||||
|
||||
{/* Info Row (Name, Phone, Date) */}
|
||||
<div style={{ backgroundColor: '#f3f4f6', padding: '18px 25px', display: 'flex', justifyContent: 'space-between', marginBottom: '30px' }}>
|
||||
@@ -882,7 +882,7 @@ const AnalysisResultPage = () => {
|
||||
width: '100%',
|
||||
height: '320px',
|
||||
overflow: 'hidden',
|
||||
border: '4px solid #0097C3'
|
||||
border: '4px solid limelite-red'
|
||||
}}>
|
||||
<img src={analysisData?.originalImage} style={{ width: '100%', height: '100%', objectFit: 'cover' }} alt="Original Scan" />
|
||||
</div>
|
||||
@@ -890,7 +890,7 @@ const AnalysisResultPage = () => {
|
||||
position: 'absolute',
|
||||
bottom: '15px',
|
||||
right: '15px',
|
||||
backgroundColor: '#0097C3',
|
||||
backgroundColor: 'limelite-red',
|
||||
color: '#fff',
|
||||
padding: '6px 15px',
|
||||
fontSize: '10px',
|
||||
@@ -903,7 +903,7 @@ const AnalysisResultPage = () => {
|
||||
<div style={{ flex: '0.6', display: 'flex', flexDirection: 'column' }}>
|
||||
<div style={{
|
||||
flex: 1,
|
||||
backgroundColor: '#0097C3',
|
||||
backgroundColor: 'limelite-red',
|
||||
color: '#fff',
|
||||
padding: '20px 15px',
|
||||
display: 'flex',
|
||||
@@ -933,7 +933,7 @@ const AnalysisResultPage = () => {
|
||||
alignItems: 'center',
|
||||
gap: '10px'
|
||||
}}>
|
||||
<span style={{ height: '15px', width: '15px', display: 'inline-block', border: '3px solid #0097C3' }}></span>
|
||||
<span style={{ height: '15px', width: '15px', display: 'inline-block', border: '3px solid limelite-red' }}></span>
|
||||
Diagnostic Deep-Dive
|
||||
</h2>
|
||||
|
||||
@@ -958,7 +958,7 @@ const AnalysisResultPage = () => {
|
||||
<div style={{
|
||||
width: `${metric.ui_score}%`,
|
||||
height: '100%',
|
||||
backgroundColor: metric.ui_score >= 70 ? '#10b981' : metric.ui_score >= 40 ? '#f59e0b' : '#0097C3'
|
||||
backgroundColor: metric.ui_score >= 70 ? '#10b981' : metric.ui_score >= 40 ? '#f59e0b' : 'limelite-red'
|
||||
}}></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -977,15 +977,15 @@ const AnalysisResultPage = () => {
|
||||
<h3 style={{ margin: '0 0 15px 0', fontSize: '14px', fontWeight: '900', color: '#1a1a1a', textTransform: 'uppercase', letterSpacing: '1px' }}>Prescriptive Guidance</h3>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '15px' }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
|
||||
<span style={{ fontSize: '10px', fontWeight: '900', color: '#0097C3' }}>STEP 01</span>
|
||||
<span style={{ fontSize: '10px', fontWeight: '900', color: 'limelite-red' }}>STEP 01</span>
|
||||
<p style={{ margin: 0, fontSize: '11px', color: '#555', lineHeight: '1.5' }}><strong>Advanced Hydration:</strong> Apply hyaluronic acid serum daily to stabilize moisture levels.</p>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
|
||||
<span style={{ fontSize: '10px', fontWeight: '900', color: '#0097C3' }}>STEP 02</span>
|
||||
<span style={{ fontSize: '10px', fontWeight: '900', color: 'limelite-red' }}>STEP 02</span>
|
||||
<p style={{ margin: 0, fontSize: '11px', color: '#555', lineHeight: '1.5' }}><strong>Dermal Protection:</strong> Broad-spectrum physical sunshade is mandatory for UV protection.</p>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
|
||||
<span style={{ fontSize: '10px', fontWeight: '900', color: '#0097C3' }}>STEP 03</span>
|
||||
<span style={{ fontSize: '10px', fontWeight: '900', color: 'limelite-red' }}>STEP 03</span>
|
||||
<p style={{ margin: 0, fontSize: '11px', color: '#555', lineHeight: '1.5' }}><strong>Clinical Intervention:</strong> Visit your specialist for focused treatment on top priority zones.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+31
-48
@@ -41,7 +41,7 @@ const App = () => {
|
||||
|
||||
// --- Load skin-api models ---
|
||||
useEffect(() => {
|
||||
console.log(`%c Build Version: ${buildInfo.version} | Date: ${buildInfo.date}`, 'color: #0097C3; font-weight: bold; font-size: 14px;');
|
||||
console.log(`%c Build Version: ${buildInfo.version} | Date: ${buildInfo.date}`, 'color: limelite-red; font-weight: bold; font-size: 14px;');
|
||||
const loadModels = async () => {
|
||||
await Promise.all([
|
||||
skinapi.nets.tinyFaceDetector.loadFromUri(process.env.PUBLIC_URL + '/models'),
|
||||
@@ -391,13 +391,13 @@ const App = () => {
|
||||
|
||||
// --- Render ---
|
||||
return (
|
||||
<div className="min-h-screen relative overflow-hidden bg-[#F8F9FA]">
|
||||
<div className="min-h-screen relative overflow-hidden bg-gradient-to-r from-limelite-maroon to-limelite-dark text-white">
|
||||
<div className="container mx-auto px-4 py-10 md:py-16 relative z-10 min-h-screen flex flex-col items-center justify-start gap-4 md:gap-8">
|
||||
|
||||
{/* Header */}
|
||||
<header className="fixed top-0 left-0 right-0 z-[60] py-4 px-6 flex items-center justify-between bg-[#0097C3] shadow-lg">
|
||||
<header className="fixed top-0 left-0 right-0 z-[60] py-4 px-6 flex items-center justify-between bg-[limelite-red] shadow-lg">
|
||||
<div className="flex items-center gap-4">
|
||||
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="Limelite Logo" className="h-12 md:h-16 w-auto brightness-0 invert" />
|
||||
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="Limelite Logo" className="h-12 md:h-16 w-auto " />
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
@@ -444,62 +444,45 @@ const App = () => {
|
||||
{view === 'landing' && (
|
||||
<div className="flex flex-col items-center justify-center w-full px-4 gap-8 fade-in mt-20 md:mt-32">
|
||||
<div className="text-center space-y-4 mb-2">
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-[#0e5e73] leading-tight tracking-[0.02em] uppercase" style={{ fontFamily: "'Oswald', sans-serif" }}>
|
||||
AI-POWERED<br />FACE ANALYZER
|
||||
<h1 className="text-4xl md:text-5xl font-serif italic text-white leading-tight tracking-[0.02em]">
|
||||
Step into your style
|
||||
</h1>
|
||||
<p className="text-lg text-gray-700 font-medium tracking-wide max-w-sm mx-auto">
|
||||
Experience professional-grade face analysis in seconds
|
||||
<p className="text-xs text-gray-300 font-sans font-bold tracking-widest uppercase mt-4 max-w-sm mx-auto">
|
||||
Select your action to begin
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Action Buttons Container */}
|
||||
<div className="w-full flex flex-col gap-4">
|
||||
<div className="w-full flex flex-row items-center justify-center gap-4 max-w-md mx-auto">
|
||||
{/* Take Photo Card */}
|
||||
<div
|
||||
<button
|
||||
onClick={() => setView('camera')}
|
||||
className="bg-white border-2 border-dashed border-[#0097C3]/30 p-8 flex flex-col items-center justify-center gap-4 cursor-pointer hover:border-[#0097C3] transition-all duration-300 shadow-xl group"
|
||||
className="flex-1 bg-white text-[#1A1A1A] rounded-xl px-8 py-4 font-bold text-sm tracking-widest uppercase shadow-lg hover:bg-gray-100 transition-all text-center border-2 border-transparent"
|
||||
>
|
||||
<div className="w-16 h-16 bg-[#0097C3]/10 rounded-full flex items-center justify-center group-hover:scale-110 transition-transform">
|
||||
<svg className="w-8 h-8 text-[#0097C3]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M15 13a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<p className="text-xl font-bold text-black uppercase tracking-widest">Take a Photo</p>
|
||||
<p className="text-gray-500 text-sm mt-1">Capture using your camera</p>
|
||||
</div>
|
||||
</div>
|
||||
Take Photo
|
||||
</button>
|
||||
|
||||
{/* Upload Photo Card */}
|
||||
<div
|
||||
<button
|
||||
onClick={() => document.getElementById('uploadInput').click()}
|
||||
className="bg-white border-2 border-dashed border-[#0097C3]/30 p-8 flex flex-col items-center justify-center gap-4 cursor-pointer hover:border-[#0097C3] transition-all duration-300 shadow-xl group"
|
||||
className="flex-1 bg-[#1A1A1A] text-white border border-gray-700 rounded-xl px-8 py-4 font-bold text-sm tracking-widest uppercase shadow-lg hover:bg-black transition-all text-center"
|
||||
>
|
||||
<div className="w-16 h-16 bg-[#0097C3]/10 rounded-full flex items-center justify-center group-hover:scale-110 transition-transform">
|
||||
<svg className="w-8 h-8 text-[#0097C3]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<p className="text-xl font-bold text-black uppercase tracking-widest">Upload Photo</p>
|
||||
<p className="text-gray-500 text-sm mt-1">Select from your gallery</p>
|
||||
</div>
|
||||
<input
|
||||
type="file"
|
||||
id="uploadInput"
|
||||
accept="image/*"
|
||||
className="hidden"
|
||||
onChange={handleFileUpload}
|
||||
/>
|
||||
</div>
|
||||
Upload Photo
|
||||
</button>
|
||||
<input
|
||||
type="file"
|
||||
id="uploadInput"
|
||||
accept="image/*"
|
||||
className="hidden"
|
||||
onChange={handleFileUpload}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Admin Link */}
|
||||
<div className="mt-8">
|
||||
<button
|
||||
onClick={() => navigate('/login')}
|
||||
className="text-gray-400 hover:text-[#0097C3] transition-colors text-xs uppercase tracking-widest font-bold"
|
||||
className="text-gray-400 hover:text-[limelite-red] transition-colors text-xs uppercase tracking-widest font-bold"
|
||||
>
|
||||
Admin Login
|
||||
</button>
|
||||
@@ -521,7 +504,7 @@ const App = () => {
|
||||
<div className="absolute bottom-12 left-0 right-0 flex justify-center items-center z-20">
|
||||
<button
|
||||
onClick={handleCaptureskin}
|
||||
className="transform active:scale-95 transition-all cursor-pointer bg-[#0097C3] w-36 h-18 py-4 px-10 rounded-full shadow-[0_0_20px_rgba(0,151,195,0.3)] flex items-center justify-center border-none"
|
||||
className="transform active:scale-95 transition-all cursor-pointer bg-[limelite-red] w-36 h-18 py-4 px-10 rounded-full shadow-[0_0_20px_rgba(0,151,195,0.3)] flex items-center justify-center border-none"
|
||||
>
|
||||
<IoMdAperture className="w-12 h-12 text-white" />
|
||||
</button>
|
||||
@@ -545,8 +528,8 @@ const App = () => {
|
||||
{/* Scanning Animation only when loading */}
|
||||
{isLoading && (
|
||||
<div className="absolute inset-0 z-20 pointer-events-none overflow-hidden">
|
||||
<div className="w-full h-[2px] bg-[#0097C3] shadow-[0_0_20px_rgba(0,151,195,0.8)] absolute top-0 animate-[scan_3s_linear_infinite]"></div>
|
||||
<div className="w-full h-32 bg-gradient-to-t from-[#0097C3]/20 to-transparent absolute top-0 -translate-y-full animate-[scanTrace_3s_linear_infinite]"></div>
|
||||
<div className="w-full h-[2px] bg-[limelite-red] shadow-[0_0_20px_rgba(0,151,195,0.8)] absolute top-0 animate-[scan_3s_linear_infinite]"></div>
|
||||
<div className="w-full h-32 bg-gradient-to-t from-[limelite-red]/20 to-transparent absolute top-0 -translate-y-full animate-[scanTrace_3s_linear_infinite]"></div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -570,7 +553,7 @@ const App = () => {
|
||||
<button
|
||||
onClick={handleSubmitClick}
|
||||
disabled={isLoading}
|
||||
className="h-14 w-20 bg-[#0097C3] text-white rounded-none flex items-center justify-center shadow-lg hover:bg-[#007ba0] transition-all active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
className="h-14 w-20 bg-[limelite-red] text-white rounded-none flex items-center justify-center shadow-lg hover:bg-[limelite-maroon] transition-all active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
aria-label="Confirm"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@@ -590,7 +573,7 @@ const App = () => {
|
||||
<div className="fixed inset-0 z-[100] flex items-center justify-center bg-black/80 backdrop-blur-sm p-6 animate-[fadeIn_0.2s_ease-out]">
|
||||
<div className="bg-white rounded-none shadow-2xl w-full max-w-sm p-8 text-center">
|
||||
<div className="w-16 h-16 bg-cyan-100 rounded-full flex items-center justify-center mx-auto mb-6">
|
||||
<svg className="w-8 h-8 text-[#0097C3]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<svg className="w-8 h-8 text-[limelite-red]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
</div>
|
||||
@@ -603,7 +586,7 @@ const App = () => {
|
||||
</p>
|
||||
<button
|
||||
onClick={handleRetakeClick}
|
||||
className="w-full bg-[#0097C3] text-white font-bold py-4 px-6 rounded-none hover:bg-[#007ba0] transition-all active:scale-95 uppercase tracking-widest text-sm"
|
||||
className="w-full bg-[limelite-red] text-white font-bold py-4 px-6 rounded-none hover:bg-[limelite-maroon] transition-all active:scale-95 uppercase tracking-widest text-sm"
|
||||
>
|
||||
Retake Photo
|
||||
</button>
|
||||
|
||||
@@ -101,7 +101,7 @@ const DashboardPage = () => {
|
||||
return (
|
||||
<div className="flex h-screen bg-[#F8F9FA] font-sans">
|
||||
{/* Sidebar */}
|
||||
<aside className="w-64 bg-[#0097C3] text-white flex flex-col shrink-0">
|
||||
<aside className="w-64 bg-[limelite-red] text-white flex flex-col shrink-0">
|
||||
<div className="p-6 mb-4">
|
||||
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="LIMELITE" className="h-10 w-auto brightness-0 invert" />
|
||||
</div>
|
||||
@@ -109,7 +109,7 @@ const DashboardPage = () => {
|
||||
<nav className="flex-1 px-0 mt-4">
|
||||
<div
|
||||
onClick={() => setActiveTab('reports')}
|
||||
className={`flex items-center gap-3 px-6 py-4 cursor-pointer transition-colors ${activeTab === 'reports' ? 'bg-white text-[#0097C3]' : 'text-white hover:bg-white/10'}`}
|
||||
className={`flex items-center gap-3 px-6 py-4 cursor-pointer transition-colors ${activeTab === 'reports' ? 'bg-white text-[limelite-red]' : 'text-white hover:bg-white/10'}`}
|
||||
>
|
||||
<HiOutlineDocumentText className="text-xl" />
|
||||
<span className="font-bold uppercase tracking-wider text-xs">Reports</span>
|
||||
@@ -126,14 +126,14 @@ const DashboardPage = () => {
|
||||
<div className="px-0 space-y-0 mb-6 border-t border-white/10">
|
||||
<div
|
||||
onClick={() => setActiveTab('settings')}
|
||||
className={`flex items-center gap-3 px-6 py-4 cursor-pointer transition-colors ${activeTab === 'settings' ? 'bg-white text-[#0097C3]' : 'text-white hover:bg-white/10'}`}
|
||||
className={`flex items-center gap-3 px-6 py-4 cursor-pointer transition-colors ${activeTab === 'settings' ? 'bg-white text-[limelite-red]' : 'text-white hover:bg-white/10'}`}
|
||||
>
|
||||
<FiSettings className="text-xl" />
|
||||
<span className="font-bold uppercase tracking-wider text-xs">Settings</span>
|
||||
</div>
|
||||
<div className="hover:bg-white/10 text-white flex items-center gap-3 px-6 py-5 transition-colors cursor-pointer border-t border-white/10">
|
||||
<div className="flex items-center gap-3 w-full">
|
||||
<div className="w-10 h-10 bg-[#0086ad] rounded-full flex items-center justify-center overflow-hidden border border-white/30 text-white font-bold text-sm">
|
||||
<div className="w-10 h-10 bg-[limelite-maroon] rounded-full flex items-center justify-center overflow-hidden border border-white/30 text-white font-bold text-sm">
|
||||
LA
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
@@ -166,7 +166,7 @@ const DashboardPage = () => {
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search"
|
||||
className="w-full bg-gray-50 border border-gray-200 rounded-lg py-2 pl-10 pr-4 focus:outline-none focus:ring-1 focus:ring-[#0097C3] text-sm text-gray-900"
|
||||
className="w-full bg-gray-50 border border-gray-200 rounded-lg py-2 pl-10 pr-4 focus:outline-none focus:ring-1 focus:ring-[limelite-red] text-sm text-gray-900"
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
/>
|
||||
@@ -199,7 +199,7 @@ const DashboardPage = () => {
|
||||
<td className="px-6 py-4 text-sm text-gray-500 font-medium">{(currentPage - 1) * ITEMS_PER_PAGE + index + 1}</td>
|
||||
<td className="px-6 py-4 text-sm font-medium text-gray-700">{report.name}</td>
|
||||
<td className="px-6 py-4 text-sm text-gray-500">{report.phone}</td>
|
||||
<td className="px-6 py-4 text-sm text-[#0097C3] font-semibold truncate max-w-[200px]">
|
||||
<td className="px-6 py-4 text-sm text-[limelite-red] font-semibold truncate max-w-[200px]">
|
||||
<a href={report.link} target="_blank" rel="noopener noreferrer" className="hover:underline">
|
||||
{report.link ? report.link.substring(report.link.indexOf('result')) : '-'}
|
||||
</a>
|
||||
@@ -244,7 +244,7 @@ const DashboardPage = () => {
|
||||
<label className="text-sm font-bold text-gray-700 uppercase">Site Name</label>
|
||||
<input
|
||||
type="text"
|
||||
className="col-span-2 border-b-2 py-2 focus:outline-none focus:border-[#0097C3] transition-colors"
|
||||
className="col-span-2 border-b-2 py-2 focus:outline-none focus:border-[limelite-red] transition-colors"
|
||||
value={settings.siteName}
|
||||
onChange={(e) => setSettings({ ...settings, siteName: e.target.value })}
|
||||
/>
|
||||
@@ -280,14 +280,14 @@ const DashboardPage = () => {
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setSettings({ ...settings, autoArchive: !settings.autoArchive })}
|
||||
className={`w-12 h-6 rounded-full transition-colors relative ${settings.autoArchive ? 'bg-[#0097C3]' : 'bg-gray-300'}`}
|
||||
className={`w-12 h-6 rounded-full transition-colors relative ${settings.autoArchive ? 'bg-[limelite-red]' : 'bg-gray-300'}`}
|
||||
>
|
||||
<div className={`absolute top-1 bg-white w-4 h-4 rounded-full transition-transform ${settings.autoArchive ? 'translate-x-7' : 'translate-x-1'}`}></div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="pt-6">
|
||||
<button className="bg-[#0097C3] text-white px-8 py-3 font-bold uppercase tracking-widest hover:bg-[#007ba0] transition-colors">
|
||||
<button className="bg-[limelite-red] text-white px-8 py-3 font-bold uppercase tracking-widest hover:bg-[limelite-maroon] transition-colors">
|
||||
Save Changes
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -23,12 +23,12 @@ const LoginPage = () => {
|
||||
<div className="min-h-screen bg-[#18181b] flex items-center justify-center p-4 font-sans">
|
||||
<div className="bg-white w-full max-w-md p-10 shadow-2xl rounded-none">
|
||||
<div className="flex flex-col items-center mb-10">
|
||||
<div className="bg-[#0097C3] p-4 mb-6">
|
||||
<div className="bg-[limelite-red] p-4 mb-6">
|
||||
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="Limelite" className="h-8 brightness-0 invert" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{error && <p className="text-[#0097C3] text-sm font-bold text-center mb-6 animate-shake">{error}</p>}
|
||||
{error && <p className="text-[limelite-red] text-sm font-bold text-center mb-6 animate-shake">{error}</p>}
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
<div>
|
||||
@@ -36,7 +36,7 @@ const LoginPage = () => {
|
||||
<input
|
||||
type="email"
|
||||
required
|
||||
className="w-full border-b-2 border-gray-200 py-3 focus:outline-none focus:border-[#0097C3] transition-colors text-black"
|
||||
className="w-full border-b-2 border-gray-200 py-3 focus:outline-none focus:border-[limelite-red] transition-colors text-black"
|
||||
placeholder="olivia@limelite.com"
|
||||
value={credentials.email}
|
||||
onChange={(e) => setCredentials({ ...credentials, email: e.target.value })}
|
||||
@@ -48,7 +48,7 @@ const LoginPage = () => {
|
||||
<input
|
||||
type={showPassword ? "text" : "password"}
|
||||
required
|
||||
className="w-full border-b-2 border-gray-200 py-3 pr-10 focus:outline-none focus:border-[#0097C3] transition-colors text-black"
|
||||
className="w-full border-b-2 border-gray-200 py-3 pr-10 focus:outline-none focus:border-[limelite-red] transition-colors text-black"
|
||||
placeholder="••••••••"
|
||||
value={credentials.password}
|
||||
onChange={(e) => setCredentials({ ...credentials, password: e.target.value })}
|
||||
@@ -64,7 +64,7 @@ const LoginPage = () => {
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full bg-[#0097C3] text-white py-4 font-bold uppercase tracking-widest hover:bg-[#007ba0] transition-colors mt-4"
|
||||
className="w-full bg-[limelite-red] text-white py-4 font-bold uppercase tracking-widest hover:bg-[limelite-maroon] transition-colors mt-4"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
|
||||
@@ -105,7 +105,7 @@ const UploadAnalysis = ({ originalImageUrl }) => {
|
||||
fontSize: "16px",
|
||||
cursor: "pointer",
|
||||
borderRadius: "8px",
|
||||
backgroundColor: "#0097C3",
|
||||
backgroundColor: "limelite-red",
|
||||
border: "none",
|
||||
color: "white",
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user