forked from bobbysheikhrahmansheikh-coder/Pak-Legal-Services
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathApp.tsx
More file actions
255 lines (232 loc) · 13.6 KB
/
Copy pathApp.tsx
File metadata and controls
255 lines (232 loc) · 13.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
import React, { useState, useEffect } from 'react';
import Navbar from './components/Navbar.tsx';
import Hero from './components/Hero.tsx';
import ServiceCard from './components/ServiceCard.tsx';
import Testimonials from './components/Testimonials.tsx';
import ChatBot from './components/ChatBot.tsx';
import Footer from './components/Footer.tsx';
import AdminPanel from './components/AdminPanel.tsx';
import ContactForm from './components/ContactForm.tsx';
import {
SERVICES as DEFAULT_SERVICES,
CLIENT_NAME as DEFAULT_NAME,
PHONE_NUMBER as DEFAULT_PHONE,
EMAIL as DEFAULT_EMAIL,
LOCATION as DEFAULT_LOCATION
} from './constants.tsx';
import { ServiceCategory, AppSettings } from './types';
const App: React.FC = () => {
const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false);
const [showLoginModal, setShowLoginModal] = useState(false);
const [password, setPassword] = useState('');
const [error, setError] = useState('');
// Dynamic State for all content
const [services, setServices] = useState<ServiceCategory[]>(DEFAULT_SERVICES);
const [settings, setSettings] = useState<AppSettings>({
clientName: DEFAULT_NAME,
phoneNumber: DEFAULT_PHONE,
email: DEFAULT_EMAIL,
location: DEFAULT_LOCATION
});
const loadData = () => {
// Load services
const savedServices = localStorage.getItem('pls_managed_services');
if (savedServices) {
setServices(JSON.parse(savedServices));
} else {
setServices(DEFAULT_SERVICES);
}
// Load settings
const savedSettings = localStorage.getItem('pls_app_settings');
if (savedSettings) {
setSettings(JSON.parse(savedSettings));
}
};
useEffect(() => {
loadData();
}, [isAdminLoggedIn]);
const handleLogin = (e: React.FormEvent) => {
e.preventDefault();
const storedPassword = localStorage.getItem('pls_admin_password') || 'admin123';
if (password === storedPassword) {
setIsAdminLoggedIn(true);
setShowLoginModal(false);
setPassword('');
setError('');
window.scrollTo(0, 0);
} else {
setError('Incorrect password. Access denied.');
}
};
if (isAdminLoggedIn) {
return <AdminPanel onLogout={() => setIsAdminLoggedIn(false)} />;
}
return (
<div className="min-h-screen relative">
<Navbar
onAdminClick={() => setShowLoginModal(true)}
settings={settings}
/>
<main>
<Hero settings={settings} />
{/* Services Section */}
<section id="services" className="py-24 bg-white scroll-mt-24">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-extrabold text-slate-900 mb-4">
Our Comprehensive Services
</h2>
<div className="w-20 h-1.5 bg-emerald-600 mx-auto rounded-full mb-6"></div>
<p className="text-slate-600 max-w-2xl mx-auto text-lg">
Whatever your documentation or legal requirements, {settings.clientName} and Pak Legal Services provide expert, fast, and reliable solutions.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
{services.map((category) => (
<ServiceCard key={category.id} category={category} settings={settings} />
))}
</div>
</div>
</section>
{/* About Section */}
<section id="about" className="py-24 bg-slate-50 overflow-hidden scroll-mt-24">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex flex-col lg:flex-row items-center gap-16">
<div className="flex-1 relative">
<div className="relative z-10 rounded-3xl overflow-hidden shadow-2xl">
<img src="https://images.unsplash.com/photo-1589829545856-d10d557cf95f?auto=format&fit=crop&q=80&w=800" alt="Professional Documentation" className="w-full h-auto" />
</div>
<div className="absolute -bottom-6 -right-6 w-32 h-32 bg-emerald-600 rounded-2xl -z-0"></div>
<div className="absolute -top-6 -left-6 w-48 h-48 bg-blue-100 rounded-full -z-0 blur-2xl"></div>
</div>
<div className="flex-1">
<h2 className="text-4xl font-bold text-slate-900 mb-8 leading-tight">
Why Choose <span className="text-emerald-600">Pak Legal Services</span>?
</h2>
<div className="space-y-8">
<div className="flex gap-5">
<div className="w-12 h-12 bg-white rounded-xl shadow-md flex-shrink-0 flex items-center justify-center text-emerald-600">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/></svg>
</div>
<div>
<h4 className="font-bold text-lg mb-1">Guaranteed Compliance</h4>
<p className="text-slate-600 text-sm leading-relaxed">We stay updated with latest FBR and NADRA regulations to ensure your documents are 100% accurate.</p>
</div>
</div>
<div className="flex gap-5">
<div className="w-12 h-12 bg-white rounded-xl shadow-md flex-shrink-0 flex items-center justify-center text-emerald-600">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
</div>
<div>
<h4 className="font-bold text-lg mb-1">Rapid Turnaround</h4>
<p className="text-slate-600 text-sm leading-relaxed">We value your time. Most digital services are processed within 24-48 hours with regular updates.</p>
</div>
</div>
<div className="flex gap-5">
<div className="w-12 h-12 bg-white rounded-xl shadow-md flex-shrink-0 flex items-center justify-center text-emerald-600">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M17 8h2a2 2 0 012 2v6a2 2 0 01-2 2h-2v4l-4-4H9l-4 4v-4H3a2 2 0 01-2-2V10a2 2 0 012-2h2M9 21h6"/></svg>
</div>
<div>
<h4 className="font-bold text-lg mb-1">Personalized Support</h4>
<p className="text-slate-600 text-sm leading-relaxed">Direct access to {settings.clientName} for specialized legal consultations and urgent documentation.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
{/* Testimonials */}
<Testimonials />
{/* Contact Section */}
<section id="contact" className="py-24 bg-white scroll-mt-24">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="bg-emerald-600 rounded-[3rem] p-10 md:p-20 text-white relative overflow-hidden shadow-2xl">
<div className="absolute top-0 right-0 w-96 h-96 bg-white/10 rounded-full -translate-y-1/2 translate-x-1/2 blur-3xl"></div>
<div className="absolute bottom-0 left-0 w-64 h-64 bg-emerald-400/20 rounded-full translate-y-1/2 -translate-x-1/2 blur-2xl"></div>
<div className="relative z-10 flex flex-col lg:flex-row justify-between items-center gap-12 text-center lg:text-left">
<div className="max-w-xl">
<h2 className="text-4xl md:text-5xl font-extrabold mb-6">Need Urgent Help?</h2>
<p className="text-emerald-50 text-xl opacity-90 mb-8 leading-relaxed">
Contact {settings.clientName} now for immediate assistance with any FBR, NADRA, or Legal document.
</p>
<div className="flex flex-col sm:flex-row gap-6 justify-center lg:justify-start">
<div className="flex items-center gap-4 bg-white/10 p-4 rounded-2xl backdrop-blur-sm">
<div className="w-12 h-12 bg-white rounded-full flex items-center justify-center text-emerald-600">
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12c0 1.73.44 3.36 1.21 4.79L2 22l5.35-1.39C8.75 21.4 10.33 22 12 22c5.52 0 10-4.48 10-10S17.52 2 12 2z"/></svg>
</div>
<div>
<p className="text-xs text-emerald-200 uppercase font-bold tracking-wider">WhatsApp</p>
<p className="text-lg font-bold">{settings.phoneNumber}</p>
</div>
</div>
<div className="flex items-center gap-4 bg-white/10 p-4 rounded-2xl backdrop-blur-sm">
<div className="w-12 h-12 bg-white rounded-full flex items-center justify-center text-emerald-600">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" /></svg>
</div>
<div>
<p className="text-xs text-emerald-200 uppercase font-bold tracking-wider">Email Us</p>
<p className="text-lg font-bold">{settings.email}</p>
</div>
</div>
</div>
</div>
<ContactForm settings={settings} />
</div>
</div>
</div>
</section>
</main>
<Footer
onAdminClick={() => setShowLoginModal(true)}
settings={settings}
/>
<ChatBot settings={settings} />
{/* WhatsApp Floating Button */}
<a
href={`https://wa.me/${settings.phoneNumber.replace(/[^0-9]/g, '')}`}
target="_blank"
rel="noopener noreferrer"
className="fixed bottom-24 right-6 bg-[#25D366] text-white w-14 h-14 rounded-full flex items-center justify-center shadow-2xl hover:scale-110 transition-transform z-50 animate-bounce"
>
<svg className="w-8 h-8" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2C6.48 2 2 6.48 2 12c0 1.73.44 3.36 1.21 4.79L2 22l5.35-1.39C8.75 21.4 10.33 22 12 22c5.52 0 10-4.48 10-10S17.52 2 12 2zM12 20.2c-1.59 0-3.15-.42-4.52-1.22l-.33-.18-3.34.87.89-3.26-.2-.32c-.88-1.42-1.34-3.07-1.34-4.76 0-5.11 4.15-9.26 9.26-9.26s9.26 4.15 9.26 9.26-4.15 9.27-9.26 9.27zm5.08-6.93c-.28-.14-1.64-.81-1.9-.9-.26-.1-.44-.14-.63.14-.19.28-.73.9-.9.1.1-.28-.1-.47-.28-.38-.09-.28-1.18-.44-2.24-1.39-.83-.73-1.39-1.63-1.55-1.92-.16-.29-.02-.45.13-.59.13-.13.29-.33.43-.5.14-.17.19-.29.28-.48.1-.19.05-.36-.02-.5-.07-.14-.63-1.52-.86-2.09-.23-.55-.46-.48-.63-.49-.16-.01-.35-.01-.54-.01-.19 0-.51.07-.77.36-.26.29-.98.96-.98 2.34 0 1.38 1.01 2.71 1.15 2.9.14.19 1.98 3.03 4.81 4.25.67.29 1.2.46 1.6.59.68.21 1.29.18 1.78.11.54-.08 1.64-.67 1.87-1.31.23-.64.23-1.19.16-1.31-.07-.11-.26-.18-.54-.32z"/>
</svg>
</a>
{/* Admin Login Modal */}
{showLoginModal && (
<div className="fixed inset-0 z-[100] flex items-center justify-center p-4">
<div className="absolute inset-0 bg-slate-900/90 backdrop-blur-sm" onClick={() => setShowLoginModal(false)}></div>
<div className="bg-white w-full max-w-sm rounded-[2rem] p-10 relative z-10 shadow-2xl animate-in zoom-in-95 duration-200">
<div className="text-center mb-8">
<div className="w-16 h-16 bg-emerald-600 rounded-2xl flex items-center justify-center text-white text-2xl font-bold mx-auto mb-4">
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/></svg>
</div>
<h3 className="text-2xl font-black text-slate-900">Admin Portal</h3>
<p className="text-slate-500 mt-1">Please enter your master password</p>
</div>
<form onSubmit={handleLogin} className="space-y-6">
<div>
<input
type="password"
autoFocus
required
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Master Password"
className="w-full px-5 py-4 bg-slate-50 border border-slate-200 rounded-2xl text-center text-lg focus:outline-none focus:ring-4 focus:ring-emerald-500/10 focus:border-emerald-500 transition-all font-mono"
/>
{error && <p className="text-rose-500 text-sm mt-3 font-bold text-center">{error}</p>}
<p className="text-slate-300 text-[10px] mt-4 text-center">Protected for {settings.clientName}</p>
</div>
<button className="w-full py-4 bg-slate-900 text-white font-bold rounded-2xl hover:bg-slate-800 transition-all active:scale-95 shadow-xl">
Login Now
</button>
</form>
</div>
</div>
)}
</div>
);
};
export default App;