logshield-cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/android-chrome-192x192.png +0 -0
- package/dist/android-chrome-512x512.png +0 -0
- package/dist/apple-touch-icon.png +0 -0
- package/dist/assets/index-B3qxIuiz.css +1 -0
- package/dist/assets/index-DDJ1Wxio.js +29 -0
- package/dist/cli/index.cjs +402 -0
- package/dist/favicon-16x16.png +0 -0
- package/dist/favicon-32x32.png +0 -0
- package/dist/favicon.ico +0 -0
- package/dist/features.jsx +462 -0
- package/dist/index.html +16 -0
- package/dist/privacy.html +217 -0
- package/dist/refund.html +221 -0
- package/dist/robots.txt +4 -0
- package/dist/site.webmanifest +20 -0
- package/dist/terms.html +140 -0
- package/dist/utils/luhn.js +16 -0
- package/dist/vite.svg +1 -0
- package/package.json +7 -11
- package/dist/cli/cli/index.cjs +0 -54
- package/dist/cli/cli/index.js +0 -57
- package/dist/cli/cli/readInput.js +0 -27
- package/dist/cli/cli/summary.js +0 -13
- package/dist/cli/cli/writeOutput.js +0 -11
- package/dist/cli/index.js +0 -52
- package/dist/cli/package.json +0 -3
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
import { ArrowLeft, Shield, Code, Zap, Lock, FileText, BookOpen, Users, MessageCircle } from 'lucide-react';
|
|
2
|
+
|
|
3
|
+
// ============================================
|
|
4
|
+
// FEATURES PAGE
|
|
5
|
+
// ============================================
|
|
6
|
+
function FeaturesPage() {
|
|
7
|
+
const features = [
|
|
8
|
+
{
|
|
9
|
+
category: "Core Features",
|
|
10
|
+
icon: Shield,
|
|
11
|
+
items: [
|
|
12
|
+
{
|
|
13
|
+
title: "70+ Security Patterns",
|
|
14
|
+
description: "Comprehensive coverage for AWS, GCP, Azure, Stripe, MongoDB, PostgreSQL, and more. Regularly updated with new patterns."
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
title: "AI-Powered Detection",
|
|
18
|
+
description: "Advanced entropy analysis automatically detects unknown secrets and high-risk patterns that traditional regex might miss."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
title: "Batch Processing",
|
|
22
|
+
description: "Sanitize multiple files at once with drag-and-drop support. Perfect for cleaning entire log directories."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
title: "Custom Patterns",
|
|
26
|
+
description: "Add your own regex patterns for company-specific secrets or internal conventions. Save and reuse across sessions."
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
category: "Privacy & Security",
|
|
32
|
+
icon: Lock,
|
|
33
|
+
items: [
|
|
34
|
+
{
|
|
35
|
+
title: "100% Client-Side",
|
|
36
|
+
description: "All processing happens in your browser. Your logs never leave your device, ensuring complete privacy."
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
title: "Zero Data Storage",
|
|
40
|
+
description: "We don't store, log, or transmit your data. What you sanitize stays with you."
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
title: "GDPR Compliant",
|
|
44
|
+
description: "Privacy-first design that meets GDPR, CCPA, and HIPAA requirements out of the box."
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
title: "No Tracking",
|
|
48
|
+
description: "We use privacy-friendly analytics (Plausible) with no cookies or personal data collection."
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
category: "Export & Integration",
|
|
54
|
+
icon: FileText,
|
|
55
|
+
items: [
|
|
56
|
+
{
|
|
57
|
+
title: "Multiple Export Formats",
|
|
58
|
+
description: "Export sanitized logs as plain text, JSON, CSV, or PDF with detailed reports."
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
title: "API Access",
|
|
62
|
+
description: "REST API for programmatic access. Integrate LogShield into your CI/CD pipelines."
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
title: "CLI Tool",
|
|
66
|
+
description: "Command-line interface for batch processing and automation. Perfect for DevOps workflows."
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
title: "VS Code Extension",
|
|
70
|
+
description: "Sanitize logs directly in your editor. Right-click and clean without leaving your IDE."
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-slate-50">
|
|
78
|
+
<div className="container py-12">
|
|
79
|
+
<a href="/" className="inline-flex items-center gap-2 text-blue-600 hover:text-blue-700 mb-8">
|
|
80
|
+
<ArrowLeft className="h-4 w-4" />
|
|
81
|
+
Back to Home
|
|
82
|
+
</a>
|
|
83
|
+
|
|
84
|
+
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4">
|
|
85
|
+
Features that <span className="bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">empower developers</span>
|
|
86
|
+
</h1>
|
|
87
|
+
<p className="text-xl text-gray-600 mb-12 max-w-3xl">
|
|
88
|
+
Everything you need to safely share logs without compromising security
|
|
89
|
+
</p>
|
|
90
|
+
|
|
91
|
+
{features.map((section, idx) => {
|
|
92
|
+
const Icon = section.icon;
|
|
93
|
+
return (
|
|
94
|
+
<div key={idx} className="mb-16">
|
|
95
|
+
<div className="flex items-center gap-3 mb-8">
|
|
96
|
+
<div className="p-3 rounded-lg bg-gradient-to-br from-blue-500 to-purple-500">
|
|
97
|
+
<Icon className="h-6 w-6 text-white" />
|
|
98
|
+
</div>
|
|
99
|
+
<h2 className="text-3xl font-bold text-gray-900">{section.category}</h2>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
<div className="grid md:grid-cols-2 gap-6">
|
|
103
|
+
{section.items.map((item, i) => (
|
|
104
|
+
<div key={i} className="p-6 bg-white rounded-xl border border-gray-200 hover:shadow-lg transition-shadow">
|
|
105
|
+
<h3 className="text-xl font-semibold text-gray-900 mb-3">
|
|
106
|
+
{item.title}
|
|
107
|
+
</h3>
|
|
108
|
+
<p className="text-gray-600">
|
|
109
|
+
{item.description}
|
|
110
|
+
</p>
|
|
111
|
+
</div>
|
|
112
|
+
))}
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
);
|
|
116
|
+
})}
|
|
117
|
+
|
|
118
|
+
<div className="mt-16 p-8 bg-gradient-to-r from-blue-600 to-purple-600 rounded-xl text-white text-center">
|
|
119
|
+
<h2 className="text-2xl font-bold mb-4">Ready to get started?</h2>
|
|
120
|
+
<p className="text-blue-100 mb-6">Try LogShield now ? no signup required</p>
|
|
121
|
+
<a href="/#app" className="inline-block px-6 py-3 bg-white text-blue-600 rounded-lg font-medium hover:bg-gray-100 transition-colors">
|
|
122
|
+
Start Sanitizing Free
|
|
123
|
+
</a>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ============================================
|
|
131
|
+
// DOCUMENTATION PAGE
|
|
132
|
+
// ============================================
|
|
133
|
+
function DocsPage() {
|
|
134
|
+
const sections = [
|
|
135
|
+
{
|
|
136
|
+
title: "Getting Started",
|
|
137
|
+
content: [
|
|
138
|
+
{ title: "Quick Start", desc: "Get up and running in 2 minutes" },
|
|
139
|
+
{ title: "How It Works", desc: "Understanding the sanitization process" },
|
|
140
|
+
{ title: "Supported Patterns", desc: "Complete list of 70+ patterns" }
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
title: "Usage Guides",
|
|
145
|
+
content: [
|
|
146
|
+
{ title: "Basic Sanitization", desc: "Paste, click, done" },
|
|
147
|
+
{ title: "Batch Processing", desc: "Handle multiple files at once" },
|
|
148
|
+
{ title: "Custom Patterns", desc: "Create your own patterns" },
|
|
149
|
+
{ title: "Export Options", desc: "Choose the right format" }
|
|
150
|
+
]
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
title: "API Reference",
|
|
154
|
+
content: [
|
|
155
|
+
{ title: "Authentication", desc: "Using API keys" },
|
|
156
|
+
{ title: "Endpoints", desc: "Available API endpoints" },
|
|
157
|
+
{ title: "Rate Limits", desc: "Understanding limits" },
|
|
158
|
+
{ title: "Error Handling", desc: "Common errors and fixes" }
|
|
159
|
+
]
|
|
160
|
+
}
|
|
161
|
+
];
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-slate-50">
|
|
165
|
+
<div className="container py-12">
|
|
166
|
+
<a href="/" className="inline-flex items-center gap-2 text-blue-600 hover:text-blue-700 mb-8">
|
|
167
|
+
<ArrowLeft className="h-4 w-4" />
|
|
168
|
+
Back to Home
|
|
169
|
+
</a>
|
|
170
|
+
|
|
171
|
+
<div className="grid lg:grid-cols-4 gap-8">
|
|
172
|
+
{/* Sidebar */}
|
|
173
|
+
<div className="lg:col-span-1">
|
|
174
|
+
<div className="sticky top-24 p-6 bg-white rounded-xl border border-gray-200">
|
|
175
|
+
<h3 className="font-semibold text-gray-900 mb-4 flex items-center gap-2">
|
|
176
|
+
<BookOpen className="h-5 w-5 text-blue-600" />
|
|
177
|
+
Documentation
|
|
178
|
+
</h3>
|
|
179
|
+
<nav className="space-y-2">
|
|
180
|
+
{sections.map((section, idx) => (
|
|
181
|
+
<div key={idx}>
|
|
182
|
+
<button className="text-sm text-gray-700 hover:text-blue-600 font-medium w-full text-left py-2">
|
|
183
|
+
{section.title}
|
|
184
|
+
</button>
|
|
185
|
+
</div>
|
|
186
|
+
))}
|
|
187
|
+
</nav>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
|
|
191
|
+
{/* Main Content */}
|
|
192
|
+
<div className="lg:col-span-3">
|
|
193
|
+
<h1 className="text-4xl font-bold text-gray-900 mb-4">Documentation</h1>
|
|
194
|
+
<p className="text-xl text-gray-600 mb-8">
|
|
195
|
+
Everything you need to know about using LogShield
|
|
196
|
+
</p>
|
|
197
|
+
|
|
198
|
+
{sections.map((section, idx) => (
|
|
199
|
+
<div key={idx} className="mb-12">
|
|
200
|
+
<h2 className="text-2xl font-bold text-gray-900 mb-6">{section.title}</h2>
|
|
201
|
+
<div className="grid gap-4">
|
|
202
|
+
{section.content.map((item, i) => (
|
|
203
|
+
<div key={i} className="p-6 bg-white rounded-lg border border-gray-200 hover:border-blue-300 transition-colors cursor-pointer">
|
|
204
|
+
<h3 className="font-semibold text-gray-900 mb-2">{item.title}</h3>
|
|
205
|
+
<p className="text-gray-600 text-sm">{item.desc}</p>
|
|
206
|
+
</div>
|
|
207
|
+
))}
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
))}
|
|
211
|
+
|
|
212
|
+
<div className="mt-12 p-6 bg-blue-50 rounded-lg border border-blue-200">
|
|
213
|
+
<h3 className="font-semibold text-gray-900 mb-2 flex items-center gap-2">
|
|
214
|
+
<MessageCircle className="h-5 w-5 text-blue-600" />
|
|
215
|
+
Need Help?
|
|
216
|
+
</h3>
|
|
217
|
+
<p className="text-gray-600 mb-4">
|
|
218
|
+
Can't find what you're looking for? We're here to help.
|
|
219
|
+
</p>
|
|
220
|
+
<a href="mailto:hello@logshield.dev" className="inline-block px-4 py-2 bg-blue-600 text-white rounded-lg text-sm font-medium hover:bg-blue-700 transition-colors">
|
|
221
|
+
Contact Support
|
|
222
|
+
</a>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
</div>
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// ============================================
|
|
232
|
+
// ABOUT PAGE
|
|
233
|
+
// ============================================
|
|
234
|
+
function AboutPage() {
|
|
235
|
+
return (
|
|
236
|
+
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-slate-50">
|
|
237
|
+
<div className="container py-12">
|
|
238
|
+
<a href="/" className="inline-flex items-center gap-2 text-blue-600 hover:text-blue-700 mb-8">
|
|
239
|
+
<ArrowLeft className="h-4 w-4" />
|
|
240
|
+
Back to Home
|
|
241
|
+
</a>
|
|
242
|
+
|
|
243
|
+
<div className="max-w-4xl mx-auto">
|
|
244
|
+
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-6">
|
|
245
|
+
About LogShield
|
|
246
|
+
</h1>
|
|
247
|
+
<p className="text-xl text-gray-600 mb-12">
|
|
248
|
+
Privacy-first log sanitization for developers worldwide
|
|
249
|
+
</p>
|
|
250
|
+
|
|
251
|
+
<div className="prose prose-lg max-w-none">
|
|
252
|
+
<div className="p-8 bg-white rounded-xl border border-gray-200 mb-8">
|
|
253
|
+
<h2 className="text-2xl font-bold text-gray-900 mb-4">Our Story</h2>
|
|
254
|
+
<p className="text-gray-600 mb-4">
|
|
255
|
+
LogShield was born from a simple need: developers need to share logs for debugging,
|
|
256
|
+
but those logs often contain sensitive data that shouldn't be exposed.
|
|
257
|
+
</p>
|
|
258
|
+
<p className="text-gray-600 mb-4">
|
|
259
|
+
After seeing countless incidents where API keys, tokens, and credentials were
|
|
260
|
+
accidentally leaked in GitHub issues, Stack Overflow posts, and support tickets,
|
|
261
|
+
we knew there had to be a better way.
|
|
262
|
+
</p>
|
|
263
|
+
<p className="text-gray-600">
|
|
264
|
+
We built LogShield to be the tool we wished existed: fast, private, and
|
|
265
|
+
comprehensive. No complex setup, no data upload, just paste and sanitize.
|
|
266
|
+
</p>
|
|
267
|
+
</div>
|
|
268
|
+
|
|
269
|
+
<div className="grid md:grid-cols-3 gap-6 mb-8">
|
|
270
|
+
<div className="p-6 bg-white rounded-xl border border-gray-200 text-center">
|
|
271
|
+
<div className="text-3xl font-bold text-blue-600 mb-2">100%</div>
|
|
272
|
+
<div className="text-sm text-gray-600">Client-Side Processing</div>
|
|
273
|
+
</div>
|
|
274
|
+
<div className="p-6 bg-white rounded-xl border border-gray-200 text-center">
|
|
275
|
+
<div className="text-3xl font-bold text-blue-600 mb-2">70+</div>
|
|
276
|
+
<div className="text-sm text-gray-600">Security Patterns</div>
|
|
277
|
+
</div>
|
|
278
|
+
<div className="p-6 bg-white rounded-xl border border-gray-200 text-center">
|
|
279
|
+
<div className="text-3xl font-bold text-blue-600 mb-2">10K+</div>
|
|
280
|
+
<div className="text-sm text-gray-600">Developers Trust Us</div>
|
|
281
|
+
</div>
|
|
282
|
+
</div>
|
|
283
|
+
|
|
284
|
+
<div className="p-8 bg-white rounded-xl border border-gray-200 mb-8">
|
|
285
|
+
<h2 className="text-2xl font-bold text-gray-900 mb-4">Our Values</h2>
|
|
286
|
+
<div className="space-y-4">
|
|
287
|
+
<div>
|
|
288
|
+
<h3 className="font-semibold text-gray-900 mb-2">?? Privacy First</h3>
|
|
289
|
+
<p className="text-gray-600">
|
|
290
|
+
Your data never leaves your browser. We don't store, log, or transmit
|
|
291
|
+
anything you sanitize.
|
|
292
|
+
</p>
|
|
293
|
+
</div>
|
|
294
|
+
<div>
|
|
295
|
+
<h3 className="font-semibold text-gray-900 mb-2">?? Developer Experience</h3>
|
|
296
|
+
<p className="text-gray-600">
|
|
297
|
+
Built by developers for developers. Simple, fast, and effective?no
|
|
298
|
+
unnecessary complexity.
|
|
299
|
+
</p>
|
|
300
|
+
</div>
|
|
301
|
+
<div>
|
|
302
|
+
<h3 className="font-semibold text-gray-900 mb-2">?? Open Source</h3>
|
|
303
|
+
<p className="text-gray-600">
|
|
304
|
+
Core sanitization engine is open source. Transparency builds trust.
|
|
305
|
+
</p>
|
|
306
|
+
</div>
|
|
307
|
+
<div>
|
|
308
|
+
<h3 className="font-semibold text-gray-900 mb-2">?? Continuous Improvement</h3>
|
|
309
|
+
<p className="text-gray-600">
|
|
310
|
+
We regularly update patterns and add features based on community feedback.
|
|
311
|
+
</p>
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
</div>
|
|
315
|
+
|
|
316
|
+
<div className="p-8 bg-gradient-to-r from-blue-600 to-purple-600 rounded-xl text-white text-center">
|
|
317
|
+
<h2 className="text-2xl font-bold mb-4">Join Our Community</h2>
|
|
318
|
+
<p className="text-blue-100 mb-6">
|
|
319
|
+
Connect with other developers, share feedback, and help shape the future of LogShield
|
|
320
|
+
</p>
|
|
321
|
+
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
|
322
|
+
<a href="https://github.com/afria85/LogShield" target="_blank" rel="noopener noreferrer" className="px-6 py-3 bg-white text-blue-600 rounded-lg font-medium hover:bg-gray-100 transition-colors">
|
|
323
|
+
GitHub
|
|
324
|
+
</a>
|
|
325
|
+
<a href="mailto:hello@logshield.dev" className="px-6 py-3 bg-blue-700 text-white rounded-lg font-medium hover:bg-blue-800 transition-colors">
|
|
326
|
+
Contact Us
|
|
327
|
+
</a>
|
|
328
|
+
</div>
|
|
329
|
+
</div>
|
|
330
|
+
</div>
|
|
331
|
+
</div>
|
|
332
|
+
</div>
|
|
333
|
+
</div>
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// ============================================
|
|
338
|
+
// BLOG PAGE
|
|
339
|
+
// ============================================
|
|
340
|
+
function BlogPage() {
|
|
341
|
+
const posts = [
|
|
342
|
+
{
|
|
343
|
+
title: "Introducing LogShield: The Privacy-First Log Sanitizer",
|
|
344
|
+
excerpt: "Learn how LogShield helps developers safely share logs without exposing sensitive data.",
|
|
345
|
+
date: "January 10, 2025",
|
|
346
|
+
readTime: "5 min read",
|
|
347
|
+
category: "Product"
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
title: "10 Common Ways Secrets Leak in Logs",
|
|
351
|
+
excerpt: "Understanding the most common patterns of credential exposure and how to prevent them.",
|
|
352
|
+
date: "January 8, 2025",
|
|
353
|
+
readTime: "8 min read",
|
|
354
|
+
category: "Security"
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
title: "Building a Client-Side Log Sanitizer",
|
|
358
|
+
excerpt: "Technical deep-dive into how we process sensitive data entirely in your browser.",
|
|
359
|
+
date: "January 5, 2025",
|
|
360
|
+
readTime: "12 min read",
|
|
361
|
+
category: "Technical"
|
|
362
|
+
}
|
|
363
|
+
];
|
|
364
|
+
|
|
365
|
+
return (
|
|
366
|
+
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-slate-50">
|
|
367
|
+
<div className="container py-12">
|
|
368
|
+
<a href="/" className="inline-flex items-center gap-2 text-blue-600 hover:text-blue-700 mb-8">
|
|
369
|
+
<ArrowLeft className="h-4 w-4" />
|
|
370
|
+
Back to Home
|
|
371
|
+
</a>
|
|
372
|
+
|
|
373
|
+
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4">Blog</h1>
|
|
374
|
+
<p className="text-xl text-gray-600 mb-12">
|
|
375
|
+
Insights on log security, privacy, and developer tools
|
|
376
|
+
</p>
|
|
377
|
+
|
|
378
|
+
<div className="max-w-4xl mx-auto space-y-8">
|
|
379
|
+
{posts.map((post, idx) => (
|
|
380
|
+
<article key={idx} className="p-8 bg-white rounded-xl border border-gray-200 hover:shadow-lg transition-shadow cursor-pointer">
|
|
381
|
+
<div className="flex items-center gap-3 mb-4">
|
|
382
|
+
<span className="px-3 py-1 bg-blue-100 text-blue-700 rounded-full text-sm font-medium">
|
|
383
|
+
{post.category}
|
|
384
|
+
</span>
|
|
385
|
+
<span className="text-sm text-gray-500">{post.date}</span>
|
|
386
|
+
<span className="text-sm text-gray-500">?</span>
|
|
387
|
+
<span className="text-sm text-gray-500">{post.readTime}</span>
|
|
388
|
+
</div>
|
|
389
|
+
|
|
390
|
+
<h2 className="text-2xl font-bold text-gray-900 mb-3 hover:text-blue-600 transition-colors">
|
|
391
|
+
{post.title}
|
|
392
|
+
</h2>
|
|
393
|
+
|
|
394
|
+
<p className="text-gray-600 mb-4">
|
|
395
|
+
{post.excerpt}
|
|
396
|
+
</p>
|
|
397
|
+
|
|
398
|
+
<button className="text-blue-600 font-medium hover:text-blue-700 flex items-center gap-2">
|
|
399
|
+
Read more
|
|
400
|
+
<ArrowLeft className="h-4 w-4 rotate-180" />
|
|
401
|
+
</button>
|
|
402
|
+
</article>
|
|
403
|
+
))}
|
|
404
|
+
</div>
|
|
405
|
+
|
|
406
|
+
<div className="max-w-4xl mx-auto mt-12 p-6 bg-blue-50 rounded-lg border border-blue-200 text-center">
|
|
407
|
+
<p className="text-gray-700 mb-4">
|
|
408
|
+
Want to stay updated? Subscribe to our newsletter.
|
|
409
|
+
</p>
|
|
410
|
+
<div className="flex gap-2 max-w-md mx-auto">
|
|
411
|
+
<input
|
|
412
|
+
type="email"
|
|
413
|
+
placeholder="your@email.com"
|
|
414
|
+
className="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
415
|
+
/>
|
|
416
|
+
<button className="px-6 py-2 bg-blue-600 text-white rounded-lg font-medium hover:bg-blue-700 transition-colors">
|
|
417
|
+
Subscribe
|
|
418
|
+
</button>
|
|
419
|
+
</div>
|
|
420
|
+
</div>
|
|
421
|
+
</div>
|
|
422
|
+
</div>
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// ============================================
|
|
427
|
+
// MAIN APP WITH ROUTING
|
|
428
|
+
// ============================================
|
|
429
|
+
export default function App() {
|
|
430
|
+
const [currentPage, setCurrentPage] = React.useState('features');
|
|
431
|
+
|
|
432
|
+
const pages = {
|
|
433
|
+
features: <FeaturesPage />,
|
|
434
|
+
docs: <DocsPage />,
|
|
435
|
+
about: <AboutPage />,
|
|
436
|
+
blog: <BlogPage />
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
return (
|
|
440
|
+
<div>
|
|
441
|
+
{/* Navigation */}
|
|
442
|
+
<div className="p-4 bg-white border-b flex gap-4 justify-center">
|
|
443
|
+
{Object.keys(pages).map(page => (
|
|
444
|
+
<button
|
|
445
|
+
key={page}
|
|
446
|
+
onClick={() => setCurrentPage(page)}
|
|
447
|
+
className={`px-4 py-2 rounded-lg font-medium transition-colors ${
|
|
448
|
+
currentPage === page
|
|
449
|
+
? 'bg-blue-600 text-white'
|
|
450
|
+
: 'text-gray-600 hover:bg-gray-100'
|
|
451
|
+
}`}
|
|
452
|
+
>
|
|
453
|
+
{page.charAt(0).toUpperCase() + page.slice(1)}
|
|
454
|
+
</button>
|
|
455
|
+
))}
|
|
456
|
+
</div>
|
|
457
|
+
|
|
458
|
+
{/* Page Content */}
|
|
459
|
+
{pages[currentPage]}
|
|
460
|
+
</div>
|
|
461
|
+
);
|
|
462
|
+
}
|
package/dist/index.html
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="description"
|
|
7
|
+
content="Privacy-first log sanitizer. Remove API keys, tokens, and PII instantly. 100% client-side." />
|
|
8
|
+
<title>LogShield</title>
|
|
9
|
+
<script defer data-domain="logshield.dev" src="https://plausible.io/js/script.js"></script>
|
|
10
|
+
<script type="module" crossorigin src="/assets/index-DDJ1Wxio.js"></script>
|
|
11
|
+
<link rel="stylesheet" crossorigin href="/assets/index-B3qxIuiz.css">
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
<div id="root"></div>
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|