Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .env.example +9 -0
- .gitattributes +56 -35
- .gitignore +8 -0
- AIFileConverter.spec +39 -0
- CMD.bash +16 -0
- LICENSE +21 -0
- LICENSE.txt +21 -0
- README.md +20 -0
- ai/ai_assistant.py +474 -0
- all-file-converter/.env.example +9 -0
- all-file-converter/.gitignore +8 -0
- all-file-converter/README.md +122 -0
- all-file-converter/assets/.aistudio/.gitignore +1 -0
- all-file-converter/index.html +13 -0
- all-file-converter/metadata.json +6 -0
- all-file-converter/package-lock.json +0 -0
- all-file-converter/package.json +36 -0
- all-file-converter/public/_redirects +2 -0
- all-file-converter/src/App.tsx +50 -0
- all-file-converter/src/components/Contact.tsx +262 -0
- all-file-converter/src/components/FAQ.tsx +137 -0
- all-file-converter/src/components/Features.tsx +97 -0
- all-file-converter/src/components/Footer.tsx +159 -0
- all-file-converter/src/components/Hero.tsx +423 -0
- all-file-converter/src/components/Navbar.tsx +213 -0
- all-file-converter/src/components/Stats.tsx +100 -0
- all-file-converter/src/components/SupportBanner.tsx +81 -0
- all-file-converter/src/components/Testimonials.tsx +98 -0
- all-file-converter/src/index.css +14 -0
- all-file-converter/src/main.tsx +10 -0
- all-file-converter/src/pages/Contact.tsx +269 -0
- all-file-converter/src/pages/FAQ.tsx +222 -0
- all-file-converter/src/pages/Features.tsx +290 -0
- all-file-converter/src/pages/Home.tsx +151 -0
- all-file-converter/src/pages/Privacy.tsx +98 -0
- all-file-converter/src/pages/Support.tsx +96 -0
- all-file-converter/src/types.ts +38 -0
- all-file-converter/src/utils/seo.ts +76 -0
- all-file-converter/tsconfig.json +26 -0
- all-file-converter/vite.config.ts +22 -0
- build/AIFileConverter/AIFileConverter.pkg +3 -0
- build/AIFileConverter/Analysis-00.toc +0 -0
- build/AIFileConverter/EXE-00.toc +0 -0
- build/AIFileConverter/PKG-00.toc +0 -0
- build/AIFileConverter/PYZ-00.pyz +3 -0
- build/AIFileConverter/PYZ-00.toc +0 -0
- build/AIFileConverter/base_library.zip +3 -0
- build/AIFileConverter/localpycs/pyimod01_archive.pyc +0 -0
- build/AIFileConverter/localpycs/pyimod02_importers.pyc +0 -0
- build/AIFileConverter/localpycs/pyimod03_ctypes.pyc +0 -0
.env.example
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# GEMINI_API_KEY: Required for Gemini AI API calls.
|
| 2 |
+
# AI Studio automatically injects this at runtime from user secrets.
|
| 3 |
+
# Users configure this via the Secrets panel in the AI Studio UI.
|
| 4 |
+
GEMINI_API_KEY="MY_GEMINI_API_KEY"
|
| 5 |
+
|
| 6 |
+
# APP_URL: The URL where this applet is hosted.
|
| 7 |
+
# AI Studio automatically injects this at runtime with the Cloud Run service URL.
|
| 8 |
+
# Used for self-referential links, OAuth callbacks, and API endpoints.
|
| 9 |
+
APP_URL="MY_APP_URL"
|
.gitattributes
CHANGED
|
@@ -1,35 +1,56 @@
|
|
| 1 |
-
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
-
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
-
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
AllFileConverter_Setup.exe filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
.venv/Lib/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-312.pyc filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-312.pyc filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
.venv/Lib/site-packages/pip/_vendor/distlib/t64-arm.exe filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
.venv/Lib/site-packages/pip/_vendor/distlib/t64.exe filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
.venv/Lib/site-packages/pip/_vendor/distlib/w64-arm.exe filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
.venv/Lib/site-packages/pip/_vendor/distlib/w64.exe filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
.venv/Lib/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-312.pyc filter=lfs diff=lfs merge=lfs -text
|
| 44 |
+
.venv/Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-312.pyc filter=lfs diff=lfs merge=lfs -text
|
| 45 |
+
.venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-312.pyc filter=lfs diff=lfs merge=lfs -text
|
| 46 |
+
.venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-312.pyc filter=lfs diff=lfs merge=lfs -text
|
| 47 |
+
.venv/Lib/site-packages/pip/_vendor/rich/__pycache__/console.cpython-312.pyc filter=lfs diff=lfs merge=lfs -text
|
| 48 |
+
.venv/Scripts/pip.exe filter=lfs diff=lfs merge=lfs -text
|
| 49 |
+
.venv/Scripts/pip3.12.exe filter=lfs diff=lfs merge=lfs -text
|
| 50 |
+
.venv/Scripts/pip3.exe filter=lfs diff=lfs merge=lfs -text
|
| 51 |
+
.venv/Scripts/python.exe filter=lfs diff=lfs merge=lfs -text
|
| 52 |
+
.venv/Scripts/pythonw.exe filter=lfs diff=lfs merge=lfs -text
|
| 53 |
+
build/AIFileConverter/AIFileConverter.pkg filter=lfs diff=lfs merge=lfs -text
|
| 54 |
+
build/AIFileConverter/PYZ-00.pyz filter=lfs diff=lfs merge=lfs -text
|
| 55 |
+
build/AIFileConverter/xref-AIFileConverter.html filter=lfs diff=lfs merge=lfs -text
|
| 56 |
+
dist/AIFileConverter.exe filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
node_modules/
|
| 2 |
+
build/
|
| 3 |
+
dist/
|
| 4 |
+
coverage/
|
| 5 |
+
.DS_Store
|
| 6 |
+
*.log
|
| 7 |
+
.env*
|
| 8 |
+
!.env.example
|
AIFileConverter.spec
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- mode: python ; coding: utf-8 -*-
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
a = Analysis(
|
| 5 |
+
['main.py'],
|
| 6 |
+
pathex=[],
|
| 7 |
+
binaries=[],
|
| 8 |
+
datas=[],
|
| 9 |
+
hiddenimports=['pycparser.lextab'],
|
| 10 |
+
hookspath=[],
|
| 11 |
+
hooksconfig={},
|
| 12 |
+
runtime_hooks=[],
|
| 13 |
+
excludes=['matplotlib', 'notebook', 'IPython', 'tensorflow'],
|
| 14 |
+
noarchive=False,
|
| 15 |
+
optimize=0,
|
| 16 |
+
)
|
| 17 |
+
pyz = PYZ(a.pure)
|
| 18 |
+
|
| 19 |
+
exe = EXE(
|
| 20 |
+
pyz,
|
| 21 |
+
a.scripts,
|
| 22 |
+
a.binaries,
|
| 23 |
+
a.datas,
|
| 24 |
+
[],
|
| 25 |
+
name='AIFileConverter',
|
| 26 |
+
debug=False,
|
| 27 |
+
bootloader_ignore_signals=False,
|
| 28 |
+
strip=False,
|
| 29 |
+
upx=True,
|
| 30 |
+
upx_exclude=[],
|
| 31 |
+
runtime_tmpdir=None,
|
| 32 |
+
console=False,
|
| 33 |
+
disable_windowed_traceback=False,
|
| 34 |
+
argv_emulation=False,
|
| 35 |
+
target_arch=None,
|
| 36 |
+
codesign_identity=None,
|
| 37 |
+
entitlements_file=None,
|
| 38 |
+
icon=['logo.ico'],
|
| 39 |
+
)
|
CMD.bash
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#https://chat.deepseek.com/share/to4ugsvhlmexygrfm4
|
| 2 |
+
#make it earn. https://chat.deepseek.com/share/to4ugsvhlmexygrfm4
|
| 3 |
+
# Install required packages
|
| 4 |
+
pip install -r requirements.txt
|
| 5 |
+
|
| 6 |
+
# For video conversion, install FFmpeg
|
| 7 |
+
# Ubuntu/Debian:
|
| 8 |
+
sudo apt-get install ffmpeg
|
| 9 |
+
|
| 10 |
+
# macOS:
|
| 11 |
+
brew install ffmpeg
|
| 12 |
+
|
| 13 |
+
# Windows: Download from ffmpeg.org
|
| 14 |
+
winget install Gyan-FFmpeg
|
| 15 |
+
# Run the application
|
| 16 |
+
python main.py
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2026 Bahadur Ali
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2026 Bahadur Ali
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
README.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<div align="center">
|
| 2 |
+
<img width="1200" height="475" alt="GHBanner" src="https://ai.google.dev/static/site-assets/images/share-ais-513315318.png" />
|
| 3 |
+
</div>
|
| 4 |
+
|
| 5 |
+
# Run and deploy your AI Studio app
|
| 6 |
+
|
| 7 |
+
This contains everything you need to run your app locally.
|
| 8 |
+
|
| 9 |
+
View your app in AI Studio: https://ai.studio/apps/48983e54-faea-404c-9ee2-ec652ce66c0b
|
| 10 |
+
|
| 11 |
+
## Run Locally
|
| 12 |
+
|
| 13 |
+
**Prerequisites:** Node.js
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
1. Install dependencies:
|
| 17 |
+
`npm install`
|
| 18 |
+
2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key
|
| 19 |
+
3. Run the app:
|
| 20 |
+
`npm run dev`
|
ai/ai_assistant.py
ADDED
|
@@ -0,0 +1,474 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import re
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from typing import Dict, Any, Tuple, Optional
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
class AIAssistant:
|
| 7 |
+
|
| 8 |
+
SUPPORTED_FORMATS = {
|
| 9 |
+
"document": ["pdf", "docx", "txt", "html", "md"],
|
| 10 |
+
"image": ["jpg", "jpeg", "png", "webp", "bmp", "tiff"],
|
| 11 |
+
"video": ["mp4", "avi", "mkv", "mov", "webm", "gif"],
|
| 12 |
+
"audio": ["mp3", "wav", "ogg", "m4a", "flac", "aac"]
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
def __init__(self):
|
| 16 |
+
|
| 17 |
+
self.knowledge_base = self.load_knowledge_base()
|
| 18 |
+
|
| 19 |
+
def load_knowledge_base(self):
|
| 20 |
+
|
| 21 |
+
return {
|
| 22 |
+
|
| 23 |
+
"document": {
|
| 24 |
+
"pdf": {
|
| 25 |
+
"best_for": "Sharing and printing documents"
|
| 26 |
+
},
|
| 27 |
+
"docx": {
|
| 28 |
+
"best_for": "Editing documents"
|
| 29 |
+
},
|
| 30 |
+
"txt": {
|
| 31 |
+
"best_for": "Plain text and notes"
|
| 32 |
+
}
|
| 33 |
+
},
|
| 34 |
+
|
| 35 |
+
"image": {
|
| 36 |
+
"jpg": {
|
| 37 |
+
"best_for": "Photos and web images"
|
| 38 |
+
},
|
| 39 |
+
"png": {
|
| 40 |
+
"best_for": "Transparency and graphics"
|
| 41 |
+
},
|
| 42 |
+
"webp": {
|
| 43 |
+
"best_for": "Modern web compression"
|
| 44 |
+
}
|
| 45 |
+
},
|
| 46 |
+
|
| 47 |
+
"video": {
|
| 48 |
+
"mp4": {
|
| 49 |
+
"best_for": "Universal compatibility"
|
| 50 |
+
},
|
| 51 |
+
"mkv": {
|
| 52 |
+
"best_for": "High quality storage"
|
| 53 |
+
}
|
| 54 |
+
},
|
| 55 |
+
|
| 56 |
+
"audio": {
|
| 57 |
+
"mp3": {
|
| 58 |
+
"best_for": "Universal playback"
|
| 59 |
+
},
|
| 60 |
+
"flac": {
|
| 61 |
+
"best_for": "Lossless audio"
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
def ask(
|
| 67 |
+
self,
|
| 68 |
+
question: str,
|
| 69 |
+
context: Dict[str, Any]
|
| 70 |
+
) -> str:
|
| 71 |
+
|
| 72 |
+
if not question.strip():
|
| 73 |
+
|
| 74 |
+
return (
|
| 75 |
+
"💬 Ask me something like:\n"
|
| 76 |
+
"• Convert this to PDF\n"
|
| 77 |
+
"• Best format for web\n"
|
| 78 |
+
"• Analyze this file"
|
| 79 |
+
)
|
| 80 |
+
|
| 81 |
+
question_lower = question.lower().strip()
|
| 82 |
+
|
| 83 |
+
# Greetings
|
| 84 |
+
if any(
|
| 85 |
+
x in question_lower
|
| 86 |
+
for x in ["hi", "hello", "hey"]
|
| 87 |
+
):
|
| 88 |
+
|
| 89 |
+
return (
|
| 90 |
+
"👋 Hello! I'm your AI File Assistant.\n\n"
|
| 91 |
+
"Try:\n"
|
| 92 |
+
"• Convert this to MP4\n"
|
| 93 |
+
"• Best format for web\n"
|
| 94 |
+
"• Analyze this file"
|
| 95 |
+
)
|
| 96 |
+
|
| 97 |
+
# Thanks
|
| 98 |
+
if "thank" in question_lower:
|
| 99 |
+
|
| 100 |
+
return (
|
| 101 |
+
"😊 You're welcome!"
|
| 102 |
+
)
|
| 103 |
+
|
| 104 |
+
# Conversion request
|
| 105 |
+
if self.is_conversion_command(
|
| 106 |
+
question_lower
|
| 107 |
+
):
|
| 108 |
+
|
| 109 |
+
return self.execute_conversion_command(
|
| 110 |
+
question_lower,
|
| 111 |
+
context
|
| 112 |
+
)
|
| 113 |
+
|
| 114 |
+
# Recommendations
|
| 115 |
+
if any(
|
| 116 |
+
x in question_lower
|
| 117 |
+
for x in [
|
| 118 |
+
"best format",
|
| 119 |
+
"recommend",
|
| 120 |
+
"suggest"
|
| 121 |
+
]
|
| 122 |
+
):
|
| 123 |
+
|
| 124 |
+
return self.suggest_format(
|
| 125 |
+
question_lower,
|
| 126 |
+
context
|
| 127 |
+
)
|
| 128 |
+
|
| 129 |
+
# Analyze
|
| 130 |
+
if any(
|
| 131 |
+
x in question_lower
|
| 132 |
+
for x in [
|
| 133 |
+
"analyze",
|
| 134 |
+
"what is this",
|
| 135 |
+
"what format"
|
| 136 |
+
]
|
| 137 |
+
):
|
| 138 |
+
|
| 139 |
+
return self.analyze_file(
|
| 140 |
+
context
|
| 141 |
+
)
|
| 142 |
+
|
| 143 |
+
# Help
|
| 144 |
+
if any(
|
| 145 |
+
x in question_lower
|
| 146 |
+
for x in [
|
| 147 |
+
"help",
|
| 148 |
+
"how to"
|
| 149 |
+
]
|
| 150 |
+
):
|
| 151 |
+
|
| 152 |
+
return self.get_help()
|
| 153 |
+
|
| 154 |
+
return self.get_general_response()
|
| 155 |
+
|
| 156 |
+
def is_conversion_command(
|
| 157 |
+
self,
|
| 158 |
+
text: str
|
| 159 |
+
) -> bool:
|
| 160 |
+
|
| 161 |
+
keywords = [
|
| 162 |
+
"convert",
|
| 163 |
+
"change",
|
| 164 |
+
"transform",
|
| 165 |
+
"make",
|
| 166 |
+
"turn into"
|
| 167 |
+
]
|
| 168 |
+
|
| 169 |
+
return any(
|
| 170 |
+
k in text
|
| 171 |
+
for k in keywords
|
| 172 |
+
)
|
| 173 |
+
|
| 174 |
+
def parse_conversion_request(
|
| 175 |
+
self,
|
| 176 |
+
text: str
|
| 177 |
+
) -> Optional[str]:
|
| 178 |
+
|
| 179 |
+
patterns = [
|
| 180 |
+
|
| 181 |
+
r"to\s+(\w+)",
|
| 182 |
+
|
| 183 |
+
r"into\s+(\w+)",
|
| 184 |
+
|
| 185 |
+
r"make\s+(?:it\s+)?(\w+)",
|
| 186 |
+
|
| 187 |
+
r"convert\s+(?:this\s+)?(?:file\s+)?to\s+(\w+)"
|
| 188 |
+
]
|
| 189 |
+
|
| 190 |
+
for pattern in patterns:
|
| 191 |
+
|
| 192 |
+
match = re.search(
|
| 193 |
+
pattern,
|
| 194 |
+
text
|
| 195 |
+
)
|
| 196 |
+
|
| 197 |
+
if match:
|
| 198 |
+
|
| 199 |
+
fmt = match.group(1).lower()
|
| 200 |
+
|
| 201 |
+
# normalize jpeg
|
| 202 |
+
if fmt == "jpeg":
|
| 203 |
+
fmt = "jpg"
|
| 204 |
+
|
| 205 |
+
return fmt
|
| 206 |
+
|
| 207 |
+
return None
|
| 208 |
+
|
| 209 |
+
def execute_conversion_command(
|
| 210 |
+
self,
|
| 211 |
+
question: str,
|
| 212 |
+
context: Dict[str, Any]
|
| 213 |
+
) -> str:
|
| 214 |
+
|
| 215 |
+
target_format = self.parse_conversion_request(
|
| 216 |
+
question
|
| 217 |
+
)
|
| 218 |
+
|
| 219 |
+
if not target_format:
|
| 220 |
+
|
| 221 |
+
return self.get_conversion_help()
|
| 222 |
+
|
| 223 |
+
file_type = context.get(
|
| 224 |
+
"file_type",
|
| 225 |
+
""
|
| 226 |
+
).lower()
|
| 227 |
+
|
| 228 |
+
current_format = context.get(
|
| 229 |
+
"output_format",
|
| 230 |
+
""
|
| 231 |
+
).lower()
|
| 232 |
+
|
| 233 |
+
if not file_type:
|
| 234 |
+
|
| 235 |
+
return (
|
| 236 |
+
"⚠ Please select a file type first."
|
| 237 |
+
)
|
| 238 |
+
|
| 239 |
+
supported = self.SUPPORTED_FORMATS.get(
|
| 240 |
+
file_type,
|
| 241 |
+
[]
|
| 242 |
+
)
|
| 243 |
+
|
| 244 |
+
if target_format not in supported:
|
| 245 |
+
|
| 246 |
+
return (
|
| 247 |
+
f"❌ {target_format.upper()} "
|
| 248 |
+
f"is not supported for "
|
| 249 |
+
f"{file_type} files.\n\n"
|
| 250 |
+
f"Supported:\n"
|
| 251 |
+
f"{', '.join(supported).upper()}"
|
| 252 |
+
)
|
| 253 |
+
|
| 254 |
+
response = (
|
| 255 |
+
"🎯 Conversion Ready\n\n"
|
| 256 |
+
f"Current Type: {file_type.title()}\n"
|
| 257 |
+
f"Target Format: {target_format.upper()}\n\n"
|
| 258 |
+
)
|
| 259 |
+
|
| 260 |
+
advice = self.get_format_advice(
|
| 261 |
+
file_type,
|
| 262 |
+
target_format
|
| 263 |
+
)
|
| 264 |
+
|
| 265 |
+
if advice:
|
| 266 |
+
|
| 267 |
+
response += (
|
| 268 |
+
f"💡 Tip: {advice}\n\n"
|
| 269 |
+
)
|
| 270 |
+
|
| 271 |
+
response += (
|
| 272 |
+
"✅ Now:\n"
|
| 273 |
+
"1. Select the format\n"
|
| 274 |
+
"2. Add files\n"
|
| 275 |
+
"3. Click Start Conversion"
|
| 276 |
+
)
|
| 277 |
+
|
| 278 |
+
return response
|
| 279 |
+
|
| 280 |
+
def suggest_format(
|
| 281 |
+
self,
|
| 282 |
+
question: str,
|
| 283 |
+
context: Dict[str, Any]
|
| 284 |
+
) -> str:
|
| 285 |
+
|
| 286 |
+
file_type = context.get(
|
| 287 |
+
"file_type",
|
| 288 |
+
""
|
| 289 |
+
).lower()
|
| 290 |
+
|
| 291 |
+
if not file_type:
|
| 292 |
+
|
| 293 |
+
return (
|
| 294 |
+
"⚠ Please select a file type first."
|
| 295 |
+
)
|
| 296 |
+
|
| 297 |
+
recommendations = {
|
| 298 |
+
|
| 299 |
+
"document": {
|
| 300 |
+
"web": "HTML",
|
| 301 |
+
"print": "PDF",
|
| 302 |
+
"edit": "DOCX",
|
| 303 |
+
"small": "TXT"
|
| 304 |
+
},
|
| 305 |
+
|
| 306 |
+
"image": {
|
| 307 |
+
"web": "WEBP",
|
| 308 |
+
"quality": "PNG",
|
| 309 |
+
"photo": "JPG",
|
| 310 |
+
"transparent": "PNG"
|
| 311 |
+
},
|
| 312 |
+
|
| 313 |
+
"video": {
|
| 314 |
+
"web": "MP4",
|
| 315 |
+
"quality": "MKV",
|
| 316 |
+
"small": "WEBM"
|
| 317 |
+
},
|
| 318 |
+
|
| 319 |
+
"audio": {
|
| 320 |
+
"quality": "FLAC",
|
| 321 |
+
"small": "MP3",
|
| 322 |
+
"edit": "WAV"
|
| 323 |
+
}
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
use_case = "web"
|
| 327 |
+
|
| 328 |
+
keywords = {
|
| 329 |
+
"print": ["print"],
|
| 330 |
+
"edit": ["edit"],
|
| 331 |
+
"small": ["small", "compress"],
|
| 332 |
+
"quality": ["quality", "lossless"],
|
| 333 |
+
"photo": ["photo"],
|
| 334 |
+
"transparent": ["transparent"]
|
| 335 |
+
}
|
| 336 |
+
|
| 337 |
+
for case, words in keywords.items():
|
| 338 |
+
|
| 339 |
+
if any(w in question for w in words):
|
| 340 |
+
|
| 341 |
+
use_case = case
|
| 342 |
+
break
|
| 343 |
+
|
| 344 |
+
fmt = recommendations.get(
|
| 345 |
+
file_type,
|
| 346 |
+
{}
|
| 347 |
+
).get(
|
| 348 |
+
use_case,
|
| 349 |
+
"PDF"
|
| 350 |
+
)
|
| 351 |
+
|
| 352 |
+
return (
|
| 353 |
+
f"📋 Recommended Format\n\n"
|
| 354 |
+
f"For {use_case} use:\n"
|
| 355 |
+
f"✅ {fmt}\n\n"
|
| 356 |
+
f"Type:\n"
|
| 357 |
+
f"Convert this to {fmt}"
|
| 358 |
+
)
|
| 359 |
+
|
| 360 |
+
def analyze_file(
|
| 361 |
+
self,
|
| 362 |
+
context: Dict[str, Any]
|
| 363 |
+
) -> str:
|
| 364 |
+
|
| 365 |
+
file_type = context.get(
|
| 366 |
+
"file_type",
|
| 367 |
+
"Unknown"
|
| 368 |
+
)
|
| 369 |
+
|
| 370 |
+
fmt = context.get(
|
| 371 |
+
"output_format",
|
| 372 |
+
"Unknown"
|
| 373 |
+
).lower()
|
| 374 |
+
|
| 375 |
+
response = (
|
| 376 |
+
"🔍 File Analysis\n\n"
|
| 377 |
+
f"Type: {file_type.title()}\n"
|
| 378 |
+
f"Format: {fmt.upper()}\n\n"
|
| 379 |
+
)
|
| 380 |
+
|
| 381 |
+
kb = self.knowledge_base.get(
|
| 382 |
+
file_type,
|
| 383 |
+
{}
|
| 384 |
+
)
|
| 385 |
+
|
| 386 |
+
if fmt in kb:
|
| 387 |
+
|
| 388 |
+
response += (
|
| 389 |
+
f"📌 Best For:\n"
|
| 390 |
+
f"{kb[fmt]['best_for']}"
|
| 391 |
+
)
|
| 392 |
+
|
| 393 |
+
else:
|
| 394 |
+
|
| 395 |
+
response += (
|
| 396 |
+
"No detailed analysis available."
|
| 397 |
+
)
|
| 398 |
+
|
| 399 |
+
return response
|
| 400 |
+
|
| 401 |
+
def get_help(self) -> str:
|
| 402 |
+
|
| 403 |
+
return (
|
| 404 |
+
"🤖 AI Assistant Help\n\n"
|
| 405 |
+
"Commands:\n"
|
| 406 |
+
"• Convert this to PDF\n"
|
| 407 |
+
"• Best format for web\n"
|
| 408 |
+
"• Analyze this file\n"
|
| 409 |
+
"• Compress this video\n\n"
|
| 410 |
+
"Supported:\n"
|
| 411 |
+
"Documents, Images, Videos, Audio"
|
| 412 |
+
)
|
| 413 |
+
|
| 414 |
+
def get_general_response(self) -> str:
|
| 415 |
+
|
| 416 |
+
return (
|
| 417 |
+
"🤖 AI Assistant Ready\n\n"
|
| 418 |
+
"Try:\n"
|
| 419 |
+
"• Convert this to PNG\n"
|
| 420 |
+
"• Best format for web\n"
|
| 421 |
+
"• Analyze this file"
|
| 422 |
+
)
|
| 423 |
+
|
| 424 |
+
def get_format_advice(
|
| 425 |
+
self,
|
| 426 |
+
file_type: str,
|
| 427 |
+
target_format: str
|
| 428 |
+
) -> str:
|
| 429 |
+
|
| 430 |
+
tips = {
|
| 431 |
+
|
| 432 |
+
("image", "jpg"):
|
| 433 |
+
"Best for photos and smaller size.",
|
| 434 |
+
|
| 435 |
+
("image", "png"):
|
| 436 |
+
"Supports transparency.",
|
| 437 |
+
|
| 438 |
+
("image", "webp"):
|
| 439 |
+
"Excellent modern compression.",
|
| 440 |
+
|
| 441 |
+
("video", "mp4"):
|
| 442 |
+
"Most compatible format.",
|
| 443 |
+
|
| 444 |
+
("video", "gif"):
|
| 445 |
+
"Keep clips short for smaller size.",
|
| 446 |
+
|
| 447 |
+
("audio", "mp3"):
|
| 448 |
+
"Universal audio playback.",
|
| 449 |
+
|
| 450 |
+
("audio", "flac"):
|
| 451 |
+
"Lossless quality.",
|
| 452 |
+
|
| 453 |
+
("document", "pdf"):
|
| 454 |
+
"Preserves formatting.",
|
| 455 |
+
|
| 456 |
+
("document", "txt"):
|
| 457 |
+
"Very small file size."
|
| 458 |
+
}
|
| 459 |
+
|
| 460 |
+
return tips.get(
|
| 461 |
+
(file_type, target_format),
|
| 462 |
+
""
|
| 463 |
+
)
|
| 464 |
+
|
| 465 |
+
def get_conversion_help(self) -> str:
|
| 466 |
+
|
| 467 |
+
return (
|
| 468 |
+
"🎯 Conversion Help\n\n"
|
| 469 |
+
"Examples:\n"
|
| 470 |
+
"• Convert this to PDF\n"
|
| 471 |
+
"• Make it MP3\n"
|
| 472 |
+
"• Change this to PNG\n"
|
| 473 |
+
"• Transform to MP4"
|
| 474 |
+
)
|
all-file-converter/.env.example
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# GEMINI_API_KEY: Required for Gemini AI API calls.
|
| 2 |
+
# AI Studio automatically injects this at runtime from user secrets.
|
| 3 |
+
# Users configure this via the Secrets panel in the AI Studio UI.
|
| 4 |
+
GEMINI_API_KEY="MY_GEMINI_API_KEY"
|
| 5 |
+
|
| 6 |
+
# APP_URL: The URL where this applet is hosted.
|
| 7 |
+
# AI Studio automatically injects this at runtime with the Cloud Run service URL.
|
| 8 |
+
# Used for self-referential links, OAuth callbacks, and API endpoints.
|
| 9 |
+
APP_URL="MY_APP_URL"
|
all-file-converter/.gitignore
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
node_modules/
|
| 2 |
+
build/
|
| 3 |
+
dist/
|
| 4 |
+
coverage/
|
| 5 |
+
.DS_Store
|
| 6 |
+
*.log
|
| 7 |
+
.env*
|
| 8 |
+
!.env.example
|
all-file-converter/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Run and deploy your AI Studio app
|
| 2 |
+
|
| 3 |
+
This contains everything you need to run your app locally.
|
| 4 |
+
|
| 5 |
+
View your app in AI Studio: https://ai.studio/apps/48983e54-faea-404c-9ee2-ec652ce66c0b
|
| 6 |
+
|
| 7 |
+
## Run Locally
|
| 8 |
+
|
| 9 |
+
**Prerequisites:** Node.js
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
1. Install dependencies:
|
| 14 |
+
`npm install`
|
| 15 |
+
2. Set the `GEMINI\_API\_KEY` in [.env.local](.env.local) to your Gemini API key
|
| 16 |
+
3. Run the app:
|
| 17 |
+
`npm run dev`
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
3\. Netlify Redirect Readiness
|
| 22 |
+
|
| 23 |
+
Vite-based Single Page Applications (SPAs) often return a 404 Not Found error when a visitor tries to refresh or directly enter secondary URL directories like /features or /faq on Netlify.
|
| 24 |
+
|
| 25 |
+
To overcome this, we configured a dynamic Netlify rule file at /public/\_redirects:
|
| 26 |
+
|
| 27 |
+
code
|
| 28 |
+
|
| 29 |
+
Text
|
| 30 |
+
|
| 31 |
+
\# Netlify Redirects for Single Page Apps
|
| 32 |
+
|
| 33 |
+
/\* /index.html 200
|
| 34 |
+
|
| 35 |
+
When Netlify builds your project, this is automatically bundled into your root assets. It redirects index files internally to your React Router shell so all pathways load instantly without breaking.
|
| 36 |
+
|
| 37 |
+
4\. Step-by-Step Guide: How to run your project with npm \& deploy to Netlify
|
| 38 |
+
|
| 39 |
+
If you are new to Node.js and npm package managers, follow these instructions to manage, preview, and host your new platform:
|
| 40 |
+
|
| 41 |
+
Step 4.1: Install Node.js \& npm on your Desktop
|
| 42 |
+
|
| 43 |
+
Download the LTS (Long-Term Support) version of Node.js from the official Node.js portal.
|
| 44 |
+
|
| 45 |
+
Run the installer. It will automatically install both node and npm (Node Package Manager) onto your machine's system path.
|
| 46 |
+
|
| 47 |
+
Open your computer's terminal (Command Prompt on Windows, Terminal on macOS) and type the following keys to confirm they are installed:
|
| 48 |
+
|
| 49 |
+
code
|
| 50 |
+
|
| 51 |
+
Bash
|
| 52 |
+
|
| 53 |
+
node -v
|
| 54 |
+
|
| 55 |
+
npm -v
|
| 56 |
+
|
| 57 |
+
Step 4.2: Run the project locally
|
| 58 |
+
|
| 59 |
+
Open your terminal, navigate to the project directory folder where this application is located:
|
| 60 |
+
|
| 61 |
+
code
|
| 62 |
+
|
| 63 |
+
Bash
|
| 64 |
+
|
| 65 |
+
cd path/to/your/project-folder
|
| 66 |
+
|
| 67 |
+
Install all development packages and required libraries (react-router-dom, etc.) in one simple command:
|
| 68 |
+
|
| 69 |
+
code
|
| 70 |
+
|
| 71 |
+
Bash
|
| 72 |
+
|
| 73 |
+
npm install
|
| 74 |
+
|
| 75 |
+
Start the interactive local development server:
|
| 76 |
+
|
| 77 |
+
code
|
| 78 |
+
|
| 79 |
+
Bash
|
| 80 |
+
|
| 81 |
+
npm run dev
|
| 82 |
+
|
| 83 |
+
Your console will provide an address link (usually http://localhost:3000 or http://localhost:5173). Open this URL in any browser to preview, test, and iterate on your application.
|
| 84 |
+
|
| 85 |
+
Step 4.3: Build for production
|
| 86 |
+
|
| 87 |
+
Before serving, always compile raw TypeScript file modules into fast, optimized static browser bundles:
|
| 88 |
+
|
| 89 |
+
code
|
| 90 |
+
|
| 91 |
+
Bash
|
| 92 |
+
|
| 93 |
+
npm run build
|
| 94 |
+
|
| 95 |
+
This compilation creates a folder named dist containing clean, minified styling stylesheets, scripts, images, and your custom Netlify \_redirects file.
|
| 96 |
+
|
| 97 |
+
Step 4.4: Deploying to Netlify Hosting (Free and Premium)
|
| 98 |
+
|
| 99 |
+
Deploying your finished platform takes under two minutes. You can choose either of these straightforward methods:
|
| 100 |
+
|
| 101 |
+
Run npm run build in your local computer terminal to generate the dist folder.
|
| 102 |
+
|
| 103 |
+
Sign in or create a free account at Netlify.
|
| 104 |
+
|
| 105 |
+
Navigate to Sites and scroll to the bottom page block.
|
| 106 |
+
|
| 107 |
+
Drag and drop your compiled dist folder directly into the Netlify visual web browser box. Your site will launch globally on a secure, optimized custom subdomain within seconds!
|
| 108 |
+
|
| 109 |
+
Commit and push this project codebase to a repository on GitHub, GitLab, or Bitbucket.
|
| 110 |
+
|
| 111 |
+
Go to your Netlify Dashboard and click Add New Site -> Import from Git.
|
| 112 |
+
|
| 113 |
+
Select your repository.
|
| 114 |
+
|
| 115 |
+
Configure the build parameters as:
|
| 116 |
+
|
| 117 |
+
Build Command: npm run build
|
| 118 |
+
|
| 119 |
+
Publish Directory: dist
|
| 120 |
+
|
| 121 |
+
Click Deploy. Netlify will build and release your pages globally. Whenever you push code variations to GitHub, Netlify will rebuild the application in the background automatically!
|
| 122 |
+
|
all-file-converter/assets/.aistudio/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
*
|
all-file-converter/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
<title>My Google AI Studio App</title>
|
| 7 |
+
</head>
|
| 8 |
+
<body>
|
| 9 |
+
<div id="root"></div>
|
| 10 |
+
<script type="module" src="/src/main.tsx"></script>
|
| 11 |
+
</body>
|
| 12 |
+
</html>
|
| 13 |
+
|
all-file-converter/metadata.json
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "All File Converter",
|
| 3 |
+
"description": "Lumina Convert – Modern, offline-first file converter supporting 200+ formats with GPU acceleration.",
|
| 4 |
+
"requestFramePermissions": [],
|
| 5 |
+
"majorCapabilities": ["MAJOR_CAPABILITY_SERVER_SIDE_GEMINI_API"]
|
| 6 |
+
}
|
all-file-converter/package-lock.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
all-file-converter/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "react-example",
|
| 3 |
+
"private": true,
|
| 4 |
+
"version": "0.0.0",
|
| 5 |
+
"type": "module",
|
| 6 |
+
"scripts": {
|
| 7 |
+
"dev": "vite --port=3000 --host=0.0.0.0",
|
| 8 |
+
"build": "vite build",
|
| 9 |
+
"preview": "vite preview",
|
| 10 |
+
"clean": "rm -rf dist server.js",
|
| 11 |
+
"lint": "tsc --noEmit"
|
| 12 |
+
},
|
| 13 |
+
"dependencies": {
|
| 14 |
+
"@google/genai": "^2.4.0",
|
| 15 |
+
"@tailwindcss/vite": "^4.1.14",
|
| 16 |
+
"@vitejs/plugin-react": "^5.0.4",
|
| 17 |
+
"dotenv": "^17.2.3",
|
| 18 |
+
"express": "^4.21.2",
|
| 19 |
+
"lucide-react": "^0.546.0",
|
| 20 |
+
"motion": "^12.23.24",
|
| 21 |
+
"react": "^19.0.1",
|
| 22 |
+
"react-dom": "^19.0.1",
|
| 23 |
+
"react-router-dom": "^7.17.0",
|
| 24 |
+
"vite": "^6.2.3"
|
| 25 |
+
},
|
| 26 |
+
"devDependencies": {
|
| 27 |
+
"@types/express": "^4.17.21",
|
| 28 |
+
"@types/node": "^22.14.0",
|
| 29 |
+
"autoprefixer": "^10.4.21",
|
| 30 |
+
"esbuild": "^0.25.0",
|
| 31 |
+
"tailwindcss": "^4.1.14",
|
| 32 |
+
"tsx": "^4.21.0",
|
| 33 |
+
"typescript": "~5.8.2",
|
| 34 |
+
"vite": "^6.2.3"
|
| 35 |
+
}
|
| 36 |
+
}
|
all-file-converter/public/_redirects
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Netlify Redirects for Single Page Apps
|
| 2 |
+
/* /index.html 200
|
all-file-converter/src/App.tsx
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @license
|
| 3 |
+
* SPDX-License-Identifier: Apache-2.0
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
| 7 |
+
import Navbar from "./components/Navbar";
|
| 8 |
+
import Footer from "./components/Footer";
|
| 9 |
+
|
| 10 |
+
// Multi-page routing views
|
| 11 |
+
import Home from "./pages/Home";
|
| 12 |
+
import Features from "./pages/Features";
|
| 13 |
+
import FAQ from "./pages/FAQ";
|
| 14 |
+
import Contact from "./pages/Contact";
|
| 15 |
+
import Support from "./pages/Support";
|
| 16 |
+
import Privacy from "./pages/Privacy";
|
| 17 |
+
|
| 18 |
+
export default function App() {
|
| 19 |
+
const DOWNLOAD_URL = "https://huggingface.co/embedingHF/AFC/resolve/main/AllFileConverter_Setup.exe";
|
| 20 |
+
|
| 21 |
+
return (
|
| 22 |
+
<BrowserRouter>
|
| 23 |
+
<div className="relative min-h-screen selection:bg-violet-100 selection:text-violet-900 bg-[#fbfbfd] flex flex-col justify-between">
|
| 24 |
+
{/* Decorative top grid lines/accents */}
|
| 25 |
+
<div className="absolute top-0 left-0 right-0 h-[450px] bg-gradient-to-b from-violet-50/20 via-transparent to-transparent pointer-events-none" />
|
| 26 |
+
|
| 27 |
+
{/* Grid Pattern */}
|
| 28 |
+
<div className="absolute inset-0 bg-[linear-gradient(to_right,#e2e8f0_1px,transparent_1px),linear-gradient(to_bottom,#e2e8f0_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_60%_50%_at_50%_0%,#000_70%,transparent_100%)] opacity-20 pointer-events-none font-sans" />
|
| 29 |
+
|
| 30 |
+
{/* Sticky glassmorphic navbar */}
|
| 31 |
+
<Navbar downloadUrl={DOWNLOAD_URL} />
|
| 32 |
+
|
| 33 |
+
{/* Main routing content layout */}
|
| 34 |
+
<main className="w-full flex-grow pt-16">
|
| 35 |
+
<Routes>
|
| 36 |
+
<Route path="/" element={<Home downloadUrl={DOWNLOAD_URL} />} />
|
| 37 |
+
<Route path="/features" element={<Features />} />
|
| 38 |
+
<Route path="/faq" element={<FAQ />} />
|
| 39 |
+
<Route path="/contact" element={<Contact />} />
|
| 40 |
+
<Route path="/support" element={<Support />} />
|
| 41 |
+
<Route path="/privacy" element={<Privacy />} />
|
| 42 |
+
</Routes>
|
| 43 |
+
</main>
|
| 44 |
+
|
| 45 |
+
{/* Footer directories and legal disclosures */}
|
| 46 |
+
<Footer />
|
| 47 |
+
</div>
|
| 48 |
+
</BrowserRouter>
|
| 49 |
+
);
|
| 50 |
+
}
|
all-file-converter/src/components/Contact.tsx
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useState, ChangeEvent, FormEvent } from "react";
|
| 2 |
+
import { Mail, MessageSquare, Phone, Send, CheckCircle, AlertTriangle } from "lucide-react";
|
| 3 |
+
import { motion } from "motion/react";
|
| 4 |
+
|
| 5 |
+
export default function Contact() {
|
| 6 |
+
const [formData, setFormData] = useState({
|
| 7 |
+
name: "",
|
| 8 |
+
email: "",
|
| 9 |
+
subject: "",
|
| 10 |
+
message: "",
|
| 11 |
+
});
|
| 12 |
+
|
| 13 |
+
const [formStatus, setFormStatus] = useState<"idle" | "submitting" | "success" | "error">("idle");
|
| 14 |
+
const [errorMessage, setErrorMessage] = useState("");
|
| 15 |
+
|
| 16 |
+
const handleChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
| 17 |
+
setFormData({
|
| 18 |
+
...formData,
|
| 19 |
+
[e.target.name]: e.target.value,
|
| 20 |
+
});
|
| 21 |
+
};
|
| 22 |
+
|
| 23 |
+
const handleSubmit = async (e: FormEvent) => {
|
| 24 |
+
e.preventDefault();
|
| 25 |
+
if (!formData.name || !formData.email || !formData.message) {
|
| 26 |
+
setFormStatus("error");
|
| 27 |
+
setErrorMessage("Please complete all required fields.");
|
| 28 |
+
return;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
setFormStatus("submitting");
|
| 32 |
+
|
| 33 |
+
try {
|
| 34 |
+
const response = await fetch("https://formspree.io/f/mojrrdov", {
|
| 35 |
+
method: "POST",
|
| 36 |
+
headers: {
|
| 37 |
+
"Content-Type": "application/json",
|
| 38 |
+
Accept: "application/json",
|
| 39 |
+
},
|
| 40 |
+
body: JSON.stringify(formData),
|
| 41 |
+
});
|
| 42 |
+
|
| 43 |
+
if (response.ok) {
|
| 44 |
+
setFormStatus("success");
|
| 45 |
+
setFormData({ name: "", email: "", subject: "", message: "" });
|
| 46 |
+
} else {
|
| 47 |
+
setFormStatus("error");
|
| 48 |
+
setErrorMessage("An error occurred on the server. Please check your network and try again.");
|
| 49 |
+
}
|
| 50 |
+
} catch (err) {
|
| 51 |
+
setFormStatus("error");
|
| 52 |
+
setErrorMessage("Could not submit the form. Please check your connection or contact our support team.");
|
| 53 |
+
}
|
| 54 |
+
};
|
| 55 |
+
|
| 56 |
+
return (
|
| 57 |
+
<section id="contact" className="py-24 bg-gradient-to-b from-[#FAF9FE] to-white relative">
|
| 58 |
+
<div className="max-w-7xl mx-auto px-4 md:px-8 relative z-10">
|
| 59 |
+
{/* Header */}
|
| 60 |
+
<div className="text-center max-w-2xl mx-auto mb-16">
|
| 61 |
+
<span className="text-xs font-bold font-mono tracking-wider text-violet-600 uppercase bg-violet-50 px-3.5 py-1.5 rounded-full">
|
| 62 |
+
Get In Touch
|
| 63 |
+
</span>
|
| 64 |
+
<h2 className="font-display font-bold text-3xl sm:text-4xl text-slate-900 tracking-tight mt-4 mb-4">
|
| 65 |
+
Custom setup assist is{" "}
|
| 66 |
+
<span className="bg-gradient-to-r from-violet-600 to-indigo-600 bg-clip-text text-transparent">
|
| 67 |
+
one click away
|
| 68 |
+
</span>
|
| 69 |
+
</h2>
|
| 70 |
+
<p className="text-slate-500 text-sm md:text-base font-light">
|
| 71 |
+
Need support with custom scripting, configuration, or folder watcher automation? Message our core team immediately.
|
| 72 |
+
</p>
|
| 73 |
+
</div>
|
| 74 |
+
|
| 75 |
+
{/* Column breakdown */}
|
| 76 |
+
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12 items-start" id="contact-panel-wrapper">
|
| 77 |
+
{/* Left Column - Contact Details */}
|
| 78 |
+
<div className="lg:col-span-5 space-y-6 text-left">
|
| 79 |
+
<h3 className="font-display font-semibold text-2xl text-slate-900 tracking-tight mb-4">
|
| 80 |
+
Direct Channels
|
| 81 |
+
</h3>
|
| 82 |
+
<p className="text-slate-500 text-sm font-light leading-relaxed mb-6">
|
| 83 |
+
Our support team answers personal emails and WhatsApp inquiries directly. Get prompt assistance with your offline integration.
|
| 84 |
+
</p>
|
| 85 |
+
|
| 86 |
+
<div className="space-y-4">
|
| 87 |
+
{/* WhatsApp Support */}
|
| 88 |
+
<a
|
| 89 |
+
href="https://wa.me/923034572298"
|
| 90 |
+
target="_blank"
|
| 91 |
+
rel="noopener noreferrer"
|
| 92 |
+
id="contact-whatsapp-direct-link"
|
| 93 |
+
className="flex items-start p-4 hover:bg-slate-50 border border-slate-100 rounded-2xl transition"
|
| 94 |
+
>
|
| 95 |
+
<div className="w-10 h-10 rounded-xl bg-emerald-50 text-emerald-600 flex items-center justify-center mr-4 flex-shrink-0 shadow-sm">
|
| 96 |
+
<Phone className="w-5 h-5" />
|
| 97 |
+
</div>
|
| 98 |
+
<div>
|
| 99 |
+
<h4 className="text-sm font-semibold text-slate-800">WhatsApp Instant Chat</h4>
|
| 100 |
+
<p className="text-xs text-slate-500 font-mono mt-0.5">+92 303 4572298</p>
|
| 101 |
+
<span className="inline-block text-[10px] font-bold text-emerald-600 font-mono mt-1 uppercase">
|
| 102 |
+
Answered in minutes
|
| 103 |
+
</span>
|
| 104 |
+
</div>
|
| 105 |
+
</a>
|
| 106 |
+
|
| 107 |
+
{/* Email Support */}
|
| 108 |
+
<a
|
| 109 |
+
href="mailto:bahaduralimunnabhai@gmail.com"
|
| 110 |
+
id="contact-email-direct-link"
|
| 111 |
+
className="flex items-start p-4 hover:bg-slate-50 border border-slate-100 rounded-2xl transition"
|
| 112 |
+
>
|
| 113 |
+
<div className="w-10 h-10 rounded-xl bg-violet-50 text-violet-600 flex items-center justify-center mr-4 flex-shrink-0 shadow-sm">
|
| 114 |
+
<Mail className="w-5 h-5" />
|
| 115 |
+
</div>
|
| 116 |
+
<div>
|
| 117 |
+
<h4 className="text-sm font-semibold text-slate-800">Secure Developer Mailbox</h4>
|
| 118 |
+
<p className="text-xs text-slate-500 font-mono mt-0.5">bahaduralimunnabhai@gmail.com</p>
|
| 119 |
+
<span className="inline-block text-[10px] font-bold text-violet-600 font-mono mt-1 uppercase">
|
| 120 |
+
Under 12hr Response SLA
|
| 121 |
+
</span>
|
| 122 |
+
</div>
|
| 123 |
+
</a>
|
| 124 |
+
|
| 125 |
+
{/* Developer Location / Core info */}
|
| 126 |
+
<div className="flex items-start p-4 bg-slate-50/50 border border-slate-100 rounded-2xl">
|
| 127 |
+
<div className="w-10 h-10 rounded-xl bg-white text-slate-500 flex items-center justify-center mr-4 flex-shrink-0 shadow-sm">
|
| 128 |
+
<MessageSquare className="w-4 h-4" />
|
| 129 |
+
</div>
|
| 130 |
+
<div>
|
| 131 |
+
<h4 className="text-sm font-semibold text-slate-800">Enterprise Configurations</h4>
|
| 132 |
+
<p className="text-xs text-slate-500 font-light mt-0.5">
|
| 133 |
+
For corporate deployment arrays, local security audits, or customized CLI wrappers.
|
| 134 |
+
</p>
|
| 135 |
+
</div>
|
| 136 |
+
</div>
|
| 137 |
+
</div>
|
| 138 |
+
</div>
|
| 139 |
+
|
| 140 |
+
{/* Right Column - Premium AJAX Formspree Card */}
|
| 141 |
+
<div className="lg:col-span-7 bg-white p-8 rounded-[24px] border border-slate-100 shadow-xl shadow-slate-100/30">
|
| 142 |
+
<form onSubmit={handleSubmit} className="space-y-5" id="formspree-contact-form">
|
| 143 |
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-5">
|
| 144 |
+
{/* Name */}
|
| 145 |
+
<div className="text-left">
|
| 146 |
+
<label htmlFor="form-name" className="block text-xs font-semibold text-slate-500 font-mono uppercase tracking-wider mb-2">
|
| 147 |
+
Your Name <span className="text-rose-500">*</span>
|
| 148 |
+
</label>
|
| 149 |
+
<input
|
| 150 |
+
type="text"
|
| 151 |
+
id="form-name"
|
| 152 |
+
name="name"
|
| 153 |
+
required
|
| 154 |
+
value={formData.name}
|
| 155 |
+
onChange={handleChange}
|
| 156 |
+
placeholder="E.g., Liam Carter"
|
| 157 |
+
className="w-full px-4 py-3 rounded-xl border border-slate-200/80 bg-slate-50/20 text-slate-800 text-sm focus:outline-none focus:ring-1 focus:ring-violet-500 focus:border-violet-500 focus:bg-white transition"
|
| 158 |
+
/>
|
| 159 |
+
</div>
|
| 160 |
+
|
| 161 |
+
{/* Email */}
|
| 162 |
+
<div className="text-left">
|
| 163 |
+
<label htmlFor="form-email" className="block text-xs font-semibold text-slate-500 font-mono uppercase tracking-wider mb-2">
|
| 164 |
+
Email Address <span className="text-rose-500">*</span>
|
| 165 |
+
</label>
|
| 166 |
+
<input
|
| 167 |
+
type="email"
|
| 168 |
+
id="form-email"
|
| 169 |
+
name="email"
|
| 170 |
+
required
|
| 171 |
+
value={formData.email}
|
| 172 |
+
onChange={handleChange}
|
| 173 |
+
placeholder="E.g., liam@corp.com"
|
| 174 |
+
className="w-full px-4 py-3 rounded-xl border border-slate-200/80 bg-slate-50/20 text-slate-800 text-sm focus:outline-none focus:ring-1 focus:ring-violet-500 focus:border-violet-500 focus:bg-white transition"
|
| 175 |
+
/>
|
| 176 |
+
</div>
|
| 177 |
+
</div>
|
| 178 |
+
|
| 179 |
+
{/* Subject */}
|
| 180 |
+
<div className="text-left">
|
| 181 |
+
<label htmlFor="form-subject" className="block text-xs font-semibold text-slate-500 font-mono uppercase tracking-wider mb-2">
|
| 182 |
+
Inquiry Subject
|
| 183 |
+
</label>
|
| 184 |
+
<input
|
| 185 |
+
type="text"
|
| 186 |
+
id="form-subject"
|
| 187 |
+
name="subject"
|
| 188 |
+
value={formData.subject}
|
| 189 |
+
onChange={handleChange}
|
| 190 |
+
placeholder="E.g., Format support setup or folder watchers"
|
| 191 |
+
className="w-full px-4 py-3 rounded-xl border border-slate-200/80 bg-slate-50/20 text-slate-800 text-sm focus:outline-none focus:ring-1 focus:ring-violet-500 focus:border-violet-500 focus:bg-white transition"
|
| 192 |
+
/>
|
| 193 |
+
</div>
|
| 194 |
+
|
| 195 |
+
{/* Message */}
|
| 196 |
+
<div className="text-left">
|
| 197 |
+
<label htmlFor="form-message" className="block text-xs font-semibold text-slate-500 font-mono uppercase tracking-wider mb-2">
|
| 198 |
+
Message Details <span className="text-rose-500">*</span>
|
| 199 |
+
</label>
|
| 200 |
+
<textarea
|
| 201 |
+
id="form-message"
|
| 202 |
+
name="message"
|
| 203 |
+
required
|
| 204 |
+
rows={4}
|
| 205 |
+
value={formData.message}
|
| 206 |
+
onChange={handleChange}
|
| 207 |
+
placeholder="How can we assist you?"
|
| 208 |
+
className="w-full px-4 py-3 rounded-xl border border-slate-200/80 bg-slate-50/20 text-slate-800 text-sm focus:outline-none focus:ring-1 focus:ring-violet-500 focus:border-violet-500 focus:bg-white transition resize-none"
|
| 209 |
+
/>
|
| 210 |
+
</div>
|
| 211 |
+
|
| 212 |
+
{/* Status Notifications */}
|
| 213 |
+
{formStatus === "success" && (
|
| 214 |
+
<div className="p-4 rounded-xl bg-emerald-50 border border-emerald-100 flex items-start text-left text-emerald-800 space-x-2.5">
|
| 215 |
+
<CheckCircle className="w-5 h-5 text-emerald-600 flex-shrink-0 mt-0.5" />
|
| 216 |
+
<div>
|
| 217 |
+
<h5 className="text-xs font-bold font-mono tracking-wider uppercase">Message Transmitted!</h5>
|
| 218 |
+
<p className="text-xs text-slate-650 mt-0.5">Thank you. Your request is in queue. Our support specialists will contact you very soon.</p>
|
| 219 |
+
</div>
|
| 220 |
+
</div>
|
| 221 |
+
)}
|
| 222 |
+
|
| 223 |
+
{formStatus === "error" && (
|
| 224 |
+
<div className="p-4 rounded-xl bg-rose-50 border border-rose-100 flex items-start text-left text-rose-800 space-x-2.5">
|
| 225 |
+
<AlertTriangle className="w-5 h-5 text-rose-600 flex-shrink-0 mt-0.5" />
|
| 226 |
+
<div>
|
| 227 |
+
<h5 className="text-xs font-bold font-mono tracking-wider uppercase">Missing Parameters</h5>
|
| 228 |
+
<p className="text-xs text-slate-650 mt-0.5">{errorMessage}</p>
|
| 229 |
+
</div>
|
| 230 |
+
</div>
|
| 231 |
+
)}
|
| 232 |
+
|
| 233 |
+
{/* Submit button */}
|
| 234 |
+
<button
|
| 235 |
+
type="submit"
|
| 236 |
+
disabled={formStatus === "submitting"}
|
| 237 |
+
id="contact-form-submit-btn"
|
| 238 |
+
className={`w-full py-4 rounded-xl font-semibold flex items-center justify-center space-x-2 border transition-all cursor-pointer ${
|
| 239 |
+
formStatus === "submitting"
|
| 240 |
+
? "bg-stone-100 text-slate-400 border-stone-100 cursor-not-allowed"
|
| 241 |
+
: "bg-slate-900 border-slate-900 text-white hover:bg-violet-600 hover:border-violet-600 shadow-md active:scale-98"
|
| 242 |
+
}`}
|
| 243 |
+
>
|
| 244 |
+
{formStatus === "submitting" ? (
|
| 245 |
+
<>
|
| 246 |
+
<span className="w-4 h-4 border-2 border-slate-400 border-t-slate-800 rounded-full animate-spin inline-block mr-2" />
|
| 247 |
+
<span>Engaging Formspree Gateway...</span>
|
| 248 |
+
</>
|
| 249 |
+
) : (
|
| 250 |
+
<>
|
| 251 |
+
<Send className="w-4 h-4" />
|
| 252 |
+
<span>Send Message Securely</span>
|
| 253 |
+
</>
|
| 254 |
+
)}
|
| 255 |
+
</button>
|
| 256 |
+
</form>
|
| 257 |
+
</div>
|
| 258 |
+
</div>
|
| 259 |
+
</div>
|
| 260 |
+
</section>
|
| 261 |
+
);
|
| 262 |
+
}
|
all-file-converter/src/components/FAQ.tsx
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useState } from "react";
|
| 2 |
+
import { Plus, Minus, HelpCircle, MessageSquare } from "lucide-react";
|
| 3 |
+
import { motion, AnimatePresence } from "motion/react";
|
| 4 |
+
|
| 5 |
+
export default function FAQ() {
|
| 6 |
+
const [openId, setOpenId] = useState<string | null>("faq-0"); // keep first open by default
|
| 7 |
+
|
| 8 |
+
const faqs = [
|
| 9 |
+
{
|
| 10 |
+
id: "faq-0",
|
| 11 |
+
question: "Is Lumina Convert free to use?",
|
| 12 |
+
answer: "Yes! Lumina Convert is 100% free at all times with absolutely no limitations, file size restricts, or premium locks. It supports all 200+ formats straight out of the box, with zero watermark logs, offline telemetry, or sign-up gates. Our team is fully committed to keeping it a clean, accessible security asset for the global development community.",
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
id: "faq-1",
|
| 16 |
+
question: "Does my data or files get uploaded to any online server?",
|
| 17 |
+
answer: "Absolutely not. Lumina Convert is configured as an 'offline-first' software. When you drop files, 100% of the conversion process occurs on your computer. Your files never leave your machine which guarantees absolute protection from leak risks, compliance audits (HIPAA/GDPR), and slow internet queues.",
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
id: "faq-2",
|
| 21 |
+
question: "Which file formats are supported?",
|
| 22 |
+
answer: "We support over 200+ formats! This includes PDFs, Microsoft Office documents (DOCX, XLSX, PPTX), rich images (PNG, WebP, JPG, SVG, TIFF), high-fidelity video codecs (MP4, MOV, MKV, AVI, WebM), audio containers (MP3, WAV, FLAC, AAC), and software formats like JSON, XML, or archives.",
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
id: "faq-3",
|
| 26 |
+
question: "Is technical support available? Can I reach you on WhatsApp?",
|
| 27 |
+
answer: "Yes, we offer real-time customer support! You can reach out directly via WhatsApp at +92-303-4572298 or email us anytime at bahaduralimunnabhai@gmail.com. We operate standard under 12-hour response SLAs, helping you install codecs or configure directory watchers.",
|
| 28 |
+
},
|
| 29 |
+
];
|
| 30 |
+
|
| 31 |
+
return (
|
| 32 |
+
<section id="faq" className="py-24 bg-white relative">
|
| 33 |
+
<div className="max-w-4xl mx-auto px-4 md:px-8">
|
| 34 |
+
{/* Header */}
|
| 35 |
+
<div className="text-center max-w-2xl mx-auto mb-16">
|
| 36 |
+
<span className="text-xs font-bold font-mono tracking-wider text-violet-600 uppercase bg-violet-50 px-3.5 py-1.5 rounded-full">
|
| 37 |
+
Frequently Asked
|
| 38 |
+
</span>
|
| 39 |
+
<h2 className="font-display font-bold text-3xl sm:text-4xl text-slate-900 tracking-tight mt-4 mb-4">
|
| 40 |
+
Got questions? We have{" "}
|
| 41 |
+
<span className="bg-gradient-to-r from-violet-600 to-indigo-600 bg-clip-text text-transparent">
|
| 42 |
+
answers
|
| 43 |
+
</span>
|
| 44 |
+
</h2>
|
| 45 |
+
<p className="text-slate-500 text-sm md:text-base font-light">
|
| 46 |
+
Everything you need to know about formats, compliance standards, license activation, and local installation.
|
| 47 |
+
</p>
|
| 48 |
+
</div>
|
| 49 |
+
|
| 50 |
+
{/* FAQs list accordion */}
|
| 51 |
+
<div className="space-y-4" id="faq-accordion-group">
|
| 52 |
+
{faqs.map((faq, index) => {
|
| 53 |
+
const isOpen = openId === faq.id;
|
| 54 |
+
return (
|
| 55 |
+
<div
|
| 56 |
+
key={faq.id}
|
| 57 |
+
className={`rounded-[24px] border transition-all duration-300 overflow-hidden ${
|
| 58 |
+
isOpen
|
| 59 |
+
? "bg-slate-50/50 border-violet-100 shadow-sm"
|
| 60 |
+
: "bg-white border-slate-100 hover:border-slate-200"
|
| 61 |
+
}`}
|
| 62 |
+
id={faq.id}
|
| 63 |
+
>
|
| 64 |
+
<button
|
| 65 |
+
onClick={() => setOpenId(isOpen ? null : faq.id)}
|
| 66 |
+
className="w-full py-5 px-6 md:px-8 flex items-center justify-between text-left focus:outline-none cursor-pointer"
|
| 67 |
+
id={`faq-btn-${faq.id}`}
|
| 68 |
+
>
|
| 69 |
+
<span className="font-display font-semibold text-base text-slate-800 pr-4">
|
| 70 |
+
{faq.question}
|
| 71 |
+
</span>
|
| 72 |
+
<div
|
| 73 |
+
className={`w-8 h-8 rounded-full border border-slate-105 flex items-center justify-center transition-transform duration-300 ${
|
| 74 |
+
isOpen ? "bg-violet-600 text-white border-violet-600 rotate-185" : "text-slate-400 bg-white"
|
| 75 |
+
}`}
|
| 76 |
+
>
|
| 77 |
+
{isOpen ? (
|
| 78 |
+
<Minus className="w-4 h-4 stroke-[2.5]" />
|
| 79 |
+
) : (
|
| 80 |
+
<Plus className="w-4 h-4 stroke-[2.5]" />
|
| 81 |
+
)}
|
| 82 |
+
</div>
|
| 83 |
+
</button>
|
| 84 |
+
|
| 85 |
+
<AnimatePresence initial={false}>
|
| 86 |
+
{isOpen && (
|
| 87 |
+
<motion.div
|
| 88 |
+
initial={{ height: 0 }}
|
| 89 |
+
animate={{ height: "auto" }}
|
| 90 |
+
exit={{ height: 0 }}
|
| 91 |
+
transition={{ duration: 0.25, ease: "easeInOut" }}
|
| 92 |
+
>
|
| 93 |
+
<div className="px-6 md:px-8 pb-6 text-sm text-slate-500 font-light leading-relaxed border-t border-slate-100/50 pt-3">
|
| 94 |
+
{faq.answer}
|
| 95 |
+
</div>
|
| 96 |
+
</motion.div>
|
| 97 |
+
)}
|
| 98 |
+
</AnimatePresence>
|
| 99 |
+
</div>
|
| 100 |
+
);
|
| 101 |
+
})}
|
| 102 |
+
</div>
|
| 103 |
+
|
| 104 |
+
{/* Floating Support Info */}
|
| 105 |
+
<div className="mt-12 p-6 rounded-3xl bg-slate-50 border border-slate-100/50 flex flex-col sm:flex-row items-center justify-between gap-4 text-left">
|
| 106 |
+
<div className="flex items-center space-x-3.5">
|
| 107 |
+
<div className="w-10 h-10 rounded-2xl bg-white flex items-center justify-center text-violet-600 shadow-sm">
|
| 108 |
+
<MessageSquare className="w-5 h-5 animate-pulse" />
|
| 109 |
+
</div>
|
| 110 |
+
<div>
|
| 111 |
+
<h4 className="text-sm font-semibold text-slate-900">Need personal folder automation?</h4>
|
| 112 |
+
<p className="text-xs text-slate-500 font-light mt-0.5">We offer custom shell triggers for business server arrays.</p>
|
| 113 |
+
</div>
|
| 114 |
+
</div>
|
| 115 |
+
<div className="flex space-x-3 flex-wrap">
|
| 116 |
+
<a
|
| 117 |
+
href="https://wa.me/923034572298"
|
| 118 |
+
target="_blank"
|
| 119 |
+
rel="noopener noreferrer"
|
| 120 |
+
id="faq-whatsapp-chat-btn"
|
| 121 |
+
className="py-2 px-4 rounded-xl bg-emerald-600 text-white font-semibold text-xs shadow-sm hover:bg-emerald-700 transition"
|
| 122 |
+
>
|
| 123 |
+
WhatsApp Us
|
| 124 |
+
</a>
|
| 125 |
+
<a
|
| 126 |
+
href="mailto:bahaduralimunnabhai@gmail.com"
|
| 127 |
+
id="faq-email-chat-btn"
|
| 128 |
+
className="py-2 px-4 rounded-xl border border-slate-205 text-slate-700 font-semibold text-xs hover:bg-slate-50 transition"
|
| 129 |
+
>
|
| 130 |
+
Email Specialist
|
| 131 |
+
</a>
|
| 132 |
+
</div>
|
| 133 |
+
</div>
|
| 134 |
+
</div>
|
| 135 |
+
</section>
|
| 136 |
+
);
|
| 137 |
+
}
|
all-file-converter/src/components/Features.tsx
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ShieldCheck, Cpu, Layers, Sparkles, FolderSync, MousePointerClick } from "lucide-react";
|
| 2 |
+
import { motion } from "motion/react";
|
| 3 |
+
|
| 4 |
+
export default function Features() {
|
| 5 |
+
const featuresList = [
|
| 6 |
+
{
|
| 7 |
+
id: "feat-formats",
|
| 8 |
+
title: "200+ Multi-Media Formats",
|
| 9 |
+
description: "Seamlessly convert documents (PDF, Word, TXT), images (WebP, PNG, JPG, GIF), videos (MP4, AVI, MKV), and audios (MP3, WAV, FLAC).",
|
| 10 |
+
icon: <Layers className="w-5 h-5 text-violet-600" />,
|
| 11 |
+
},
|
| 12 |
+
{
|
| 13 |
+
id: "feat-offline",
|
| 14 |
+
title: "100% On-Device Offline Engine",
|
| 15 |
+
description: "Keep private business compliance pristine. Zero server uploads mean 100% data confidentiality, shielding you from third-party server risks.",
|
| 16 |
+
icon: <ShieldCheck className="w-5 h-5 text-indigo-600" />,
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
id: "feat-gpu",
|
| 20 |
+
title: "GPU Hardware Accelerated",
|
| 21 |
+
description: "Fully optimized for Nvidia CUDA, OpenCL, and Apple Metal. Achieve up to 200x speedups during complex encoding and file compressing.",
|
| 22 |
+
icon: <Cpu className="w-5 h-5 text-fuchsia-600" />,
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
id: "feat-ai",
|
| 26 |
+
title: "Local AI Super-Resolution",
|
| 27 |
+
description: "Upscale pixelated images, clarify noisy interviews, or automatically summarize files using fully local models with no token usage.",
|
| 28 |
+
icon: <Sparkles className="w-5 h-5 text-violet-500" />,
|
| 29 |
+
},
|
| 30 |
+
{
|
| 31 |
+
id: "feat-batch",
|
| 32 |
+
title: "Smart Batch Pipeline",
|
| 33 |
+
description: "Drop folder collections other software crashes on. Parallel multitasking processing converts batches of 500+ items seamlessly.",
|
| 34 |
+
icon: <FolderSync className="w-5 h-5 text-emerald-500" />,
|
| 35 |
+
},
|
| 36 |
+
{
|
| 37 |
+
id: "feat-drag",
|
| 38 |
+
title: "Fluid Drag & Drop Workspace",
|
| 39 |
+
description: "Drop files directly into the minimized background desktop panel or folder watch list to process media in seconds.",
|
| 40 |
+
icon: <MousePointerClick className="w-5 h-5 text-indigo-500" />,
|
| 41 |
+
},
|
| 42 |
+
];
|
| 43 |
+
|
| 44 |
+
return (
|
| 45 |
+
<section id="features" className="py-24 bg-gradient-to-b from-white to-[#FAF9FE] relative">
|
| 46 |
+
<div className="max-w-7xl mx-auto px-4 md:px-8">
|
| 47 |
+
{/* Header */}
|
| 48 |
+
<div className="text-center max-w-2xl mx-auto mb-16">
|
| 49 |
+
<span className="text-xs font-bold font-mono tracking-wider text-violet-600 uppercase bg-violet-50 px-3.5 py-1.5 rounded-full">
|
| 50 |
+
Technical Architecture
|
| 51 |
+
</span>
|
| 52 |
+
<h2 className="font-display font-bold text-3xl sm:text-4xl text-slate-900 tracking-tight mt-4 mb-5">
|
| 53 |
+
Engineered for{" "}
|
| 54 |
+
<span className="bg-gradient-to-r from-violet-600 to-indigo-600 bg-clip-text text-transparent">
|
| 55 |
+
maximum power
|
| 56 |
+
</span>
|
| 57 |
+
</h2>
|
| 58 |
+
<p className="text-slate-500 text-base font-light">
|
| 59 |
+
Why send confidential layouts and corporate multimedia to server queues? Protect your pipelines with high-speed local processing.
|
| 60 |
+
</p>
|
| 61 |
+
</div>
|
| 62 |
+
|
| 63 |
+
{/* Feature Grid */}
|
| 64 |
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8" id="features-cards-grid">
|
| 65 |
+
{featuresList.map((feature, i) => (
|
| 66 |
+
<motion.div
|
| 67 |
+
key={feature.id}
|
| 68 |
+
initial={{ opacity: 0, y: 25 }}
|
| 69 |
+
whileInView={{ opacity: 1, y: 0 }}
|
| 70 |
+
viewport={{ once: true, margin: "-50px" }}
|
| 71 |
+
transition={{ delay: i * 0.05, duration: 0.5 }}
|
| 72 |
+
whileHover={{ y: -6, shadow: "0 20px 40px -15px rgba(0,0,0,0.07)" }}
|
| 73 |
+
className="p-8 rounded-[24px] bg-white border border-slate-100 shadow-md shadow-slate-100/30 text-left transition-all relative group overflow-hidden"
|
| 74 |
+
id={feature.id}
|
| 75 |
+
>
|
| 76 |
+
{/* Highlight background shine */}
|
| 77 |
+
<div className="absolute inset-0 bg-gradient-to-br from-violet-50/10 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
|
| 78 |
+
|
| 79 |
+
<div className="w-12 h-12 rounded-2xl bg-slate-50 border border-slate-100/50 flex items-center justify-center mb-6 shadow-sm group-hover:scale-110 group-hover:border-violet-100 group-hover:bg-violet-50/20 transition-all duration-300">
|
| 80 |
+
{feature.icon}
|
| 81 |
+
</div>
|
| 82 |
+
|
| 83 |
+
<div>
|
| 84 |
+
<h3 className="font-display font-semibold text-lg text-slate-800 mb-2.5 tracking-tight group-hover:text-violet-600 transition-colors">
|
| 85 |
+
{feature.title}
|
| 86 |
+
</h3>
|
| 87 |
+
<p className="text-slate-500 text-sm leading-relaxed font-light">
|
| 88 |
+
{feature.description}
|
| 89 |
+
</p>
|
| 90 |
+
</div>
|
| 91 |
+
</motion.div>
|
| 92 |
+
))}
|
| 93 |
+
</div>
|
| 94 |
+
</div>
|
| 95 |
+
</section>
|
| 96 |
+
);
|
| 97 |
+
}
|
all-file-converter/src/components/Footer.tsx
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ShieldCheck, Mail, ArrowUp, Github, Linkedin, HelpCircle } from "lucide-react";
|
| 2 |
+
import { Link } from "react-router-dom";
|
| 3 |
+
|
| 4 |
+
export default function Footer() {
|
| 5 |
+
const socialIcons = [
|
| 6 |
+
{
|
| 7 |
+
name: "HuggingFace",
|
| 8 |
+
url: "https://huggingface.co/embedingHF",
|
| 9 |
+
icon: (
|
| 10 |
+
<span className="text-xs font-bold font-mono tracking-tighter bg-amber-50 text-amber-600 px-2.5 py-1 rounded-lg border border-amber-200 hover:bg-amber-100/50 transition">
|
| 11 |
+
🤗 HuggingFace
|
| 12 |
+
</span>
|
| 13 |
+
),
|
| 14 |
+
},
|
| 15 |
+
{
|
| 16 |
+
name: "GitHub",
|
| 17 |
+
url: "https://github.com",
|
| 18 |
+
icon: <Github className="w-4 h-4 text-slate-500 hover:text-slate-900 transition" />,
|
| 19 |
+
},
|
| 20 |
+
{
|
| 21 |
+
name: "LinkedIn",
|
| 22 |
+
url: "https://linkedin.com",
|
| 23 |
+
icon: <Linkedin className="w-4 h-4 text-indigo-500 hover:text-indigo-700 transition" />,
|
| 24 |
+
},
|
| 25 |
+
];
|
| 26 |
+
|
| 27 |
+
const productLinks = [
|
| 28 |
+
{ name: "Home Dashboard", path: "/" },
|
| 29 |
+
{ name: "Technical Specifications", path: "/features" },
|
| 30 |
+
{ name: "Support Development", path: "/support" },
|
| 31 |
+
{ name: "Common FAQs", path: "/faq" },
|
| 32 |
+
{ name: "Privacy & HIPAA Policy", path: "/privacy" },
|
| 33 |
+
{ name: "Developer Ticket Portal", path: "/contact" },
|
| 34 |
+
];
|
| 35 |
+
|
| 36 |
+
const scrollToTop = () => {
|
| 37 |
+
window.scrollTo({
|
| 38 |
+
top: 0,
|
| 39 |
+
behavior: "smooth",
|
| 40 |
+
});
|
| 41 |
+
};
|
| 42 |
+
|
| 43 |
+
return (
|
| 44 |
+
<footer className="bg-slate-950 text-white relative pt-16 pb-12 overflow-hidden border-t border-slate-900">
|
| 45 |
+
{/* Absolute top grid subtle gradient */}
|
| 46 |
+
<div className="absolute top-0 left-0 right-0 h-[1.5px] bg-gradient-to-r from-transparent via-slate-800 to-transparent pointer-events-none" />
|
| 47 |
+
|
| 48 |
+
<div className="max-w-7xl mx-auto px-4 md:px-8 grid grid-cols-1 md:grid-cols-12 gap-12 text-left relative z-10 mb-12">
|
| 49 |
+
{/* Logo and brief */}
|
| 50 |
+
<div className="md:col-span-4 space-y-4">
|
| 51 |
+
<div className="flex items-center space-x-2.5">
|
| 52 |
+
<div className="w-9 h-9 rounded-xl bg-gradient-to-tr from-violet-500 to-indigo-500 flex items-center justify-center shadow-md shadow-violet-500/20">
|
| 53 |
+
<ShieldCheck className="w-5 h-5 text-white" />
|
| 54 |
+
</div>
|
| 55 |
+
<div className="text-left font-display">
|
| 56 |
+
<span className="block font-semibold text-base text-white">Lumina Convert</span>
|
| 57 |
+
<span className="block text-[10px] uppercase font-mono tracking-widest text-violet-400 -mt-1 font-semibold">
|
| 58 |
+
All File Converter
|
| 59 |
+
</span>
|
| 60 |
+
</div>
|
| 61 |
+
</div>
|
| 62 |
+
<p className="text-slate-400 text-xs font-light leading-relaxed max-w-sm">
|
| 63 |
+
High performance, standalone software processing document conversions locally on your computer with full hardware acceleration. Keep control of your intellectual property.
|
| 64 |
+
</p>
|
| 65 |
+
</div>
|
| 66 |
+
|
| 67 |
+
{/* Navigation Quicklinks */}
|
| 68 |
+
<div className="md:col-span-4 space-y-4">
|
| 69 |
+
<h4 className="text-xs font-mono font-bold tracking-wider uppercase text-slate-400 border-b border-white/5 pb-2">
|
| 70 |
+
Dynamic Navigation Directory
|
| 71 |
+
</h4>
|
| 72 |
+
<ul className="grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-2.5">
|
| 73 |
+
{productLinks.map((link) => (
|
| 74 |
+
<li key={link.path}>
|
| 75 |
+
<Link
|
| 76 |
+
to={link.path}
|
| 77 |
+
id={`footer-nav-${link.name.toLowerCase().replace(/\s+/g, "-")}`}
|
| 78 |
+
className="text-slate-400 hover:text-white text-xs font-medium tracking-wide transition cursor-pointer"
|
| 79 |
+
>
|
| 80 |
+
{link.name}
|
| 81 |
+
</Link>
|
| 82 |
+
</li>
|
| 83 |
+
))}
|
| 84 |
+
</ul>
|
| 85 |
+
</div>
|
| 86 |
+
|
| 87 |
+
{/* Contact details */}
|
| 88 |
+
<div className="md:col-span-4 space-y-4">
|
| 89 |
+
<h4 className="text-xs font-mono font-bold tracking-wider uppercase text-slate-400 border-b border-white/5 pb-2">
|
| 90 |
+
Secure Help Desk
|
| 91 |
+
</h4>
|
| 92 |
+
<div className="space-y-2.5 text-xs text-slate-400">
|
| 93 |
+
<p className="flex items-center space-x-2">
|
| 94 |
+
<span className="text-slate-500 font-mono">Mail:</span>
|
| 95 |
+
<a href="mailto:bahaduralimunnabhai@gmail.com" id="footer-secure-email" className="hover:text-white transition">
|
| 96 |
+
bahaduralimunnabhai@gmail.com
|
| 97 |
+
</a>
|
| 98 |
+
</p>
|
| 99 |
+
<p className="flex items-center space-x-2">
|
| 100 |
+
<span className="text-slate-500 font-mono">WhatsApp Desk:</span>
|
| 101 |
+
<a
|
| 102 |
+
href="https://wa.me/923034572298"
|
| 103 |
+
target="_blank"
|
| 104 |
+
rel="noopener noreferrer"
|
| 105 |
+
id="footer-secure-whatsapp"
|
| 106 |
+
className="hover:text-white transition"
|
| 107 |
+
>
|
| 108 |
+
+92 303 4572298
|
| 109 |
+
</a>
|
| 110 |
+
</p>
|
| 111 |
+
<div className="flex gap-2 items-start mt-4 p-3 bg-white/5 rounded-xl border border-white/5">
|
| 112 |
+
<HelpCircle className="w-3.5 h-3.5 text-violet-400 flex-shrink-0 mt-0.5" />
|
| 113 |
+
<p className="text-[10px] text-slate-400 font-light leading-relaxed">
|
| 114 |
+
Need customized bulk CLI converters or folder watchers support? Call our developer hotline instantly.
|
| 115 |
+
</p>
|
| 116 |
+
</div>
|
| 117 |
+
</div>
|
| 118 |
+
</div>
|
| 119 |
+
</div>
|
| 120 |
+
|
| 121 |
+
{/* Social links / Bottom Bar */}
|
| 122 |
+
<div className="max-w-7xl mx-auto px-4 md:px-8 border-t border-white/5 pt-8 flex flex-col sm:flex-row items-center justify-between gap-6">
|
| 123 |
+
<div className="flex flex-col sm:flex-row items-center space-y-2 sm:space-y-0 sm:space-x-4 text-xs font-mono text-slate-500 text-center sm:text-left">
|
| 124 |
+
<span>© {new Date().getFullYear()} All File Converter / Lumina Convert.</span>
|
| 125 |
+
<span className="hidden sm:inline text-slate-700">|</span>
|
| 126 |
+
<span className="text-[10px]">100% Offline HIPAA & GDPR Codec Compliant.</span>
|
| 127 |
+
</div>
|
| 128 |
+
|
| 129 |
+
{/* Social channels bar */}
|
| 130 |
+
<div className="flex items-center space-x-4">
|
| 131 |
+
<div className="flex items-center space-x-3 pr-4 border-r border-white/5">
|
| 132 |
+
{socialIcons.map((soc, idx) => (
|
| 133 |
+
<a
|
| 134 |
+
key={idx}
|
| 135 |
+
href={soc.url}
|
| 136 |
+
target="_blank"
|
| 137 |
+
rel="noopener noreferrer"
|
| 138 |
+
id={`footer-social-${soc.name.toLowerCase()}`}
|
| 139 |
+
title={soc.name}
|
| 140 |
+
>
|
| 141 |
+
{soc.icon}
|
| 142 |
+
</a>
|
| 143 |
+
))}
|
| 144 |
+
</div>
|
| 145 |
+
|
| 146 |
+
{/* scroll to top rocket */}
|
| 147 |
+
<button
|
| 148 |
+
onClick={scrollToTop}
|
| 149 |
+
id="footer-scroll-top-btn"
|
| 150 |
+
className="w-8 h-8 rounded-full bg-white/5 text-slate-400 hover:text-white hover:bg-violet-600 transition flex items-center justify-center cursor-pointer shadow-inner"
|
| 151 |
+
title="Scroll to Top"
|
| 152 |
+
>
|
| 153 |
+
<ArrowUp className="w-4 h-4" />
|
| 154 |
+
</button>
|
| 155 |
+
</div>
|
| 156 |
+
</div>
|
| 157 |
+
</footer>
|
| 158 |
+
);
|
| 159 |
+
}
|
all-file-converter/src/components/Hero.tsx
ADDED
|
@@ -0,0 +1,423 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useState, useRef, ChangeEvent } from "react";
|
| 2 |
+
import { Download, Play, FileUp, Sparkles, Cpu, CheckCircle, RefreshCw, FileText, Image as ImageIcon, Video, Music } from "lucide-react";
|
| 3 |
+
import { motion, AnimatePresence } from "motion/react";
|
| 4 |
+
|
| 5 |
+
interface HeroProps {
|
| 6 |
+
downloadUrl: string;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
const PRESET_FILES = [
|
| 10 |
+
{ name: "quarterly_report.docx", size: "2.4 MB", type: "document" },
|
| 11 |
+
{ name: "product_photo.png", size: "8.1 MB", type: "image" },
|
| 12 |
+
{ name: "marketing_pitch.mp4", size: "45.2 MB", type: "video" },
|
| 13 |
+
{ name: "intro_music.mp3", size: "5.7 MB", type: "audio" },
|
| 14 |
+
];
|
| 15 |
+
|
| 16 |
+
const CONVERSION_OPTIONS: Record<string, string[]> = {
|
| 17 |
+
document: ["PDF Document (.pdf)", "Markdown Text (.md)", "eBook (.epub)", "Web Page (.html)"],
|
| 18 |
+
image: ["WebP Image (.webp)", "JPEG Premium (.jpg)", "PNG Lossless (.png)", "PDF Page (.pdf)"],
|
| 19 |
+
video: ["MP4 Video (.mp4)", "GIF Animation (.gif)", "MP3 Audio (.mp3)", "AVI Format (.avi)"],
|
| 20 |
+
audio: ["WAV Lossless (.wav)", "AAC Advanced (.aac)", "MP3 Standard (.mp3)", "FLAC Studio (.flac)"],
|
| 21 |
+
};
|
| 22 |
+
|
| 23 |
+
export default function Hero({ downloadUrl }: HeroProps) {
|
| 24 |
+
const [selectedFile, setSelectedFile] = useState<typeof PRESET_FILES[0] | null>(PRESET_FILES[1]); // default to image
|
| 25 |
+
const [targetFormat, setTargetFormat] = useState<string>("WebP Image (.webp)");
|
| 26 |
+
const [isConverting, setIsConverting] = useState(false);
|
| 27 |
+
const [progress, setProgress] = useState(0);
|
| 28 |
+
const [gpuLoad, setGpuLoad] = useState(0);
|
| 29 |
+
const [isConverted, setIsConverted] = useState(false);
|
| 30 |
+
const [showNotification, setShowNotification] = useState(false);
|
| 31 |
+
|
| 32 |
+
// drag state
|
| 33 |
+
const [isDragOver, setIsDragOver] = useState(false);
|
| 34 |
+
const fileInputRef = useRef<HTMLInputElement>(null);
|
| 35 |
+
|
| 36 |
+
// handle preset selection
|
| 37 |
+
const selectPreset = (file: typeof PRESET_FILES[0]) => {
|
| 38 |
+
if (isConverting) return;
|
| 39 |
+
setSelectedFile(file);
|
| 40 |
+
setIsConverted(false);
|
| 41 |
+
setProgress(0);
|
| 42 |
+
// set first formatting option as default
|
| 43 |
+
const options = CONVERSION_OPTIONS[file.type];
|
| 44 |
+
setTargetFormat(options[0]);
|
| 45 |
+
};
|
| 46 |
+
|
| 47 |
+
// simulate conversion
|
| 48 |
+
const handleConvert = () => {
|
| 49 |
+
if (!selectedFile || isConverting) return;
|
| 50 |
+
setIsConverting(true);
|
| 51 |
+
setIsConverted(false);
|
| 52 |
+
setProgress(0);
|
| 53 |
+
|
| 54 |
+
const interval = setInterval(() => {
|
| 55 |
+
setProgress((prev) => {
|
| 56 |
+
// dynamic GPU metrics simulate load
|
| 57 |
+
setGpuLoad(Math.floor(Math.random() * 35) + 60); // 60-95% GPU load
|
| 58 |
+
if (prev >= 100) {
|
| 59 |
+
clearInterval(interval);
|
| 60 |
+
setGpuLoad(0);
|
| 61 |
+
setTimeout(() => {
|
| 62 |
+
setIsConverting(false);
|
| 63 |
+
setIsConverted(true);
|
| 64 |
+
setShowNotification(true);
|
| 65 |
+
setTimeout(() => setShowNotification(false), 4000);
|
| 66 |
+
}, 300);
|
| 67 |
+
return 100;
|
| 68 |
+
}
|
| 69 |
+
// accelerate progress conversion
|
| 70 |
+
const step = Math.floor(Math.random() * 15) + 8;
|
| 71 |
+
return Math.min(prev + step, 100);
|
| 72 |
+
});
|
| 73 |
+
}, 150);
|
| 74 |
+
};
|
| 75 |
+
|
| 76 |
+
const triggerScrollToFeatures = () => {
|
| 77 |
+
const el = document.getElementById("features");
|
| 78 |
+
if (el) {
|
| 79 |
+
window.scrollTo({
|
| 80 |
+
top: el.offsetTop - 85,
|
| 81 |
+
behavior: "smooth",
|
| 82 |
+
});
|
| 83 |
+
}
|
| 84 |
+
};
|
| 85 |
+
|
| 86 |
+
const handleCustomFileUpload = (e: ChangeEvent<HTMLInputElement>) => {
|
| 87 |
+
const file = e.target.files?.[0];
|
| 88 |
+
if (file) {
|
| 89 |
+
const type = file.type.startsWith("image/")
|
| 90 |
+
? "image"
|
| 91 |
+
: file.type.startsWith("video/")
|
| 92 |
+
? "video"
|
| 93 |
+
: file.type.startsWith("audio/")
|
| 94 |
+
? "audio"
|
| 95 |
+
: "document";
|
| 96 |
+
|
| 97 |
+
const mappedFile = {
|
| 98 |
+
name: file.name,
|
| 99 |
+
size: `${(file.size / (1024 * 1024)).toFixed(1)} MB`,
|
| 100 |
+
type,
|
| 101 |
+
};
|
| 102 |
+
setSelectedFile(mappedFile);
|
| 103 |
+
setIsConverted(false);
|
| 104 |
+
setProgress(0);
|
| 105 |
+
setTargetFormat(CONVERSION_OPTIONS[type][0]);
|
| 106 |
+
}
|
| 107 |
+
};
|
| 108 |
+
|
| 109 |
+
const iconForType = (type: string) => {
|
| 110 |
+
switch (type) {
|
| 111 |
+
case "document":
|
| 112 |
+
return <FileText className="w-5 h-5 text-indigo-500" />;
|
| 113 |
+
case "image":
|
| 114 |
+
return <ImageIcon className="w-5 h-5 text-violet-500" />;
|
| 115 |
+
case "video":
|
| 116 |
+
return <Video className="w-5 h-5 text-fuchsia-500" />;
|
| 117 |
+
case "audio":
|
| 118 |
+
return <Music className="w-5 h-5 text-emerald-500" />;
|
| 119 |
+
default:
|
| 120 |
+
return <FileText className="w-5 h-5 text-slate-500" />;
|
| 121 |
+
}
|
| 122 |
+
};
|
| 123 |
+
|
| 124 |
+
return (
|
| 125 |
+
<section
|
| 126 |
+
id="home"
|
| 127 |
+
className="relative pt-32 pb-24 md:pt-40 md:pb-36 bg-gradient-to-b from-[#FAF9FE] via-[#FBFBFD] to-white overflow-hidden min-h-screen flex flex-col justify-center"
|
| 128 |
+
>
|
| 129 |
+
{/* Decorative Orbs */}
|
| 130 |
+
<div className="absolute top-1/4 left-1/10 w-96 h-96 bg-violet-200/40 rounded-full blur-3xl pointer-events-none" />
|
| 131 |
+
<div className="absolute bottom-1/5 right-1/10 w-112 h-112 bg-indigo-200/30 rounded-full blur-3xl pointer-events-none" />
|
| 132 |
+
|
| 133 |
+
<div className="max-w-7xl mx-auto px-4 md:px-8 grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-8 items-center relative z-10 w-full">
|
| 134 |
+
{/* Left column: Text & CTAs */}
|
| 135 |
+
<div className="lg:col-span-6 flex flex-col justify-center text-center lg:text-left">
|
| 136 |
+
{/* Badge */}
|
| 137 |
+
<div className="inline-flex items-center space-x-2 bg-violet-50 border border-violet-100 px-3.5 py-1.5 rounded-full mx-auto lg:mx-0 w-fit mb-6">
|
| 138 |
+
<Sparkles className="w-3.5 h-3.5 text-violet-600 animate-pulse" />
|
| 139 |
+
<span className="text-xs font-semibold text-violet-700 font-mono uppercase tracking-wider">
|
| 140 |
+
v1.4.2 Released — Faster & Secure
|
| 141 |
+
</span>
|
| 142 |
+
</div>
|
| 143 |
+
|
| 144 |
+
{/* Headline */}
|
| 145 |
+
<h1 className="font-display text-4xl sm:text-5xl lg:text-6xl font-bold text-slate-900 tracking-tight leading-[1.1] mb-6">
|
| 146 |
+
Convert any file in{" "}
|
| 147 |
+
<span className="bg-gradient-to-r from-violet-600 via-indigo-600 to-fuchsia-600 bg-clip-text text-transparent">
|
| 148 |
+
seconds
|
| 149 |
+
</span>
|
| 150 |
+
</h1>
|
| 151 |
+
|
| 152 |
+
{/* Subtitle */}
|
| 153 |
+
<p className="text-slate-600 text-lg sm:text-xl font-light leading-relaxed max-w-2xl mx-auto lg:mx-0 mb-8">
|
| 154 |
+
{`Lumina Convert delivers ultra-secure, offline-first conversion supporting 200+ formats without exporting raw data to the cloud. Empowered by full local GPU acceleration.`}
|
| 155 |
+
</p>
|
| 156 |
+
|
| 157 |
+
{/* Direct CTA Buttons */}
|
| 158 |
+
<div className="flex flex-col sm:flex-row items-center justify-center lg:justify-start gap-4 mb-8">
|
| 159 |
+
<a
|
| 160 |
+
href={downloadUrl}
|
| 161 |
+
download
|
| 162 |
+
id="hero-download-setup-btn"
|
| 163 |
+
className="w-full sm:w-auto inline-flex items-center justify-center space-x-3 px-8 py-4 rounded-full bg-slate-900 text-white font-medium shadow-lg shadow-slate-900/10 hover:bg-violet-600 hover:shadow-violet-500/30 active:scale-98 transition-all duration-300 cursor-pointer"
|
| 164 |
+
>
|
| 165 |
+
<Download className="w-5 h-5 animate-bounce" />
|
| 166 |
+
<span className="text-base">Download for Windows</span>
|
| 167 |
+
</a>
|
| 168 |
+
<button
|
| 169 |
+
onClick={triggerScrollToFeatures}
|
| 170 |
+
id="hero-explore-features-btn"
|
| 171 |
+
className="w-full sm:w-auto inline-flex items-center justify-center space-x-2 px-8 py-4 rounded-full bg-white text-slate-700 border border-slate-200/80 font-medium hover:border-slate-300 hover:bg-slate-50 active:scale-98 transition-all duration-300 cursor-pointer"
|
| 172 |
+
>
|
| 173 |
+
<span>Explore Features</span>
|
| 174 |
+
</button>
|
| 175 |
+
</div>
|
| 176 |
+
|
| 177 |
+
{/* Extra metadata */}
|
| 178 |
+
<div className="flex items-center justify-center lg:justify-start space-x-6 text-slate-500 text-xs font-medium font-mono">
|
| 179 |
+
<span className="flex items-center space-x-1.5 border-r border-slate-200 pr-6">
|
| 180 |
+
<span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
|
| 181 |
+
<span>100% Offline Converter</span>
|
| 182 |
+
</span>
|
| 183 |
+
<span>Free Standard Version</span>
|
| 184 |
+
</div>
|
| 185 |
+
</div>
|
| 186 |
+
|
| 187 |
+
{/* Right column: Beautiful Interactive Glassmorphic Convertible Console */}
|
| 188 |
+
<div className="lg:col-span-6 w-full flex justify-center">
|
| 189 |
+
<div className="w-full max-w-lg rounded-3xl bg-white/70 backdrop-blur-xl border border-white/60 shadow-2xl shadow-slate-200/50 p-6 relative">
|
| 190 |
+
<div className="absolute top-3 left-4 flex space-x-1.5">
|
| 191 |
+
<span className="w-3 h-3 rounded-full bg-rose-400" />
|
| 192 |
+
<span className="w-3 h-3 rounded-full bg-amber-400" />
|
| 193 |
+
<span className="w-3 h-3 rounded-full bg-emerald-400" />
|
| 194 |
+
</div>
|
| 195 |
+
<div className="text-center font-mono text-[11px] text-slate-400 mb-6">
|
| 196 |
+
LuminaConvert_WebStudio_Lite
|
| 197 |
+
</div>
|
| 198 |
+
|
| 199 |
+
{/* Test Presets bar */}
|
| 200 |
+
<div className="mb-4">
|
| 201 |
+
<label className="block text-xs font-semibold text-slate-500 font-mono mb-2 uppercase tracking-wider">
|
| 202 |
+
Select a test file structure
|
| 203 |
+
</label>
|
| 204 |
+
<div className="grid grid-cols-4 gap-2">
|
| 205 |
+
{PRESET_FILES.map((file, idx) => (
|
| 206 |
+
<button
|
| 207 |
+
key={idx}
|
| 208 |
+
onClick={() => selectPreset(file)}
|
| 209 |
+
id={`hero-preset-file-${idx}`}
|
| 210 |
+
className={`p-2 rounded-xl border text-center transition-all focus:outline-none cursor-pointer flex flex-col items-center justify-center ${
|
| 211 |
+
selectedFile?.name === file.name
|
| 212 |
+
? "bg-violet-50/60 border-violet-200 shadow-sm"
|
| 213 |
+
: "bg-stone-50/20 border-slate-100 hover:bg-slate-50"
|
| 214 |
+
}`}
|
| 215 |
+
>
|
| 216 |
+
{iconForType(file.type)}
|
| 217 |
+
<span className="text-[9px] font-medium text-slate-700 truncate w-full mt-1">
|
| 218 |
+
{file.name.substring(0, 10)}...
|
| 219 |
+
</span>
|
| 220 |
+
</button>
|
| 221 |
+
))}
|
| 222 |
+
</div>
|
| 223 |
+
</div>
|
| 224 |
+
|
| 225 |
+
{/* Main converter box */}
|
| 226 |
+
<div
|
| 227 |
+
className={`bg-slate-50/50 rounded-2xl border-2 border-dashed p-6 transition-all relative ${
|
| 228 |
+
isDragOver ? "border-violet-400 bg-violet-50/20" : "border-slate-200/60"
|
| 229 |
+
}`}
|
| 230 |
+
onDragOver={(e) => {
|
| 231 |
+
e.preventDefault();
|
| 232 |
+
setIsDragOver(true);
|
| 233 |
+
}}
|
| 234 |
+
onDragLeave={() => setIsDragOver(false)}
|
| 235 |
+
onDrop={(e) => {
|
| 236 |
+
e.preventDefault();
|
| 237 |
+
setIsDragOver(false);
|
| 238 |
+
const file = e.dataTransfer.files?.[0];
|
| 239 |
+
if (file) {
|
| 240 |
+
const type = file.type.startsWith("image/")
|
| 241 |
+
? "image"
|
| 242 |
+
: file.type.startsWith("video/")
|
| 243 |
+
? "video"
|
| 244 |
+
: file.type.startsWith("audio/")
|
| 245 |
+
? "audio"
|
| 246 |
+
: "document";
|
| 247 |
+
|
| 248 |
+
setSelectedFile({
|
| 249 |
+
name: file.name,
|
| 250 |
+
size: `${(file.size / (1024 * 1024)).toFixed(1)} MB`,
|
| 251 |
+
type,
|
| 252 |
+
});
|
| 253 |
+
setIsConverted(false);
|
| 254 |
+
setProgress(0);
|
| 255 |
+
setTargetFormat(CONVERSION_OPTIONS[type][0]);
|
| 256 |
+
}
|
| 257 |
+
}}
|
| 258 |
+
>
|
| 259 |
+
<input
|
| 260 |
+
type="file"
|
| 261 |
+
ref={fileInputRef}
|
| 262 |
+
onChange={handleCustomFileUpload}
|
| 263 |
+
className="hidden"
|
| 264 |
+
id="hero-hidden-file-input"
|
| 265 |
+
/>
|
| 266 |
+
|
| 267 |
+
{selectedFile ? (
|
| 268 |
+
<div className="space-y-4">
|
| 269 |
+
<div className="flex items-center justify-between">
|
| 270 |
+
<div className="flex items-center space-x-3">
|
| 271 |
+
<div className="p-2.5 rounded-xl bg-white border border-slate-100 shadow-sm">
|
| 272 |
+
{iconForType(selectedFile.type)}
|
| 273 |
+
</div>
|
| 274 |
+
<div className="text-left">
|
| 275 |
+
<h4 className="text-sm font-semibold text-slate-800 line-clamp-1 max-w-[180px]">
|
| 276 |
+
{selectedFile.name}
|
| 277 |
+
</h4>
|
| 278 |
+
<p className="text-xs text-slate-500 font-mono">{selectedFile.size}</p>
|
| 279 |
+
</div>
|
| 280 |
+
</div>
|
| 281 |
+
|
| 282 |
+
<button
|
| 283 |
+
onClick={() => setSelectedFile(null)}
|
| 284 |
+
id="hero-remove-file-btn"
|
| 285 |
+
className="text-xs font-semibold text-rose-500 hover:text-rose-600 hover:underline cursor-pointer"
|
| 286 |
+
>
|
| 287 |
+
Remove
|
| 288 |
+
</button>
|
| 289 |
+
</div>
|
| 290 |
+
|
| 291 |
+
{/* Target format picker */}
|
| 292 |
+
<div className="text-left bg-white border border-slate-100/80 p-3.5 rounded-xl shadow-sm mt-3">
|
| 293 |
+
<span className="block text-[10px] font-mono text-slate-400 tracking-wider font-semibold uppercase mb-1">
|
| 294 |
+
Target format
|
| 295 |
+
</span>
|
| 296 |
+
<select
|
| 297 |
+
value={targetFormat}
|
| 298 |
+
onChange={(e) => {
|
| 299 |
+
setTargetFormat(e.target.value);
|
| 300 |
+
setIsConverted(false);
|
| 301 |
+
setProgress(0);
|
| 302 |
+
}}
|
| 303 |
+
id="hero-target-format-select"
|
| 304 |
+
className="w-full text-sm font-semibold text-slate-700 bg-transparent focus:outline-none cursor-pointer"
|
| 305 |
+
>
|
| 306 |
+
{CONVERSION_OPTIONS[selectedFile.type].map((opt, i) => (
|
| 307 |
+
<option key={i} value={opt}>
|
| 308 |
+
{opt}
|
| 309 |
+
</option>
|
| 310 |
+
))}
|
| 311 |
+
</select>
|
| 312 |
+
</div>
|
| 313 |
+
</div>
|
| 314 |
+
) : (
|
| 315 |
+
<button
|
| 316 |
+
onClick={() => fileInputRef.current?.click()}
|
| 317 |
+
id="hero-upload-area-btn"
|
| 318 |
+
className="w-full h-full flex flex-col items-center justify-center p-6 focus:outline-none cursor-pointer"
|
| 319 |
+
>
|
| 320 |
+
<div className="w-12 h-12 rounded-2xl bg-white border border-slate-100 flex items-center justify-center text-violet-500 shadow-sm mb-3">
|
| 321 |
+
<FileUp className="w-6 h-6" />
|
| 322 |
+
</div>
|
| 323 |
+
<span className="text-sm font-medium text-slate-700">Drag & drop or browse locally</span>
|
| 324 |
+
<span className="text-xs text-slate-400 mt-1">supports pdf, png, mp4, docx, mp3</span>
|
| 325 |
+
</button>
|
| 326 |
+
)}
|
| 327 |
+
</div>
|
| 328 |
+
|
| 329 |
+
{/* Actions / Progress tracking */}
|
| 330 |
+
<div className="mt-5 space-y-4">
|
| 331 |
+
{isConverting && (
|
| 332 |
+
<div className="space-y-2 p-4 rounded-xl bg-indigo-50/50 border border-indigo-100/50">
|
| 333 |
+
<div className="flex items-center justify-between text-xs font-mono">
|
| 334 |
+
<span className="flex items-center space-x-1.5 text-indigo-700">
|
| 335 |
+
<RefreshCw className="w-3.5 h-3.5 animate-spin" />
|
| 336 |
+
<span>Processing files...</span>
|
| 337 |
+
</span>
|
| 338 |
+
<span className="font-bold text-indigo-700">{progress}%</span>
|
| 339 |
+
</div>
|
| 340 |
+
<div className="w-full h-1.5 bg-indigo-100 rounded-full overflow-hidden">
|
| 341 |
+
<div
|
| 342 |
+
className="h-full bg-gradient-to-r from-violet-600 to-indigo-600 rounded-full transition-all duration-150"
|
| 343 |
+
style={{ width: `${progress}%` }}
|
| 344 |
+
/>
|
| 345 |
+
</div>
|
| 346 |
+
<div className="flex items-center justify-between text-[10px] font-mono text-slate-400 pt-1">
|
| 347 |
+
<span className="flex items-center space-x-1">
|
| 348 |
+
<Cpu className="w-3 h-3 text-violet-500 animate-pulse" />
|
| 349 |
+
<span>GPU Hardware: {gpuLoad}% (Local Core)</span>
|
| 350 |
+
</span>
|
| 351 |
+
<span>100% Offline safe</span>
|
| 352 |
+
</div>
|
| 353 |
+
</div>
|
| 354 |
+
)}
|
| 355 |
+
|
| 356 |
+
{isConverted && (
|
| 357 |
+
<motion.div
|
| 358 |
+
initial={{ opacity: 0, y: 10 }}
|
| 359 |
+
animate={{ opacity: 1, y: 0 }}
|
| 360 |
+
className="flex items-center justify-between p-4 rounded-2xl bg-emerald-50/80 border border-emerald-100 text-left"
|
| 361 |
+
>
|
| 362 |
+
<div className="flex items-center space-x-2.5">
|
| 363 |
+
<CheckCircle className="w-5 h-5 text-emerald-600 flex-shrink-0" />
|
| 364 |
+
<div>
|
| 365 |
+
<h5 className="text-xs font-semibold text-emerald-800 uppercase tracking-wider font-mono">
|
| 366 |
+
Conversion Complete
|
| 367 |
+
</h5>
|
| 368 |
+
<p className="text-slate-600 text-sm font-medium truncate max-w-[200px]">
|
| 369 |
+
{selectedFile?.name.split(".")[0] || ""}.
|
| 370 |
+
{targetFormat.match(/\(([^)]+)\)/)?.[1]?.replace(".", "") || "webp"}
|
| 371 |
+
</p>
|
| 372 |
+
</div>
|
| 373 |
+
</div>
|
| 374 |
+
<button
|
| 375 |
+
onClick={() => {
|
| 376 |
+
alert("Offline prototype converter success! The full offline desktop version is up to 200x faster for files up to 50GB. Redirecting to download full app package...");
|
| 377 |
+
window.location.href = downloadUrl;
|
| 378 |
+
}}
|
| 379 |
+
id="hero-download-converted-mock-btn"
|
| 380 |
+
className="px-3.5 py-1.5 rounded-lg bg-emerald-600 text-white text-xs font-semibold hover:bg-emerald-700 transition"
|
| 381 |
+
>
|
| 382 |
+
Download
|
| 383 |
+
</button>
|
| 384 |
+
</motion.div>
|
| 385 |
+
)}
|
| 386 |
+
|
| 387 |
+
<button
|
| 388 |
+
disabled={!selectedFile || isConverting}
|
| 389 |
+
onClick={handleConvert}
|
| 390 |
+
id="hero-action-convert-btn"
|
| 391 |
+
className={`w-full py-4 rounded-2xl font-semibold flex items-center justify-center space-x-2 border transition-all cursor-pointer ${
|
| 392 |
+
!selectedFile || isConverting
|
| 393 |
+
? "bg-slate-100 text-slate-400 border-slate-100 cursor-not-allowed"
|
| 394 |
+
: "bg-slate-900 border-slate-900 text-white shadow-md hover:bg-violet-600 hover:border-violet-600 active:scale-98"
|
| 395 |
+
}`}
|
| 396 |
+
>
|
| 397 |
+
<Play className="w-4 h-4 fill-current" />
|
| 398 |
+
<span>Convert Locally Now</span>
|
| 399 |
+
</button>
|
| 400 |
+
</div>
|
| 401 |
+
</div>
|
| 402 |
+
</div>
|
| 403 |
+
</div>
|
| 404 |
+
|
| 405 |
+
{/* Floating success toast notifier */}
|
| 406 |
+
<AnimatePresence>
|
| 407 |
+
{showNotification && (
|
| 408 |
+
<motion.div
|
| 409 |
+
initial={{ opacity: 0, y: 50 }}
|
| 410 |
+
animate={{ opacity: 1, y: 0 }}
|
| 411 |
+
exit={{ opacity: 0, y: 50 }}
|
| 412 |
+
className="fixed bottom-6 right-6 z-50 bg-slate-950 text-white py-3.5 px-5 rounded-2xl flex items-center space-x-3 shadow-2xl border border-white/10"
|
| 413 |
+
>
|
| 414 |
+
<div className="w-2 h-2 rounded-full bg-emerald-400 animate-ping" />
|
| 415 |
+
<span className="text-xs font-medium font-mono text-slate-200">
|
| 416 |
+
⚡ Local CUDA Core GPU optimization completed processing!
|
| 417 |
+
</span>
|
| 418 |
+
</motion.div>
|
| 419 |
+
)}
|
| 420 |
+
</AnimatePresence>
|
| 421 |
+
</section>
|
| 422 |
+
);
|
| 423 |
+
}
|
all-file-converter/src/components/Navbar.tsx
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useState, useEffect } from "react";
|
| 2 |
+
import { Menu, X, Download, ShieldCheck } from "lucide-react";
|
| 3 |
+
import { motion, AnimatePresence } from "motion/react";
|
| 4 |
+
import { Link, useLocation } from "react-router-dom";
|
| 5 |
+
|
| 6 |
+
interface NavbarProps {
|
| 7 |
+
downloadUrl: string;
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
export default function Navbar({ downloadUrl }: NavbarProps) {
|
| 11 |
+
const [isOpen, setIsOpen] = useState(false);
|
| 12 |
+
const [isScrolled, setIsScrolled] = useState(false);
|
| 13 |
+
const location = useLocation();
|
| 14 |
+
|
| 15 |
+
const navItems = [
|
| 16 |
+
{ name: "Home", path: "/" },
|
| 17 |
+
{ name: "Features Specs", path: "/features" },
|
| 18 |
+
{ name: "FAQ Hub", path: "/faq" },
|
| 19 |
+
{ name: "Support Us", path: "/support" },
|
| 20 |
+
{ name: "Contact Specialist", path: "/contact" },
|
| 21 |
+
];
|
| 22 |
+
|
| 23 |
+
useEffect(() => {
|
| 24 |
+
const handleScroll = () => {
|
| 25 |
+
setIsScrolled(window.scrollY > 20);
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
window.addEventListener("scroll", handleScroll);
|
| 29 |
+
return () => window.removeEventListener("scroll", handleScroll);
|
| 30 |
+
}, []);
|
| 31 |
+
|
| 32 |
+
// Close mobile navigation drawer whenever path shifts
|
| 33 |
+
useEffect(() => {
|
| 34 |
+
setIsOpen(false);
|
| 35 |
+
window.scrollTo(0, 0);
|
| 36 |
+
}, [location.pathname]);
|
| 37 |
+
|
| 38 |
+
const activePath = location.pathname;
|
| 39 |
+
|
| 40 |
+
return (
|
| 41 |
+
<>
|
| 42 |
+
<nav
|
| 43 |
+
id="main-nav"
|
| 44 |
+
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
|
| 45 |
+
isScrolled
|
| 46 |
+
? "py-3 px-4 md:px-8 bg-white/80 backdrop-blur-md shadow-sm border-b border-slate-100"
|
| 47 |
+
: "py-5 px-4 md:px-8 bg-transparent"
|
| 48 |
+
}`}
|
| 49 |
+
>
|
| 50 |
+
<div className="max-w-7xl mx-auto flex items-center justify-between">
|
| 51 |
+
{/* Logo */}
|
| 52 |
+
<Link
|
| 53 |
+
to="/"
|
| 54 |
+
className="flex items-center space-x-2 group focus:outline-none cursor-pointer"
|
| 55 |
+
id="nav-logo-btn"
|
| 56 |
+
>
|
| 57 |
+
<div className="w-10 h-10 rounded-xl bg-gradient-to-tr from-violet-600 to-indigo-600 flex items-center justify-center shadow-md shadow-violet-500/20 group-hover:scale-105 transition-transform duration-300">
|
| 58 |
+
<ShieldCheck className="w-5 h-5 text-white" />
|
| 59 |
+
</div>
|
| 60 |
+
<div className="text-left">
|
| 61 |
+
<span className="block font-display font-medium text-lg text-slate-900 tracking-tight">
|
| 62 |
+
Lumina Convert
|
| 63 |
+
</span>
|
| 64 |
+
<span className="block text-[10px] font-mono tracking-wider text-violet-600 -mt-1 font-semibold uppercase">
|
| 65 |
+
All File Converter
|
| 66 |
+
</span>
|
| 67 |
+
</div>
|
| 68 |
+
</Link>
|
| 69 |
+
|
| 70 |
+
{/* Desktop Nav Items */}
|
| 71 |
+
<div className="hidden md:flex items-center space-x-8">
|
| 72 |
+
<div className="flex items-center space-x-6">
|
| 73 |
+
{navItems.map((item) => (
|
| 74 |
+
<Link
|
| 75 |
+
key={item.path}
|
| 76 |
+
to={item.path}
|
| 77 |
+
id={`nav-item-${item.name.toLowerCase().replace(/\s+/g, "-")}`}
|
| 78 |
+
className={`text-sm font-semibold tracking-wide transition-colors cursor-pointer relative py-1.5 focus:outline-none ${
|
| 79 |
+
activePath === item.path
|
| 80 |
+
? "text-violet-600 font-bold"
|
| 81 |
+
: "text-slate-600 hover:text-slate-900"
|
| 82 |
+
}`}
|
| 83 |
+
>
|
| 84 |
+
<span>{item.name}</span>
|
| 85 |
+
{activePath === item.path && (
|
| 86 |
+
<motion.div
|
| 87 |
+
layoutId="activeIndicator"
|
| 88 |
+
className="absolute bottom-0 left-0 right-0 h-0.5 bg-violet-600 rounded-full"
|
| 89 |
+
transition={{ type: "spring", stiffness: 380, damping: 30 }}
|
| 90 |
+
/>
|
| 91 |
+
)}
|
| 92 |
+
</Link>
|
| 93 |
+
))}
|
| 94 |
+
</div>
|
| 95 |
+
|
| 96 |
+
{/* Premium CTA Button */}
|
| 97 |
+
<a
|
| 98 |
+
href={downloadUrl}
|
| 99 |
+
download
|
| 100 |
+
id="navbar-download-btn"
|
| 101 |
+
className="inline-flex items-center justify-center space-x-2 px-6 py-2.5 rounded-full bg-slate-900 text-white text-sm font-semibold shadow-md shadow-slate-900/10 hover:bg-violet-600 hover:shadow-violet-500/20 active:scale-95 transition-all duration-300 cursor-pointer"
|
| 102 |
+
>
|
| 103 |
+
<Download className="w-4 h-4" />
|
| 104 |
+
<span>Download Free</span>
|
| 105 |
+
</a>
|
| 106 |
+
</div>
|
| 107 |
+
|
| 108 |
+
{/* Mobile Menu Button */}
|
| 109 |
+
<div className="flex md:hidden items-center space-x-2">
|
| 110 |
+
<a
|
| 111 |
+
href={downloadUrl}
|
| 112 |
+
download
|
| 113 |
+
id="navbar-download-mobile-btn"
|
| 114 |
+
className="p-2.5 rounded-full bg-slate-900 text-white shadow-sm hover:bg-violet-600 transition-colors cursor-pointer"
|
| 115 |
+
title="Download Converter"
|
| 116 |
+
>
|
| 117 |
+
<Download className="w-4 h-4" />
|
| 118 |
+
</a>
|
| 119 |
+
<button
|
| 120 |
+
onClick={() => setIsOpen(!isOpen)}
|
| 121 |
+
id="mobile-menu-toggle-btn"
|
| 122 |
+
className="p-2 text-slate-700 hover:text-slate-900 focus:outline-none cursor-pointer"
|
| 123 |
+
aria-label="Toggle navigation menu"
|
| 124 |
+
>
|
| 125 |
+
{isOpen ? <X className="w-6 h-6" /> : <Menu className="w-6 h-6" />}
|
| 126 |
+
</button>
|
| 127 |
+
</div>
|
| 128 |
+
</div>
|
| 129 |
+
</nav>
|
| 130 |
+
|
| 131 |
+
{/* Mobile Drawer Overlay */}
|
| 132 |
+
<AnimatePresence>
|
| 133 |
+
{isOpen && (
|
| 134 |
+
<>
|
| 135 |
+
{/* Backdrop */}
|
| 136 |
+
<motion.div
|
| 137 |
+
initial={{ opacity: 0 }}
|
| 138 |
+
animate={{ opacity: 1 }}
|
| 139 |
+
exit={{ opacity: 0 }}
|
| 140 |
+
onClick={() => setIsOpen(false)}
|
| 141 |
+
className="fixed inset-0 bg-slate-900/20 backdrop-blur-sm z-40 md:hidden"
|
| 142 |
+
/>
|
| 143 |
+
|
| 144 |
+
{/* Sidebar drawer */}
|
| 145 |
+
<motion.div
|
| 146 |
+
initial={{ x: "100%" }}
|
| 147 |
+
animate={{ x: 0 }}
|
| 148 |
+
exit={{ x: "100%" }}
|
| 149 |
+
transition={{ type: "spring", damping: 25, stiffness: 200 }}
|
| 150 |
+
className="fixed right-0 top-0 bottom-0 w-72 bg-white z-50 p-6 shadow-2xl flex flex-col justify-between border-l border-slate-100 md:hidden"
|
| 151 |
+
>
|
| 152 |
+
<div>
|
| 153 |
+
<div className="flex items-center justify-between mb-8">
|
| 154 |
+
<div className="flex items-center space-x-2">
|
| 155 |
+
<div className="w-8 h-8 rounded-lg bg-gradient-to-tr from-violet-600 to-indigo-600 flex items-center justify-center shadow-md">
|
| 156 |
+
<ShieldCheck className="w-4 h-4 text-white" />
|
| 157 |
+
</div>
|
| 158 |
+
<span className="font-display font-semibold text-slate-900">Lumina Convert</span>
|
| 159 |
+
</div>
|
| 160 |
+
<button
|
| 161 |
+
onClick={() => setIsOpen(false)}
|
| 162 |
+
id="mobile-drawer-close-btn"
|
| 163 |
+
className="p-1 rounded-full hover:bg-slate-100 text-slate-500 cursor-pointer"
|
| 164 |
+
>
|
| 165 |
+
<X className="w-5 h-5" />
|
| 166 |
+
</button>
|
| 167 |
+
</div>
|
| 168 |
+
|
| 169 |
+
<div className="flex flex-col space-y-2">
|
| 170 |
+
{navItems.map((item) => (
|
| 171 |
+
<Link
|
| 172 |
+
key={item.path}
|
| 173 |
+
to={item.path}
|
| 174 |
+
id={`mobile-nav-item-${item.name.toLowerCase().replace(/\s+/g, "-")}`}
|
| 175 |
+
className={`text-left py-3 px-4 rounded-xl text-sm font-semibold tracking-wide transition-colors cursor-pointer flex justify-between items-center ${
|
| 176 |
+
activePath === item.path
|
| 177 |
+
? "bg-violet-50 text-violet-600 font-bold"
|
| 178 |
+
: "text-slate-600 hover:bg-slate-50"
|
| 179 |
+
}`}
|
| 180 |
+
>
|
| 181 |
+
<span>{item.name}</span>
|
| 182 |
+
{activePath === item.path && (
|
| 183 |
+
<div className="w-1.5 h-1.5 rounded-full bg-violet-600" />
|
| 184 |
+
)}
|
| 185 |
+
</Link>
|
| 186 |
+
))}
|
| 187 |
+
</div>
|
| 188 |
+
</div>
|
| 189 |
+
|
| 190 |
+
<div className="space-y-4">
|
| 191 |
+
<div className="p-4 rounded-2xl bg-slate-50 border border-slate-100">
|
| 192 |
+
<h4 className="text-xs font-mono font-bold uppercase tracking-wider text-slate-500 mb-1">
|
| 193 |
+
v1.4.2 Standalone
|
| 194 |
+
</h4>
|
| 195 |
+
<p className="text-[11px] text-slate-600 mb-3">Offline GPU acceleration included.</p>
|
| 196 |
+
<a
|
| 197 |
+
href={downloadUrl}
|
| 198 |
+
download
|
| 199 |
+
id="mobile-drawer-download-cta"
|
| 200 |
+
className="w-full inline-flex items-center justify-center space-x-2 py-3 rounded-xl bg-violet-600 text-white font-medium text-xs shadow-md hover:bg-violet-700 active:scale-95 transition-all cursor-pointer"
|
| 201 |
+
>
|
| 202 |
+
<Download className="w-4 h-4" />
|
| 203 |
+
<span>Download Installer</span>
|
| 204 |
+
</a>
|
| 205 |
+
</div>
|
| 206 |
+
</div>
|
| 207 |
+
</motion.div>
|
| 208 |
+
</>
|
| 209 |
+
)}
|
| 210 |
+
</AnimatePresence>
|
| 211 |
+
</>
|
| 212 |
+
);
|
| 213 |
+
}
|
all-file-converter/src/components/Stats.tsx
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { CheckCircle2, Users, FileCode, Zap } from "lucide-react";
|
| 2 |
+
import { motion } from "motion/react";
|
| 3 |
+
|
| 4 |
+
export default function Stats() {
|
| 5 |
+
const statsList = [
|
| 6 |
+
{
|
| 7 |
+
id: "stat-formats",
|
| 8 |
+
marker: "200+",
|
| 9 |
+
label: "Supported Formats",
|
| 10 |
+
subText: "PDF, Image, Video, Audio, Archiving, Docs",
|
| 11 |
+
icon: <FileCode className="w-5 h-5 text-violet-600" />,
|
| 12 |
+
color: "from-violet-500/10 to-indigo-500/10",
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
id: "stat-users",
|
| 16 |
+
marker: "50,000+",
|
| 17 |
+
label: "Active Installs",
|
| 18 |
+
subText: "Leading offline desktop choice worldwide",
|
| 19 |
+
icon: <Users className="w-5 h-5 text-indigo-600" />,
|
| 20 |
+
color: "from-indigo-500/10 to-sky-500/10",
|
| 21 |
+
},
|
| 22 |
+
{
|
| 23 |
+
id: "stat-rate",
|
| 24 |
+
marker: "99.9%",
|
| 25 |
+
label: "Success Processing",
|
| 26 |
+
subText: "Advanced local encoding checks",
|
| 27 |
+
icon: <CheckCircle2 className="w-5 h-5 text-emerald-600" />,
|
| 28 |
+
color: "from-emerald-500/10 to-teal-500/10",
|
| 29 |
+
},
|
| 30 |
+
{
|
| 31 |
+
id: "stat-gpu",
|
| 32 |
+
marker: "0ms Cloud Delay",
|
| 33 |
+
label: "GPU Accelerated",
|
| 34 |
+
subText: "100% on-device AI upscaling and codecs",
|
| 35 |
+
icon: <Zap className="w-5 h-5 text-fuchsia-600" />,
|
| 36 |
+
color: "from-fuchsia-100 to-pink-100",
|
| 37 |
+
},
|
| 38 |
+
];
|
| 39 |
+
|
| 40 |
+
const containerVariants = {
|
| 41 |
+
hidden: { opacity: 0 },
|
| 42 |
+
visible: {
|
| 43 |
+
opacity: 1,
|
| 44 |
+
transition: {
|
| 45 |
+
staggerChildren: 0.1,
|
| 46 |
+
},
|
| 47 |
+
},
|
| 48 |
+
};
|
| 49 |
+
|
| 50 |
+
const itemVariants = {
|
| 51 |
+
hidden: { opacity: 0, y: 20 },
|
| 52 |
+
visible: { opacity: 1, y: 0, transition: { type: "spring", stiffness: 100 } },
|
| 53 |
+
};
|
| 54 |
+
|
| 55 |
+
return (
|
| 56 |
+
<section className="py-16 bg-white border-y border-slate-100">
|
| 57 |
+
<div className="max-w-7xl mx-auto px-4 md:px-8">
|
| 58 |
+
<motion.div
|
| 59 |
+
variants={containerVariants}
|
| 60 |
+
initial="hidden"
|
| 61 |
+
whileInView="visible"
|
| 62 |
+
viewport={{ once: true, margin: "-100px" }}
|
| 63 |
+
className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6"
|
| 64 |
+
id="stats-container"
|
| 65 |
+
>
|
| 66 |
+
{statsList.map((stat) => (
|
| 67 |
+
<motion.div
|
| 68 |
+
key={stat.id}
|
| 69 |
+
variants={itemVariants}
|
| 70 |
+
whileHover={{ y: -5, shadow: "0 10px 30px -15px rgba(0,0,0,0.06)" }}
|
| 71 |
+
className="p-6 rounded-3xl bg-slate-50 border border-slate-100/60 text-left transition-all relative overflow-hidden group"
|
| 72 |
+
id={stat.id}
|
| 73 |
+
>
|
| 74 |
+
{/* Decorative side shape */}
|
| 75 |
+
<div className="absolute top-0 right-0 w-32 h-32 bg-slate-100/40 rounded-full blur-2xl group-hover:scale-125 transition-transform duration-500 pointer-events-none" />
|
| 76 |
+
|
| 77 |
+
<div className="flex items-center space-x-3 mb-4">
|
| 78 |
+
<div className={`p-3 rounded-2xl bg-white shadow-sm flex items-center justify-center`}>
|
| 79 |
+
{stat.icon}
|
| 80 |
+
</div>
|
| 81 |
+
<div className="font-display font-bold text-2xl md:text-3xl text-slate-900 tracking-tight">
|
| 82 |
+
{stat.marker}
|
| 83 |
+
</div>
|
| 84 |
+
</div>
|
| 85 |
+
|
| 86 |
+
<div>
|
| 87 |
+
<h4 className="text-slate-800 text-sm font-semibold tracking-wide mb-1">
|
| 88 |
+
{stat.label}
|
| 89 |
+
</h4>
|
| 90 |
+
<p className="text-xs text-slate-500 leading-relaxed font-light">
|
| 91 |
+
{stat.subText}
|
| 92 |
+
</p>
|
| 93 |
+
</div>
|
| 94 |
+
</motion.div>
|
| 95 |
+
))}
|
| 96 |
+
</motion.div>
|
| 97 |
+
</div>
|
| 98 |
+
</section>
|
| 99 |
+
);
|
| 100 |
+
}
|
all-file-converter/src/components/SupportBanner.tsx
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Coffee, ShoppingBag, AlertCircle, Heart } from "lucide-react";
|
| 2 |
+
|
| 3 |
+
export default function SupportBanner() {
|
| 4 |
+
return (
|
| 5 |
+
<section id="support" className="py-16 bg-white border-t border-b border-slate-100/80">
|
| 6 |
+
<div className="max-w-4xl mx-auto px-4 md:px-8">
|
| 7 |
+
<div className="p-8 rounded-[32px] bg-gradient-to-br from-[#FAF9FE] to-white border border-violet-100/50 shadow-xl shadow-slate-100/40 relative overflow-hidden">
|
| 8 |
+
{/* Subtle decoration */}
|
| 9 |
+
<div className="absolute -top-12 -right-12 w-48 h-48 bg-amber-500/5 rounded-full blur-2xl pointer-events-none" />
|
| 10 |
+
<div className="absolute -bottom-12 -left-12 w-48 h-48 bg-violet-500/5 rounded-full blur-2xl pointer-events-none" />
|
| 11 |
+
|
| 12 |
+
{/* Heading */}
|
| 13 |
+
<div className="flex flex-col items-center text-center max-w-xl mx-auto mb-8">
|
| 14 |
+
<div className="w-10 h-10 rounded-2xl bg-amber-50/80 text-amber-600 border border-amber-100 flex items-center justify-center mb-4">
|
| 15 |
+
<Heart className="w-5 h-5 fill-current text-rose-500 animate-pulse" />
|
| 16 |
+
</div>
|
| 17 |
+
<h3 className="font-display font-medium text-xl md:text-2xl text-slate-900 tracking-tight">
|
| 18 |
+
Support Our Offline Engine Development
|
| 19 |
+
</h3>
|
| 20 |
+
<p className="text-slate-500 text-xs md:text-sm font-light mt-2">
|
| 21 |
+
We work tirelessly to keep Lumina Convert open, GDPR-compliant, and 100% free of web tracking servers. Your kind support directly finances our local codec development!
|
| 22 |
+
</p>
|
| 23 |
+
</div>
|
| 24 |
+
|
| 25 |
+
{/* Two Support CTA Pillars */}
|
| 26 |
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 max-w-2xl mx-auto mb-6" id="support-cta-grid">
|
| 27 |
+
{/* Buy Me A Coffee Column */}
|
| 28 |
+
<a
|
| 29 |
+
href="https://www.buymeacoffee.com/bahaduralimunnabhai"
|
| 30 |
+
target="_blank"
|
| 31 |
+
rel="noopener noreferrer"
|
| 32 |
+
id="support-buymeacoffee-link"
|
| 33 |
+
className="group p-5 rounded-2xl bg-[#FFDD00]/10 border border-[#FFDD00]/30 hover:bg-[#FFDD00]/20 transition-all duration-300 flex items-center space-x-4 text-left cursor-pointer"
|
| 34 |
+
>
|
| 35 |
+
<div className="w-12 h-12 rounded-xl bg-[#FFDD00] flex items-center justify-center shadow-sm text-yellow-950">
|
| 36 |
+
<Coffee className="w-6 h-6 stroke-[2]" />
|
| 37 |
+
</div>
|
| 38 |
+
<div>
|
| 39 |
+
<h4 className="font-semibold text-sm text-slate-800 group-hover:text-amber-900 transition-colors">
|
| 40 |
+
Buy Me a Coffee
|
| 41 |
+
</h4>
|
| 42 |
+
<p className="text-[11px] text-slate-500 font-light mt-0.5">
|
| 43 |
+
Fuel our coding sessions with a fresh warm brew.
|
| 44 |
+
</p>
|
| 45 |
+
</div>
|
| 46 |
+
</a>
|
| 47 |
+
|
| 48 |
+
{/* Shop on Amazon Column */}
|
| 49 |
+
<a
|
| 50 |
+
href="https://amazon.com?tag=bahaduralimunnabhai-20" // Standard fallback tag model
|
| 51 |
+
target="_blank"
|
| 52 |
+
rel="noopener noreferrer"
|
| 53 |
+
id="support-amazon-affiliate-link"
|
| 54 |
+
className="group p-5 rounded-2xl bg-[#FF9900]/10 border border-[#FF9900]/30 hover:bg-[#FF9900]/20 transition-all duration-300 flex items-center space-x-4 text-left cursor-pointer"
|
| 55 |
+
>
|
| 56 |
+
<div className="w-12 h-12 rounded-xl bg-[#FF9900] flex items-center justify-center shadow-sm text-slate-950">
|
| 57 |
+
<ShoppingBag className="w-5 h-5 text-white stroke-[2.5]" />
|
| 58 |
+
</div>
|
| 59 |
+
<div>
|
| 60 |
+
<h4 className="font-semibold text-sm text-slate-800 group-hover:text-amber-900 transition-colors">
|
| 61 |
+
Shop on Amazon
|
| 62 |
+
</h4>
|
| 63 |
+
<p className="text-[11px] text-slate-500 font-light mt-0.5">
|
| 64 |
+
Update your local storage hardware through our link.
|
| 65 |
+
</p>
|
| 66 |
+
</div>
|
| 67 |
+
</a>
|
| 68 |
+
</div>
|
| 69 |
+
|
| 70 |
+
{/* Amazon Affiliate Legal Disclosure */}
|
| 71 |
+
<div className="flex items-start max-w-xl mx-auto text-left bg-slate-50/60 border border-slate-100 p-4 rounded-xl">
|
| 72 |
+
<AlertCircle className="w-4 h-4 text-slate-400 mr-2.5 mt-0.5 flex-shrink-0" />
|
| 73 |
+
<p className="text-[11px] text-slate-450 leading-relaxed font-mono">
|
| 74 |
+
<span className="font-semibold text-slate-600">Amazon Affiliate Disclosure:</span> As an Amazon Associate, we earn from qualifying purchases. Using these tracking links helps fund Lumina Convert’s developer updates without posing any extra cost to your purchases.
|
| 75 |
+
</p>
|
| 76 |
+
</div>
|
| 77 |
+
</div>
|
| 78 |
+
</div>
|
| 79 |
+
</section>
|
| 80 |
+
);
|
| 81 |
+
}
|
all-file-converter/src/components/Testimonials.tsx
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Star, Quote } from "lucide-react";
|
| 2 |
+
import { motion } from "motion/react";
|
| 3 |
+
|
| 4 |
+
export default function Testimonials() {
|
| 5 |
+
const reviews = [
|
| 6 |
+
{
|
| 7 |
+
id: "review-1",
|
| 8 |
+
name: "Liam Carter",
|
| 9 |
+
role: "Product Architect, Apex Design Group",
|
| 10 |
+
feedback: "Lumina Convert has been a lifesaver for our design team. We work with massive TIFF imagery & raw assets which used to stretch our client non-disclosure boundaries on web converters. Having a 100% offline local utility is incredibly powerful.",
|
| 11 |
+
rating: 5,
|
| 12 |
+
initials: "LC",
|
| 13 |
+
gradient: "from-violet-500 to-indigo-500",
|
| 14 |
+
},
|
| 15 |
+
{
|
| 16 |
+
id: "review-2",
|
| 17 |
+
name: "Elena Rostova",
|
| 18 |
+
role: "Operations Director, LegalTrust Systems",
|
| 19 |
+
feedback: "Under strict regulatory guidelines, our corporate contracts and depositions cannot traverse cloud platforms. Lumina solves our compliance headaches beautifully. The 100% offline GPU processing is unbelievably rapid.",
|
| 20 |
+
rating: 5,
|
| 21 |
+
initials: "ER",
|
| 22 |
+
gradient: "from-indigo-500 to-sky-500",
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
id: "review-3",
|
| 26 |
+
name: "James Thornton",
|
| 27 |
+
role: "Senior Frontend Engineer, SynthTech",
|
| 28 |
+
feedback: "I drop huge directory bundles of thousands of audio tracks and SVGs. Web converters crash or crawl. Lumina's standalone batch converting remains responsive, and the fact that it is 100% free with absolutely no hidden upgrades is phenomenal.",
|
| 29 |
+
rating: 5,
|
| 30 |
+
initials: "JT",
|
| 31 |
+
gradient: "from-fuchsia-500 to-pink-500",
|
| 32 |
+
},
|
| 33 |
+
];
|
| 34 |
+
|
| 35 |
+
return (
|
| 36 |
+
<section className="py-24 bg-gradient-to-b from-[#FAF9FE] to-white relative overflow-hidden">
|
| 37 |
+
<div className="absolute top-1/4 right-0 w-96 h-96 bg-indigo-50 rounded-full blur-3xl pointer-events-none" />
|
| 38 |
+
|
| 39 |
+
<div className="max-w-7xl mx-auto px-4 md:px-8 relative z-10">
|
| 40 |
+
{/* Header */}
|
| 41 |
+
<div className="text-center max-w-2xl mx-auto mb-16">
|
| 42 |
+
<span className="text-xs font-bold font-mono tracking-wider text-violet-600 uppercase bg-violet-50 px-3.5 py-1.5 rounded-full">
|
| 43 |
+
User Testimonials
|
| 44 |
+
</span>
|
| 45 |
+
<h2 className="font-display font-bold text-3xl sm:text-4xl text-slate-900 tracking-tight mt-4 mb-4">
|
| 46 |
+
Trusted by creators &{" "}
|
| 47 |
+
<span className="bg-gradient-to-r from-violet-600 to-indigo-600 bg-clip-text text-transparent">
|
| 48 |
+
professionals
|
| 49 |
+
</span>
|
| 50 |
+
</h2>
|
| 51 |
+
<p className="text-slate-500 text-sm md:text-base font-light">
|
| 52 |
+
Read how small business managers, designers, and compliance teams protect their data with our local converters.
|
| 53 |
+
</p>
|
| 54 |
+
</div>
|
| 55 |
+
|
| 56 |
+
{/* Reviews grid */}
|
| 57 |
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8" id="testimonials-reviews-grid">
|
| 58 |
+
{reviews.map((review, i) => (
|
| 59 |
+
<motion.div
|
| 60 |
+
key={review.id}
|
| 61 |
+
initial={{ opacity: 0, y: 15 }}
|
| 62 |
+
whileInView={{ opacity: 1, y: 0 }}
|
| 63 |
+
viewport={{ once: true }}
|
| 64 |
+
transition={{ delay: i * 0.1, duration: 0.4 }}
|
| 65 |
+
className="p-8 rounded-[24px] bg-white border border-slate-100/80 shadow-md shadow-slate-100/10 hover:shadow-xl hover:shadow-slate-200/20 text-left flex flex-col justify-between relative transition-all"
|
| 66 |
+
id={review.id}
|
| 67 |
+
>
|
| 68 |
+
<Quote className="absolute right-6 top-6 w-12 h-12 text-slate-55/70 rotate-180 opacity-10 pointer-events-none" />
|
| 69 |
+
|
| 70 |
+
<div>
|
| 71 |
+
{/* Stars bar */}
|
| 72 |
+
<div className="flex space-x-1 mb-5">
|
| 73 |
+
{[...Array(review.rating)].map((_, index) => (
|
| 74 |
+
<Star key={index} className="w-4 h-4 fill-amber-400 text-amber-400" />
|
| 75 |
+
))}
|
| 76 |
+
</div>
|
| 77 |
+
|
| 78 |
+
<p className="text-slate-600 text-sm italic font-light leading-relaxed mb-6">
|
| 79 |
+
“{review.feedback}”
|
| 80 |
+
</p>
|
| 81 |
+
</div>
|
| 82 |
+
|
| 83 |
+
<div className="flex items-center space-x-3.5 border-t border-slate-50/50 pt-5">
|
| 84 |
+
<div className={`w-10 h-10 rounded-full bg-gradient-to-tr ${review.gradient} flex items-center justify-center text-white text-xs font-bold font-mono shadow-sm`}>
|
| 85 |
+
{review.initials}
|
| 86 |
+
</div>
|
| 87 |
+
<div>
|
| 88 |
+
<h4 className="text-sm font-semibold text-slate-900">{review.name}</h4>
|
| 89 |
+
<p className="text-xs text-slate-500 font-medium">{review.role}</p>
|
| 90 |
+
</div>
|
| 91 |
+
</div>
|
| 92 |
+
</motion.div>
|
| 93 |
+
))}
|
| 94 |
+
</div>
|
| 95 |
+
</div>
|
| 96 |
+
</section>
|
| 97 |
+
);
|
| 98 |
+
}
|
all-file-converter/src/index.css
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap');
|
| 2 |
+
@import "tailwindcss";
|
| 3 |
+
|
| 4 |
+
@theme {
|
| 5 |
+
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
| 6 |
+
--font-display: "Space Grotesk", sans-serif;
|
| 7 |
+
--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, monospace;
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
body {
|
| 11 |
+
background-color: #fbfbfd;
|
| 12 |
+
color: #1c1c1e;
|
| 13 |
+
font-family: var(--font-sans);
|
| 14 |
+
}
|
all-file-converter/src/main.tsx
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import {StrictMode} from 'react';
|
| 2 |
+
import {createRoot} from 'react-dom/client';
|
| 3 |
+
import App from './App.tsx';
|
| 4 |
+
import './index.css';
|
| 5 |
+
|
| 6 |
+
createRoot(document.getElementById('root')!).render(
|
| 7 |
+
<StrictMode>
|
| 8 |
+
<App />
|
| 9 |
+
</StrictMode>,
|
| 10 |
+
);
|
all-file-converter/src/pages/Contact.tsx
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useState, ChangeEvent, FormEvent, useEffect } from "react";
|
| 2 |
+
import { Mail, MessageSquare, Phone, Send, CheckCircle, AlertTriangle, ShieldCheck } from "lucide-react";
|
| 3 |
+
import { updateSEO } from "../utils/seo";
|
| 4 |
+
|
| 5 |
+
export default function Contact() {
|
| 6 |
+
const [formData, setFormData] = useState({
|
| 7 |
+
name: "",
|
| 8 |
+
email: "",
|
| 9 |
+
subject: "",
|
| 10 |
+
message: "",
|
| 11 |
+
});
|
| 12 |
+
|
| 13 |
+
const [formStatus, setFormStatus] = useState<"idle" | "submitting" | "success" | "error">("idle");
|
| 14 |
+
const [errorMessage, setErrorMessage] = useState("");
|
| 15 |
+
|
| 16 |
+
useEffect(() => {
|
| 17 |
+
updateSEO({
|
| 18 |
+
title: "Contact Specialist Support | Lumina Convert Desktop Tool",
|
| 19 |
+
description: "Get in touch with Lumina Convert development team. Submit support tickets, request corporate volume configurations, or custom watcher codecs.",
|
| 20 |
+
keywords: "Lumina convert support ticket, contact developer, offline converter help, custom business converter, Formspree gateway",
|
| 21 |
+
});
|
| 22 |
+
}, []);
|
| 23 |
+
|
| 24 |
+
const handleChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
| 25 |
+
setFormData({
|
| 26 |
+
...formData,
|
| 27 |
+
[e.target.name]: e.target.value,
|
| 28 |
+
});
|
| 29 |
+
};
|
| 30 |
+
|
| 31 |
+
const handleSubmit = async (e: FormEvent) => {
|
| 32 |
+
e.preventDefault();
|
| 33 |
+
if (!formData.name || !formData.email || !formData.message) {
|
| 34 |
+
setFormStatus("error");
|
| 35 |
+
setErrorMessage("Please complete all required fields.");
|
| 36 |
+
return;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
setFormStatus("submitting");
|
| 40 |
+
|
| 41 |
+
try {
|
| 42 |
+
const response = await fetch("https://formspree.io/f/mojrrdov", {
|
| 43 |
+
method: "POST",
|
| 44 |
+
headers: {
|
| 45 |
+
"Content-Type": "application/json",
|
| 46 |
+
Accept: "application/json",
|
| 47 |
+
},
|
| 48 |
+
body: JSON.stringify(formData),
|
| 49 |
+
});
|
| 50 |
+
|
| 51 |
+
if (response.ok) {
|
| 52 |
+
setFormStatus("success");
|
| 53 |
+
setFormData({ name: "", email: "", subject: "", message: "" });
|
| 54 |
+
} else {
|
| 55 |
+
setFormStatus("error");
|
| 56 |
+
setErrorMessage("An error occurred on the server. Please check your network and try again.");
|
| 57 |
+
}
|
| 58 |
+
} catch (err) {
|
| 59 |
+
setFormStatus("error");
|
| 60 |
+
setErrorMessage("Could not submit the form. Please check your connection or contact our support team.");
|
| 61 |
+
}
|
| 62 |
+
};
|
| 63 |
+
|
| 64 |
+
return (
|
| 65 |
+
<section className="py-12 bg-gradient-to-b from-[#FBFBFD] to-white min-h-screen">
|
| 66 |
+
<div className="max-w-7xl mx-auto px-4 md:px-8 mt-12 pb-24 text-left">
|
| 67 |
+
{/* Header */}
|
| 68 |
+
<div className="text-center max-w-2xl mx-auto mb-16">
|
| 69 |
+
<span className="text-xs font-bold font-mono tracking-wider text-violet-600 uppercase bg-violet-50 px-3.5 py-1.5 rounded-full">
|
| 70 |
+
Developer Helpline
|
| 71 |
+
</span>
|
| 72 |
+
<h1 className="font-display font-bold text-3xl sm:text-4xl lg:text-5xl text-slate-900 tracking-tight mt-4 mb-4">
|
| 73 |
+
Custom Setup Assist is{" "}
|
| 74 |
+
<span className="bg-gradient-to-r from-violet-600 to-indigo-600 bg-clip-text text-transparent font-extrabold">
|
| 75 |
+
One Click Away
|
| 76 |
+
</span>
|
| 77 |
+
</h1>
|
| 78 |
+
<p className="text-slate-500 text-sm md:text-base font-light">
|
| 79 |
+
Need support with custom automation scripts, command line configurations, or folder watcher integrations? Message our core team immediately.
|
| 80 |
+
</p>
|
| 81 |
+
</div>
|
| 82 |
+
|
| 83 |
+
{/* Column breakdown */}
|
| 84 |
+
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12 items-start" id="contact-panel-wrapper">
|
| 85 |
+
{/* Left Column - Contact Details */}
|
| 86 |
+
<div className="lg:col-span-5 space-y-6 text-left">
|
| 87 |
+
<h3 className="font-display font-semibold text-2xl text-slate-900 tracking-tight mb-4">
|
| 88 |
+
Direct Channels
|
| 89 |
+
</h3>
|
| 90 |
+
<p className="text-slate-500 text-sm font-light leading-relaxed mb-6">
|
| 91 |
+
Our core support team answers personal emails and WhatsApp inquiries directly. Get prompt assistance with your offline integration.
|
| 92 |
+
</p>
|
| 93 |
+
|
| 94 |
+
<div className="space-y-4">
|
| 95 |
+
{/* WhatsApp Support */}
|
| 96 |
+
<a
|
| 97 |
+
href="https://wa.me/923034572298"
|
| 98 |
+
target="_blank"
|
| 99 |
+
rel="noopener noreferrer"
|
| 100 |
+
id="contact-whatsapp-direct-link"
|
| 101 |
+
className="flex items-start p-4 hover:bg-slate-50 border border-slate-100 rounded-2xl bg-white transition shadow-sm"
|
| 102 |
+
>
|
| 103 |
+
<div className="w-10 h-10 rounded-xl bg-emerald-50 text-emerald-600 flex items-center justify-center mr-4 flex-shrink-0 shadow-sm">
|
| 104 |
+
<Phone className="w-5 h-5" />
|
| 105 |
+
</div>
|
| 106 |
+
<div>
|
| 107 |
+
<h4 className="text-sm font-semibold text-slate-800">WhatsApp Instant Chat</h4>
|
| 108 |
+
<p className="text-xs text-slate-500 font-mono mt-0.5">+92 303 4572298</p>
|
| 109 |
+
<span className="inline-block text-[10px] font-bold text-emerald-600 font-mono mt-1 uppercase">
|
| 110 |
+
Answered in minutes
|
| 111 |
+
</span>
|
| 112 |
+
</div>
|
| 113 |
+
</a>
|
| 114 |
+
|
| 115 |
+
{/* Email Support */}
|
| 116 |
+
<a
|
| 117 |
+
href="mailto:bahaduralimunnabhai@gmail.com"
|
| 118 |
+
id="contact-email-direct-link"
|
| 119 |
+
className="flex items-start p-4 hover:bg-slate-50 border border-slate-100 rounded-2xl bg-white transition shadow-sm"
|
| 120 |
+
>
|
| 121 |
+
<div className="w-10 h-10 rounded-xl bg-violet-50 text-violet-600 flex items-center justify-center mr-4 flex-shrink-0 shadow-sm">
|
| 122 |
+
<Mail className="w-5 h-5" />
|
| 123 |
+
</div>
|
| 124 |
+
<div>
|
| 125 |
+
<h4 className="text-sm font-semibold text-slate-800">Secure Developer Mailbox</h4>
|
| 126 |
+
<p className="text-xs text-slate-500 font-mono mt-0.5">bahaduralimunnabhai@gmail.com</p>
|
| 127 |
+
<span className="inline-block text-[10px] font-bold text-violet-600 font-mono mt-1 uppercase">
|
| 128 |
+
Under 12hr Response SLA
|
| 129 |
+
</span>
|
| 130 |
+
</div>
|
| 131 |
+
</a>
|
| 132 |
+
|
| 133 |
+
{/* Secure statement */}
|
| 134 |
+
<div className="p-5 bg-indigo-50/50 border border-indigo-100/60 rounded-2xl">
|
| 135 |
+
<div className="flex items-center space-x-2.5 mb-2">
|
| 136 |
+
<ShieldCheck className="w-4 h-4 text-indigo-600" />
|
| 137 |
+
<span className="text-xs font-bold font-mono uppercase text-indigo-700 tracking-wide">Confidential Support Guaranteed</span>
|
| 138 |
+
</div>
|
| 139 |
+
<p className="text-slate-500 text-xs font-light leading-relaxed">
|
| 140 |
+
We treat all corporate queries, deployment designs, and logs, under strict privacy protection guidelines. Zero details are shared with advertisers.
|
| 141 |
+
</p>
|
| 142 |
+
</div>
|
| 143 |
+
</div>
|
| 144 |
+
</div>
|
| 145 |
+
|
| 146 |
+
{/* Right Column - Premium AJAX Formspree Card */}
|
| 147 |
+
<div className="lg:col-span-7 bg-white p-8 rounded-3xl border border-slate-100 shadow-xl shadow-slate-100/10">
|
| 148 |
+
<h3 className="font-display font-semibold text-xl text-slate-900 mb-6">Send a Support Ticket</h3>
|
| 149 |
+
<form onSubmit={handleSubmit} className="space-y-5" id="formspree-contact-form">
|
| 150 |
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-5">
|
| 151 |
+
{/* Name */}
|
| 152 |
+
<div className="text-left">
|
| 153 |
+
<label htmlFor="form-name" className="block text-xs font-semibold text-slate-500 font-mono uppercase tracking-wider mb-2">
|
| 154 |
+
Your Name <span className="text-rose-500">*</span>
|
| 155 |
+
</label>
|
| 156 |
+
<input
|
| 157 |
+
type="text"
|
| 158 |
+
id="form-name"
|
| 159 |
+
name="name"
|
| 160 |
+
required
|
| 161 |
+
value={formData.name}
|
| 162 |
+
onChange={handleChange}
|
| 163 |
+
placeholder="E.g., Liam Carter"
|
| 164 |
+
className="w-full px-4 py-3 rounded-xl border border-slate-200/80 bg-slate-50/20 text-slate-800 text-sm focus:outline-none focus:ring-1 focus:ring-violet-500 focus:border-violet-500 focus:bg-white transition"
|
| 165 |
+
/>
|
| 166 |
+
</div>
|
| 167 |
+
|
| 168 |
+
{/* Email */}
|
| 169 |
+
<div className="text-left">
|
| 170 |
+
<label htmlFor="form-email" className="block text-xs font-semibold text-slate-500 font-mono uppercase tracking-wider mb-2">
|
| 171 |
+
Email Address <span className="text-rose-500">*</span>
|
| 172 |
+
</label>
|
| 173 |
+
<input
|
| 174 |
+
type="email"
|
| 175 |
+
id="form-email"
|
| 176 |
+
name="email"
|
| 177 |
+
required
|
| 178 |
+
value={formData.email}
|
| 179 |
+
onChange={handleChange}
|
| 180 |
+
placeholder="E.g., liam@corp.com"
|
| 181 |
+
className="w-full px-4 py-3 rounded-xl border border-slate-200/80 bg-slate-50/20 text-slate-800 text-sm focus:outline-none focus:ring-1 focus:ring-violet-500 focus:border-violet-500 focus:bg-white transition"
|
| 182 |
+
/>
|
| 183 |
+
</div>
|
| 184 |
+
</div>
|
| 185 |
+
|
| 186 |
+
{/* Subject */}
|
| 187 |
+
<div className="text-left">
|
| 188 |
+
<label htmlFor="form-subject" className="block text-xs font-semibold text-slate-500 font-mono uppercase tracking-wider mb-2">
|
| 189 |
+
Inquiry Subject
|
| 190 |
+
</label>
|
| 191 |
+
<input
|
| 192 |
+
type="text"
|
| 193 |
+
id="form-subject"
|
| 194 |
+
name="subject"
|
| 195 |
+
value={formData.subject}
|
| 196 |
+
onChange={handleChange}
|
| 197 |
+
placeholder="E.g., Format support setup or folder watchers"
|
| 198 |
+
className="w-full px-4 py-3 rounded-xl border border-slate-200/80 bg-slate-50/20 text-slate-800 text-sm focus:outline-none focus:ring-1 focus:ring-violet-500 focus:border-violet-500 focus:bg-white transition"
|
| 199 |
+
/>
|
| 200 |
+
</div>
|
| 201 |
+
|
| 202 |
+
{/* Message */}
|
| 203 |
+
<div className="text-left">
|
| 204 |
+
<label htmlFor="form-message" className="block text-xs font-semibold text-slate-500 font-mono uppercase tracking-wider mb-2">
|
| 205 |
+
Message Details <span className="text-rose-500">*</span>
|
| 206 |
+
</label>
|
| 207 |
+
<textarea
|
| 208 |
+
id="form-message"
|
| 209 |
+
name="message"
|
| 210 |
+
required
|
| 211 |
+
rows={4}
|
| 212 |
+
value={formData.message}
|
| 213 |
+
onChange={handleChange}
|
| 214 |
+
placeholder="How can we assist you with our free tool?"
|
| 215 |
+
className="w-full px-4 py-3 rounded-xl border border-slate-200/80 bg-slate-50/20 text-slate-800 text-sm focus:outline-none focus:ring-1 focus:ring-violet-500 focus:border-violet-500 focus:bg-white transition resize-none"
|
| 216 |
+
/>
|
| 217 |
+
</div>
|
| 218 |
+
|
| 219 |
+
{/* Status Notifications */}
|
| 220 |
+
{formStatus === "success" && (
|
| 221 |
+
<div className="p-4 rounded-xl bg-emerald-50 border border-emerald-100 flex items-start text-left text-emerald-800 space-x-2.5">
|
| 222 |
+
<CheckCircle className="w-5 h-5 text-emerald-600 flex-shrink-0 mt-0.5" />
|
| 223 |
+
<div>
|
| 224 |
+
<h5 className="text-xs font-bold font-mono tracking-wider uppercase">Message Transmitted!</h5>
|
| 225 |
+
<p className="text-xs text-slate-650 mt-0.5">Thank you. Your request is in queue. Our support specialists will contact you very soon.</p>
|
| 226 |
+
</div>
|
| 227 |
+
</div>
|
| 228 |
+
)}
|
| 229 |
+
|
| 230 |
+
{formStatus === "error" && (
|
| 231 |
+
<div className="p-4 rounded-xl bg-rose-50 border border-rose-100 flex items-start text-left text-rose-800 space-x-2.5">
|
| 232 |
+
<AlertTriangle className="w-5 h-5 text-rose-600 flex-shrink-0 mt-0.5" />
|
| 233 |
+
<div>
|
| 234 |
+
<h5 className="text-xs font-bold font-mono tracking-wider uppercase">Missing Parameters</h5>
|
| 235 |
+
<p className="text-xs text-slate-650 mt-0.5">{errorMessage}</p>
|
| 236 |
+
</div>
|
| 237 |
+
</div>
|
| 238 |
+
)}
|
| 239 |
+
|
| 240 |
+
{/* Submit button */}
|
| 241 |
+
<button
|
| 242 |
+
type="submit"
|
| 243 |
+
disabled={formStatus === "submitting"}
|
| 244 |
+
id="contact-form-submit-btn"
|
| 245 |
+
className={`w-full py-4 rounded-xl font-semibold flex items-center justify-center space-x-2 border transition-all cursor-pointer ${
|
| 246 |
+
formStatus === "submitting"
|
| 247 |
+
? "bg-stone-100 text-slate-400 border-stone-100 cursor-not-allowed"
|
| 248 |
+
: "bg-slate-900 border-slate-900 text-white hover:bg-violet-600 hover:border-violet-600 shadow-sm active:scale-98"
|
| 249 |
+
}`}
|
| 250 |
+
>
|
| 251 |
+
{formStatus === "submitting" ? (
|
| 252 |
+
<>
|
| 253 |
+
<span className="w-4 h-4 border-2 border-slate-400 border-t-slate-800 rounded-full animate-spin inline-block mr-2" />
|
| 254 |
+
<span>Engaging Formspree Gateway...</span>
|
| 255 |
+
</>
|
| 256 |
+
) : (
|
| 257 |
+
<>
|
| 258 |
+
<Send className="w-4 h-4" />
|
| 259 |
+
<span>Send Message Securely</span>
|
| 260 |
+
</>
|
| 261 |
+
)}
|
| 262 |
+
</button>
|
| 263 |
+
</form>
|
| 264 |
+
</div>
|
| 265 |
+
</div>
|
| 266 |
+
</div>
|
| 267 |
+
</section>
|
| 268 |
+
);
|
| 269 |
+
}
|
all-file-converter/src/pages/FAQ.tsx
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useEffect, useState } from "react";
|
| 2 |
+
import { updateSEO } from "../utils/seo";
|
| 3 |
+
import { HelpCircle, MessageSquare, Phone, Plus, Minus, Search, ShieldAlert, Laptop, Star } from "lucide-react";
|
| 4 |
+
import { motion, AnimatePresence } from "motion/react";
|
| 5 |
+
|
| 6 |
+
const FAQ_CATEGORIES = [
|
| 7 |
+
{ id: "all", name: "All FAQs" },
|
| 8 |
+
{ id: "security", name: "Data Security" },
|
| 9 |
+
{ id: "formats", name: "Supported Formats" },
|
| 10 |
+
{ id: "installation", name: "Installation & System" },
|
| 11 |
+
];
|
| 12 |
+
|
| 13 |
+
const FAQS_LIST = [
|
| 14 |
+
{
|
| 15 |
+
id: "faq-0",
|
| 16 |
+
cat: "security",
|
| 17 |
+
question: "Is Lumina Convert 100% free at all times?",
|
| 18 |
+
answer: "Yes, absolutely! Lumina Convert is entirely free, with no hidden subscriptions, trial caps, watermarks, or locked files. Every features, including batch conversions, high quality resolution configurations and dynamic on-device GPU acceleration, is active from the moment of installation.",
|
| 19 |
+
},
|
| 20 |
+
{
|
| 21 |
+
id: "faq-1",
|
| 22 |
+
cat: "security",
|
| 23 |
+
question: "Does my data or files get uploaded to any internet servers?",
|
| 24 |
+
answer: "No, never. Lumina Convert operates as an 'offline-first' software. 100% of the conversions and encodings process locally in your system. This makes our framework highly trusted by healthcare teams (HIPAA guidelines) and legal professionals bound under rigid client-non-disclosure policies.",
|
| 25 |
+
},
|
| 26 |
+
{
|
| 27 |
+
id: "faq-2",
|
| 28 |
+
cat: "formats",
|
| 29 |
+
question: "How many formats can Lumina Convert encode?",
|
| 30 |
+
answer: "Lumina supports over 200+ distinct multimedia extensions. You can convert documents (PDF, DOCX, XLSX, CSV), rich graphic layouts (WebP, SVG, PNG, TIFF, JPG), high frame rate films (MP4, MKV, MOV, GIF), and lossless studio audios (WAV, FLAC, Standard MP3).",
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
id: "faq-3",
|
| 34 |
+
cat: "installation",
|
| 35 |
+
question: "Which platforms does the installer require?",
|
| 36 |
+
answer: "Our standard installer supports Windows 10 and Windows 11 (both 64-bit platforms). It integrates pre-compiled architecture assemblies for NVIDIA CUDA, OpenCL cores, and standard CPU multithreading models out-of-the-box, ensuring optimal performance across different hardware configurations.",
|
| 37 |
+
},
|
| 38 |
+
{
|
| 39 |
+
id: "faq-4",
|
| 40 |
+
cat: "security",
|
| 41 |
+
question: "Can I use Lumina Convert on confidential government datasets?",
|
| 42 |
+
answer: "Yes. Because Lumina Convert holds zero networking permission layers on default execution files, it is impossible for compiled data structures to telemetry to external cloud coordinates. It safe-guards strict compliance acts.",
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
id: "faq-5",
|
| 46 |
+
cat: "installation",
|
| 47 |
+
question: "How do I trigger folder watch automation channels?",
|
| 48 |
+
answer: "In the desktop settings panel, select 'Watch Directories'. Link your target directories (e.g. ~/Downloads/Inputs). Select a standard encoding profile (e.g., PDF to Lossless WebP). When new items enter that folder path, Lumina Convert triggers automatically behind-the-scenes using minimal background system processing.",
|
| 49 |
+
},
|
| 50 |
+
];
|
| 51 |
+
|
| 52 |
+
export default function FAQ() {
|
| 53 |
+
const [searchTerm, setSearchTerm] = useState("");
|
| 54 |
+
const [activeCat, setActiveCat] = useState("all");
|
| 55 |
+
const [openId, setOpenId] = useState<string | null>("faq-0");
|
| 56 |
+
|
| 57 |
+
useEffect(() => {
|
| 58 |
+
updateSEO({
|
| 59 |
+
title: "Help Center & FAQs | Lumina Convert Local Desktop Application",
|
| 60 |
+
description: "Find instant answers to offline file security, HIPAA compliance protocols, multi-thread system processing hardware minimums, and folder automation pipelines on Lumina Convert.",
|
| 61 |
+
keywords: "Lumina convert FAQ, HIPAA compliant PDF converter, offline file converter support, watch folders tutorial",
|
| 62 |
+
});
|
| 63 |
+
}, []);
|
| 64 |
+
|
| 65 |
+
const filteredFaqs = FAQS_LIST.filter((faq) => {
|
| 66 |
+
const matchesSearch =
|
| 67 |
+
faq.question.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
| 68 |
+
faq.answer.toLowerCase().includes(searchTerm.toLowerCase());
|
| 69 |
+
const matchesCat = activeCat === "all" || faq.cat === activeCat;
|
| 70 |
+
return matchesSearch && matchesCat;
|
| 71 |
+
});
|
| 72 |
+
|
| 73 |
+
return (
|
| 74 |
+
<section className="py-12 bg-gradient-to-b from-[#FBFBFD] to-white min-h-screen">
|
| 75 |
+
<div className="max-w-4xl mx-auto px-4 md:px-8 mt-12 pb-24 text-left">
|
| 76 |
+
{/* Badge */}
|
| 77 |
+
<div className="mb-6 flex justify-center lg:justify-start">
|
| 78 |
+
<div className="inline-flex items-center space-x-2 bg-violet-50 border border-violet-100 px-3.5 py-1.5 rounded-full">
|
| 79 |
+
<HelpCircle className="w-3.5 h-3.5 text-violet-600" />
|
| 80 |
+
<span className="text-xs font-bold font-mono text-violet-700 uppercase tracking-widest">
|
| 81 |
+
Lumina Support Registry
|
| 82 |
+
</span>
|
| 83 |
+
</div>
|
| 84 |
+
</div>
|
| 85 |
+
|
| 86 |
+
{/* Title */}
|
| 87 |
+
<h1 className="font-display text-3xl sm:text-4xl lg:text-5xl font-bold text-slate-900 tracking-tight leading-tight mb-5 text-center lg:text-left">
|
| 88 |
+
Interactive Help Center &{" "}
|
| 89 |
+
<span className="bg-gradient-to-r from-violet-600 to-indigo-600 bg-clip-text text-transparent font-extrabold">
|
| 90 |
+
Knowledge Hub
|
| 91 |
+
</span>
|
| 92 |
+
</h1>
|
| 93 |
+
<p className="text-slate-600 text-base md:text-lg font-light max-w-3xl mb-12 text-center lg:text-left">
|
| 94 |
+
Have queries about dynamic on-device hardware acceleration, CUDA installation, folder watcher configurations, or offline licensing agreements? Browse our expert library.
|
| 95 |
+
</p>
|
| 96 |
+
|
| 97 |
+
{/* Search & Category Filter */}
|
| 98 |
+
<div className="bg-white p-6 rounded-3xl border border-slate-100 shadow-sm mb-10 space-y-4">
|
| 99 |
+
<div className="relative">
|
| 100 |
+
<Search className="absolute left-3.5 top-1/2 -translate-y-1/2 w-4.5 h-4.5 text-slate-400" />
|
| 101 |
+
<input
|
| 102 |
+
type="text"
|
| 103 |
+
value={searchTerm}
|
| 104 |
+
onChange={(e) => setSearchTerm(e.target.value)}
|
| 105 |
+
placeholder="Search through help topics (e.g., HIPAA, GPU, watch folders)..."
|
| 106 |
+
className="w-full pl-11 pr-4 py-3 bg-slate-50 border border-slate-200/80 rounded-2xl text-slate-800 text-sm focus:outline-none focus:ring-1 focus:ring-violet-500 focus:border-violet-500 focus:bg-white transition"
|
| 107 |
+
/>
|
| 108 |
+
</div>
|
| 109 |
+
|
| 110 |
+
<div className="flex flex-wrap gap-2 pt-2 border-t border-slate-100">
|
| 111 |
+
{FAQ_CATEGORIES.map((cat) => (
|
| 112 |
+
<button
|
| 113 |
+
key={cat.id}
|
| 114 |
+
onClick={() => {
|
| 115 |
+
setActiveCat(cat.id);
|
| 116 |
+
setOpenId(null);
|
| 117 |
+
}}
|
| 118 |
+
className={`text-xs font-semibold py-2 px-4 rounded-xl transition cursor-pointer border ${
|
| 119 |
+
activeCat === cat.id
|
| 120 |
+
? "bg-violet-600 text-white border-violet-600"
|
| 121 |
+
: "bg-white text-slate-600 border-slate-200/60 hover:bg-slate-50"
|
| 122 |
+
}`}
|
| 123 |
+
>
|
| 124 |
+
{cat.name}
|
| 125 |
+
</button>
|
| 126 |
+
))}
|
| 127 |
+
</div>
|
| 128 |
+
</div>
|
| 129 |
+
|
| 130 |
+
{/* FAQ Accordion Grid */}
|
| 131 |
+
<div className="space-y-4" id="faq-interactive-accordion">
|
| 132 |
+
{filteredFaqs.length > 0 ? (
|
| 133 |
+
filteredFaqs.map((faq) => {
|
| 134 |
+
const isOpen = openId === faq.id;
|
| 135 |
+
return (
|
| 136 |
+
<div
|
| 137 |
+
key={faq.id}
|
| 138 |
+
className={`rounded-2xl border transition-all duration-300 overflow-hidden ${
|
| 139 |
+
isOpen
|
| 140 |
+
? "bg-slate-50-60 border-violet-100 shadow-sm"
|
| 141 |
+
: "bg-white border-slate-100 hover:border-slate-200"
|
| 142 |
+
}`}
|
| 143 |
+
id={faq.id}
|
| 144 |
+
>
|
| 145 |
+
<button
|
| 146 |
+
onClick={() => setOpenId(isOpen ? null : faq.id)}
|
| 147 |
+
className="w-full py-5 px-6 md:px-8 flex items-center justify-between text-left focus:outline-none cursor-pointer"
|
| 148 |
+
>
|
| 149 |
+
<span className="font-display font-semibold text-sm md:text-base text-slate-800 pr-4">
|
| 150 |
+
{faq.question}
|
| 151 |
+
</span>
|
| 152 |
+
<div
|
| 153 |
+
className={`w-7 h-7 rounded-full border flex items-center justify-center transition-transform duration-300 flex-shrink-0 ${
|
| 154 |
+
isOpen ? "bg-violet-600 text-white border-violet-600" : "text-slate-400 bg-white"
|
| 155 |
+
}`}
|
| 156 |
+
>
|
| 157 |
+
{isOpen ? (
|
| 158 |
+
<Minus className="w-3.5 h-3.5 stroke-[2.5]" />
|
| 159 |
+
) : (
|
| 160 |
+
<Plus className="w-3.5 h-3.5 stroke-[2.5]" />
|
| 161 |
+
)}
|
| 162 |
+
</div>
|
| 163 |
+
</button>
|
| 164 |
+
|
| 165 |
+
<AnimatePresence initial={false}>
|
| 166 |
+
{isOpen && (
|
| 167 |
+
<motion.div
|
| 168 |
+
initial={{ height: 0 }}
|
| 169 |
+
animate={{ height: "auto" }}
|
| 170 |
+
exit={{ height: 0 }}
|
| 171 |
+
transition={{ duration: 0.2, ease: "easeInOut" }}
|
| 172 |
+
>
|
| 173 |
+
<div className="px-6 md:px-8 pb-6 text-xs md:text-sm text-slate-500 font-light leading-relaxed border-t border-slate-100/30 pt-3">
|
| 174 |
+
{faq.answer}
|
| 175 |
+
</div>
|
| 176 |
+
</motion.div>
|
| 177 |
+
)}
|
| 178 |
+
</AnimatePresence>
|
| 179 |
+
</div>
|
| 180 |
+
);
|
| 181 |
+
})
|
| 182 |
+
) : (
|
| 183 |
+
<div className="text-center py-12 bg-white rounded-3xl border border-dashed border-slate-200/85">
|
| 184 |
+
<ShieldAlert className="w-8 h-8 text-slate-300 mx-auto mb-2" />
|
| 185 |
+
<p className="text-sm font-semibold text-slate-700">No help logs matched search</p>
|
| 186 |
+
<p className="text-xs text-slate-400 mt-1">Try other general keywords like 'free' or 'offline'.</p>
|
| 187 |
+
</div>
|
| 188 |
+
)}
|
| 189 |
+
</div>
|
| 190 |
+
|
| 191 |
+
{/* Support contacts banner */}
|
| 192 |
+
<div className="mt-16 bg-white border border-slate-100 p-6 rounded-[28px] flex flex-col sm:flex-row items-center justify-between gap-6 shadow-sm">
|
| 193 |
+
<div className="flex items-center space-x-4 text-left">
|
| 194 |
+
<div className="w-12 h-12 rounded-2xl bg-indigo-50 border border-indigo-100 text-indigo-600 flex items-center justify-center shadow-inner">
|
| 195 |
+
<MessageSquare className="w-5 h-5" />
|
| 196 |
+
</div>
|
| 197 |
+
<div>
|
| 198 |
+
<h4 className="font-semibold text-sm text-slate-900">Still have custom script questions?</h4>
|
| 199 |
+
<p className="text-xs text-slate-500 font-light mt-0.5">Speak with our local developers directly via WhatsApp.</p>
|
| 200 |
+
</div>
|
| 201 |
+
</div>
|
| 202 |
+
<div className="flex gap-3">
|
| 203 |
+
<a
|
| 204 |
+
href="https://wa.me/923034572298"
|
| 205 |
+
target="_blank"
|
| 206 |
+
rel="noopener noreferrer"
|
| 207 |
+
className="py-2 px-5 rounded-xl bg-emerald-600 hover:bg-emerald-700 transition text-white text-xs font-semibold shadow-sm"
|
| 208 |
+
>
|
| 209 |
+
WhatsApp (+92 303 4572298)
|
| 210 |
+
</a>
|
| 211 |
+
<a
|
| 212 |
+
href="mailto:bahaduralimunnabhai@gmail.com"
|
| 213 |
+
className="py-2 px-5 rounded-xl border border-slate-200 text-slate-700 hover:bg-slate-50 transition text-xs font-semibold"
|
| 214 |
+
>
|
| 215 |
+
Email Inbox
|
| 216 |
+
</a>
|
| 217 |
+
</div>
|
| 218 |
+
</div>
|
| 219 |
+
</div>
|
| 220 |
+
</section>
|
| 221 |
+
);
|
| 222 |
+
}
|
all-file-converter/src/pages/Features.tsx
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useEffect, useState } from "react";
|
| 2 |
+
import { updateSEO } from "../utils/seo";
|
| 3 |
+
import { Layers, CheckCircle2, Cpu, FileText, Image as ImageIcon, Video, Music, Command, Code, Search, ArrowRight } from "lucide-react";
|
| 4 |
+
import { motion } from "motion/react";
|
| 5 |
+
|
| 6 |
+
const FORMAT_CATEGORIES = [
|
| 7 |
+
{
|
| 8 |
+
id: "docs",
|
| 9 |
+
name: "Documents & Office",
|
| 10 |
+
icon: <FileText className="w-5 h-5 text-indigo-500" />,
|
| 11 |
+
intro: "Convert reports, contracts, spreadsheets, presentations, and vector documents.",
|
| 12 |
+
formats: [
|
| 13 |
+
{ ext: "PDF", name: "Portable Document Format", bidirectional: true, speed: "Instant" },
|
| 14 |
+
{ ext: "DOC/DOCX", name: "Microsoft Word Template", bidirectional: true, speed: "Ultra Fast" },
|
| 15 |
+
{ ext: "XLS/XLSX", name: "Microsoft Excel Spreadsheet", bidirectional: true, speed: "Fast" },
|
| 16 |
+
{ ext: "PPT/PPTX", name: "Microsoft PowerPoint Presentation", bidirectional: true, speed: "Fast" },
|
| 17 |
+
{ ext: "TXT/RTF", name: "Plain and Rich Text Files", bidirectional: true, speed: "Instant" },
|
| 18 |
+
{ ext: "CSV", name: "Comma Separated Values", bidirectional: true, speed: "Instant" },
|
| 19 |
+
{ ext: "EPUB", name: "Electronic Publication eBook", bidirectional: true, speed: "Medium" },
|
| 20 |
+
{ ext: "HTML/MHTML", name: "Web Document Format", bidirectional: true, speed: "Instant" },
|
| 21 |
+
],
|
| 22 |
+
},
|
| 23 |
+
{
|
| 24 |
+
id: "images",
|
| 25 |
+
name: "Images & Vectors",
|
| 26 |
+
icon: <ImageIcon className="w-5 h-5 text-violet-500" />,
|
| 27 |
+
intro: "Compress design projects, generate modern formats, or export lossless vectors.",
|
| 28 |
+
formats: [
|
| 29 |
+
{ ext: "WEBP", name: "Google WebP Ultra Image", bidirectional: true, speed: "GPU Optimized" },
|
| 30 |
+
{ ext: "PNG", name: "Lossless Portable Network Graphics", bidirectional: true, speed: "GPU Stacked" },
|
| 31 |
+
{ ext: "JPG/JPEG", name: "Standard Joint Photographic Group", bidirectional: true, speed: "Instant" },
|
| 32 |
+
{ ext: "SVG", name: "Scalable Vector Illustration", bidirectional: true, speed: "Instant" },
|
| 33 |
+
{ ext: "TIFF", name: "High-definition Desktop Publishing", bidirectional: true, speed: "Fast" },
|
| 34 |
+
{ ext: "GIF", name: "Graphical Interchange Animation", bidirectional: true, speed: "Medium" },
|
| 35 |
+
{ ext: "BMP", name: "Bitmapped Color Grid Archive", bidirectional: true, speed: "Instant" },
|
| 36 |
+
{ ext: "ICO", name: "Windows App Integration Icon", bidirectional: true, speed: "Instant" },
|
| 37 |
+
],
|
| 38 |
+
},
|
| 39 |
+
{
|
| 40 |
+
id: "video",
|
| 41 |
+
name: "Video & Animation",
|
| 42 |
+
icon: <Video className="w-5 h-5 text-fuchsia-500" />,
|
| 43 |
+
intro: "Encode films, strip streams, adjust bitrates, or convert slideshow matrices.",
|
| 44 |
+
formats: [
|
| 45 |
+
{ ext: "MP4", name: "MPEG-4 Standard Stream", bidirectional: true, speed: "6x CUDA Speed" },
|
| 46 |
+
{ ext: "MKV", name: "Matroska Multimedia Container", bidirectional: true, speed: "GPU Direct" },
|
| 47 |
+
{ ext: "MOV", name: "Apple QuickTime Film", bidirectional: true, speed: "Mac Metal core" },
|
| 48 |
+
{ ext: "AVI", name: "Audio Video Interleaved Legacy", bidirectional: true, speed: "Fast" },
|
| 49 |
+
{ ext: "WEBM", name: "Google WebM High-Compression", bidirectional: true, speed: "GPU Direct" },
|
| 50 |
+
{ ext: "GIF (Video)", name: "Convert film segment to Animated GIF", bidirectional: true, speed: "CPU Heavy" },
|
| 51 |
+
{ ext: "MPEG/MPG", name: "Classic Broadcasting Suite", bidirectional: false, speed: "Fast" },
|
| 52 |
+
],
|
| 53 |
+
},
|
| 54 |
+
{
|
| 55 |
+
id: "audio",
|
| 56 |
+
name: "Audio & Music",
|
| 57 |
+
icon: <Music className="w-5 h-5 text-emerald-500" />,
|
| 58 |
+
intro: "Sample podcast tracks, convert audio notes, or compress studio tracks.",
|
| 59 |
+
formats: [
|
| 60 |
+
{ ext: "MP3", name: "MPEG Layer-3 Audio Stream", bidirectional: true, speed: "Instant" },
|
| 61 |
+
{ ext: "WAV", name: "Waveform Studio High Fidelity", bidirectional: true, speed: "Instant" },
|
| 62 |
+
{ ext: "FLAC", name: "Free Lossless Audio Codec", bidirectional: true, speed: "Fast" },
|
| 63 |
+
{ ext: "AAC", name: "Advanced Audio Coding Stream", bidirectional: true, speed: "Instant" },
|
| 64 |
+
{ ext: "OGG", name: "Ogg Vorbis Compressed Media", bidirectional: true, speed: "Fast" },
|
| 65 |
+
{ ext: "M4A", name: "Apple AAC Audio Wrapper", bidirectional: true, speed: "Instant" },
|
| 66 |
+
{ ext: "WMA", name: "Windows Media Format Audio", bidirectional: true, speed: "Fast" },
|
| 67 |
+
],
|
| 68 |
+
},
|
| 69 |
+
];
|
| 70 |
+
|
| 71 |
+
const CLI_EXAMPLE = `# Convert standard document to WebP locally
|
| 72 |
+
lumina-convert --input quarterly_report.pdf --output webp/ --quality 95
|
| 73 |
+
|
| 74 |
+
# Super-resolution upscale image via GPU CUDA
|
| 75 |
+
lumina-convert --upscale 2x --cpu-threads 8 --gpu-state cudanext --file photo.jpg
|
| 76 |
+
|
| 77 |
+
# Batch extract all frames from video
|
| 78 |
+
lumina-convert --batch --dir ~/media/exports --format mp3 --dry-run false`;
|
| 79 |
+
|
| 80 |
+
export default function Features() {
|
| 81 |
+
const [searchTerm, setSearchTerm] = useState("");
|
| 82 |
+
const [activeTab, setActiveTab] = useState("all");
|
| 83 |
+
|
| 84 |
+
useEffect(() => {
|
| 85 |
+
updateSEO({
|
| 86 |
+
title: "Supported Formats & CLI Specs | Lumina Convert Technical",
|
| 87 |
+
description: "Explore 200+ converter formats. Complete database details for PDF, DOCX, WebP, SVG, PNG, MP4, MKV, FLAC, and WAV converting pipelines equipped by Lumina local GPU acceleration.",
|
| 88 |
+
keywords: "Lumina convert formats list, local video codec, on-device audio conversion, CLI file converter command, secure conversion parameters",
|
| 89 |
+
});
|
| 90 |
+
}, []);
|
| 91 |
+
|
| 92 |
+
// Filter formats
|
| 93 |
+
const filteredCategories = FORMAT_CATEGORIES.map((cat) => {
|
| 94 |
+
if (activeTab !== "all" && cat.id !== activeTab) {
|
| 95 |
+
return null;
|
| 96 |
+
}
|
| 97 |
+
const matchingFormats = cat.formats.filter((f) =>
|
| 98 |
+
f.ext.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
| 99 |
+
f.name.toLowerCase().includes(searchTerm.toLowerCase())
|
| 100 |
+
);
|
| 101 |
+
if (matchingFormats.length === 0 && searchTerm !== "") return null;
|
| 102 |
+
return {
|
| 103 |
+
...cat,
|
| 104 |
+
formats: searchTerm === "" ? cat.formats : matchingFormats,
|
| 105 |
+
};
|
| 106 |
+
}).filter((c) => c !== null) as typeof FORMAT_CATEGORIES;
|
| 107 |
+
|
| 108 |
+
return (
|
| 109 |
+
<section className="py-12 bg-gradient-to-b from-[#FBFBFD] to-[#FAF9FE] min-h-screen">
|
| 110 |
+
<div className="max-w-7xl mx-auto px-4 md:px-8 mt-12 pb-24 text-left">
|
| 111 |
+
{/* Breadcrumb / Badge */}
|
| 112 |
+
<div className="mb-6 flex justify-center lg:justify-start">
|
| 113 |
+
<div className="inline-flex items-center space-x-2 bg-violet-50 border border-violet-100 px-3.5 py-1.5 rounded-full">
|
| 114 |
+
<Layers className="w-3.5 h-3.5 text-violet-600" />
|
| 115 |
+
<span className="text-xs font-bold font-mono text-violet-700 uppercase tracking-widest">
|
| 116 |
+
Lumina Architecture Database
|
| 117 |
+
</span>
|
| 118 |
+
</div>
|
| 119 |
+
</div>
|
| 120 |
+
|
| 121 |
+
{/* Title */}
|
| 122 |
+
<h1 className="font-display text-3xl sm:text-4xl lg:text-5xl font-bold text-slate-900 tracking-tight leading-tight mb-5 text-center lg:text-left">
|
| 123 |
+
200+ Formats, Powered by{" "}
|
| 124 |
+
<span className="bg-gradient-to-r from-violet-600 to-indigo-600 bg-clip-text text-transparent font-extrabold">
|
| 125 |
+
Local Codecs
|
| 126 |
+
</span>
|
| 127 |
+
</h1>
|
| 128 |
+
<p className="text-slate-600 text-base md:text-lg font-light max-w-3xl mb-12 text-center lg:text-left">
|
| 129 |
+
Lumina Convert embeds compiled versions of FFmpeg, Ghostscript, and WebP tools directly within our Windows executable framework. Review our active on-device encoding pipeline below.
|
| 130 |
+
</p>
|
| 131 |
+
|
| 132 |
+
{/* Search bar & Category filters */}
|
| 133 |
+
<div className="bg-white p-6 rounded-3xl border border-slate-100/80 shadow-md shadow-slate-100/20 mb-12">
|
| 134 |
+
<div className="flex flex-col md:flex-row gap-4 items-center justify-between">
|
| 135 |
+
{/* Search */}
|
| 136 |
+
<div className="relative w-full md:w-80">
|
| 137 |
+
<Search className="absolute left-3.5 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" />
|
| 138 |
+
<input
|
| 139 |
+
type="text"
|
| 140 |
+
value={searchTerm}
|
| 141 |
+
onChange={(e) => setSearchTerm(e.target.value)}
|
| 142 |
+
placeholder="Search extension (e.g., pdf, webp)..."
|
| 143 |
+
className="w-full pl-10 pr-4 py-2.5 bg-slate-50 border border-slate-200/80 rounded-2xl text-slate-800 text-sm focus:outline-none focus:ring-1 focus:ring-violet-500 focus:border-violet-500 focus:bg-white transition"
|
| 144 |
+
/>
|
| 145 |
+
</div>
|
| 146 |
+
|
| 147 |
+
{/* Filter segments */}
|
| 148 |
+
<div className="flex flex-wrap gap-2 w-full md:w-auto">
|
| 149 |
+
{[
|
| 150 |
+
{ name: "All Categories", id: "all" },
|
| 151 |
+
{ name: "Documents", id: "docs" },
|
| 152 |
+
{ name: "Images", id: "images" },
|
| 153 |
+
{ name: "Videos", id: "video" },
|
| 154 |
+
{ name: "Audios", id: "audio" },
|
| 155 |
+
].map((tab) => (
|
| 156 |
+
<button
|
| 157 |
+
key={tab.id}
|
| 158 |
+
onClick={() => setActiveTab(tab.id)}
|
| 159 |
+
className={`text-xs font-semibold py-2 px-4 rounded-xl transition cursor-pointer border ${
|
| 160 |
+
activeTab === tab.id
|
| 161 |
+
? "bg-violet-600 text-white border-violet-600 shadow-sm"
|
| 162 |
+
: "bg-white text-slate-600 border-slate-200/60 hover:bg-slate-50"
|
| 163 |
+
}`}
|
| 164 |
+
>
|
| 165 |
+
{tab.name}
|
| 166 |
+
</button>
|
| 167 |
+
))}
|
| 168 |
+
</div>
|
| 169 |
+
</div>
|
| 170 |
+
</div>
|
| 171 |
+
|
| 172 |
+
{/* Categories rendering */}
|
| 173 |
+
<div className="space-y-16" id="technical-categories-group">
|
| 174 |
+
{filteredCategories.length > 0 ? (
|
| 175 |
+
filteredCategories.map((cat) => (
|
| 176 |
+
<div key={cat.id} className="space-y-6" id={`category-block-${cat.id}`}>
|
| 177 |
+
{/* Category Header */}
|
| 178 |
+
<div className="flex items-center space-x-3 pb-3 border-b border-slate-150">
|
| 179 |
+
<div className="p-2.5 rounded-xl bg-white border border-slate-100/60 shadow-sm">
|
| 180 |
+
{cat.icon}
|
| 181 |
+
</div>
|
| 182 |
+
<div>
|
| 183 |
+
<h2 className="font-display font-bold text-xl text-slate-900 tracking-tight">
|
| 184 |
+
{cat.name}
|
| 185 |
+
</h2>
|
| 186 |
+
<p className="text-slate-500 text-xs font-light">{cat.intro}</p>
|
| 187 |
+
</div>
|
| 188 |
+
</div>
|
| 189 |
+
|
| 190 |
+
{/* Formats Grid */}
|
| 191 |
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
| 192 |
+
{cat.formats.map((f, i) => (
|
| 193 |
+
<div
|
| 194 |
+
key={i}
|
| 195 |
+
className="p-5 rounded-2xl bg-white border border-slate-100 shadow-sm hover:border-violet-100 hover:shadow-md transition-all text-left flex flex-col justify-between"
|
| 196 |
+
>
|
| 197 |
+
<div>
|
| 198 |
+
{/* Extension header */}
|
| 199 |
+
<div className="flex justify-between items-center mb-2.5">
|
| 200 |
+
<span className="font-mono font-bold text-sm bg-slate-100 text-slate-800 px-2.5 py-1 rounded-lg">
|
| 201 |
+
.{f.ext}
|
| 202 |
+
</span>
|
| 203 |
+
<span className="text-[10px] font-mono font-semibold text-violet-600 tracking-wider uppercase bg-violet-50 px-2 py-0.5 rounded">
|
| 204 |
+
{f.speed}
|
| 205 |
+
</span>
|
| 206 |
+
</div>
|
| 207 |
+
|
| 208 |
+
{/* Name */}
|
| 209 |
+
<h4 className="text-sm font-semibold text-slate-900 mb-1">{f.ext} Container</h4>
|
| 210 |
+
<p className="text-slate-500 text-xs font-light leading-relaxed mb-4">
|
| 211 |
+
{f.name} encoder algorithms.
|
| 212 |
+
</p>
|
| 213 |
+
</div>
|
| 214 |
+
|
| 215 |
+
<div className="flex items-center text-[10px] text-slate-400 border-t border-slate-50/50 pt-3">
|
| 216 |
+
<CheckCircle2 className="w-3.5 h-3.5 text-emerald-500 mr-1.5" />
|
| 217 |
+
<span>Bi-directional local processing</span>
|
| 218 |
+
</div>
|
| 219 |
+
</div>
|
| 220 |
+
))}
|
| 221 |
+
</div>
|
| 222 |
+
</div>
|
| 223 |
+
))
|
| 224 |
+
) : (
|
| 225 |
+
<div className="text-center py-16 bg-white p-8 rounded-3xl border border-dashed border-slate-205 max-w-sm mx-auto">
|
| 226 |
+
<p className="text-sm font-semibold text-slate-700">No format extensions found</p>
|
| 227 |
+
<p className="text-xs text-slate-500 mt-1">Try testing other search queries.</p>
|
| 228 |
+
</div>
|
| 229 |
+
)}
|
| 230 |
+
</div>
|
| 231 |
+
|
| 232 |
+
{/* Premium Developer Command Line CLI Showcase */}
|
| 233 |
+
<div className="mt-20 bg-slate-950 p-8 rounded-[32px] border border-white/10 shadow-2xl relative overflow-hidden">
|
| 234 |
+
<div className="absolute top-0 right-0 w-96 h-96 bg-violet-600/10 rounded-full blur-3xl pointer-events-none" />
|
| 235 |
+
|
| 236 |
+
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 items-center">
|
| 237 |
+
{/* CLI text info */}
|
| 238 |
+
<div className="lg:col-span-5 text-left space-y-5">
|
| 239 |
+
<div className="inline-flex items-center space-x-2 bg-white/10 border border-white/10 px-3 py-1 rounded-full text-slate-350">
|
| 240 |
+
<Command className="w-3.5 h-3.5 text-violet-400" />
|
| 241 |
+
<span className="text-[10px] font-mono font-bold uppercase tracking-wider">
|
| 242 |
+
Power-User CLI Engine
|
| 243 |
+
</span>
|
| 244 |
+
</div>
|
| 245 |
+
<h3 className="font-display font-medium text-2xl text-white tracking-tight">
|
| 246 |
+
Headless Terminal Triggers
|
| 247 |
+
</h3>
|
| 248 |
+
<p className="text-slate-400 text-xs md:text-sm font-light leading-relaxed">
|
| 249 |
+
Need to automate conversions from watch folders, shell scripts, or localized server procedures? Every Lumina Convert install registers the <code>lumina-convert</code> wrapper to the system environment PATH.
|
| 250 |
+
</p>
|
| 251 |
+
<ul className="space-y-2 text-xs text-slate-300 font-light">
|
| 252 |
+
<li className="flex items-center gap-2">
|
| 253 |
+
<div className="w-1.5 h-1.5 rounded-full bg-violet-400" />
|
| 254 |
+
<span>Supports complete wildcards (e.g. *.png)</span>
|
| 255 |
+
</li>
|
| 256 |
+
<li className="flex items-center gap-2">
|
| 257 |
+
<div className="w-1.5 h-1.5 rounded-full bg-violet-400" />
|
| 258 |
+
<span>Returns industry-standard shell code outputs</span>
|
| 259 |
+
</li>
|
| 260 |
+
<li className="flex items-center gap-2">
|
| 261 |
+
<div className="w-1.5 h-1.5 rounded-full bg-violet-400" />
|
| 262 |
+
<span>Lightweight wrapper (~12MB storage trace)</span>
|
| 263 |
+
</li>
|
| 264 |
+
</ul>
|
| 265 |
+
</div>
|
| 266 |
+
|
| 267 |
+
{/* Simulated Shell Terminal */}
|
| 268 |
+
<div className="lg:col-span-7 bg-slate-900 border border-white/5 rounded-2xl overflow-hidden shadow-inner">
|
| 269 |
+
{/* Window Header */}
|
| 270 |
+
<div className="bg-slate-950 px-4 py-2.5 flex items-center justify-between border-b border-white/5">
|
| 271 |
+
<div className="flex space-x-1.5">
|
| 272 |
+
<span className="w-3 h-3 rounded-full bg-rose-450 opacity-80" />
|
| 273 |
+
<span className="w-3 h-3 rounded-full bg-amber-450 opacity-80" />
|
| 274 |
+
<span className="w-3 h-3 rounded-full bg-emerald-450 opacity-80" />
|
| 275 |
+
</div>
|
| 276 |
+
<span className="text-[10px] font-mono font-bold text-slate-400">PowerShell - L_Convert_CLI</span>
|
| 277 |
+
<span className="w-1" />
|
| 278 |
+
</div>
|
| 279 |
+
|
| 280 |
+
{/* Code window */}
|
| 281 |
+
<div className="p-5 text-left font-mono text-xs text-slate-300 leading-relaxed overflow-x-auto whitespace-pre bg-slate-950/80">
|
| 282 |
+
{CLI_EXAMPLE}
|
| 283 |
+
</div>
|
| 284 |
+
</div>
|
| 285 |
+
</div>
|
| 286 |
+
</div>
|
| 287 |
+
</div>
|
| 288 |
+
</section>
|
| 289 |
+
);
|
| 290 |
+
}
|
all-file-converter/src/pages/Home.tsx
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useEffect } from "react";
|
| 2 |
+
import Hero from "../components/Hero";
|
| 3 |
+
import Stats from "../components/Stats";
|
| 4 |
+
import Features from "../components/Features";
|
| 5 |
+
import Testimonials from "../components/Testimonials";
|
| 6 |
+
import { updateSEO } from "../utils/seo";
|
| 7 |
+
import { Shield, Sparkles, Heart } from "lucide-react";
|
| 8 |
+
import { Link } from "react-router-dom";
|
| 9 |
+
|
| 10 |
+
interface HomeProps {
|
| 11 |
+
downloadUrl: string;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
export default function Home({ downloadUrl }: HomeProps) {
|
| 15 |
+
useEffect(() => {
|
| 16 |
+
updateSEO({
|
| 17 |
+
title: "All File Converter | Lumina Convert - 100% Offline GPU Accelerated",
|
| 18 |
+
description: "Convert any file in seconds - PDF, images, video, audio. Lumina Convert is a high-speed, 100% offline-first software offering total data confidentiality and GPU hardware acceleration.",
|
| 19 |
+
keywords: "file converter, offline file converter, video converter, image converter, PDF to Word, local converter, GPU accelerated file encoding, HIPAA file converter, Lumina Convert",
|
| 20 |
+
schema: JSON.stringify({
|
| 21 |
+
"@context": "https://schema.org",
|
| 22 |
+
"@type": "SoftwareApplication",
|
| 23 |
+
"name": "Lumina Convert",
|
| 24 |
+
"operatingSystem": "Windows 10, Windows 11",
|
| 25 |
+
"applicationCategory": "UtilityApplication",
|
| 26 |
+
"offers": {
|
| 27 |
+
"@type": "Offer",
|
| 28 |
+
"price": "0.00",
|
| 29 |
+
"priceCurrency": "USD"
|
| 30 |
+
},
|
| 31 |
+
"description": "Convert any file locally and offline in seconds. Over 200+ formats with open source codec speedup.",
|
| 32 |
+
"downloadUrl": downloadUrl
|
| 33 |
+
})
|
| 34 |
+
});
|
| 35 |
+
}, [downloadUrl]);
|
| 36 |
+
|
| 37 |
+
return (
|
| 38 |
+
<div className="home-page-root animate-fade-in">
|
| 39 |
+
{/* Hero section with main file converting console */}
|
| 40 |
+
<Hero downloadUrl={downloadUrl} />
|
| 41 |
+
|
| 42 |
+
{/* Trust Stats Bar */}
|
| 43 |
+
<Stats />
|
| 44 |
+
|
| 45 |
+
{/* Feature Highlights Grid */}
|
| 46 |
+
<div className="py-12 bg-white">
|
| 47 |
+
<Features />
|
| 48 |
+
</div>
|
| 49 |
+
|
| 50 |
+
{/* Split High Ranking SEO Informative Block */}
|
| 51 |
+
<section className="py-20 bg-gradient-to-b from-[#fbfbfd] to-[#faf9fe] border-t border-slate-150">
|
| 52 |
+
<div className="max-w-7xl mx-auto px-4 md:px-8 grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
|
| 53 |
+
<div className="text-left space-y-6">
|
| 54 |
+
<div className="inline-flex items-center space-x-2 bg-indigo-50 border border-indigo-100 px-3.5 py-1.5 rounded-full">
|
| 55 |
+
<Shield className="w-3.5 h-3.5 text-indigo-600" />
|
| 56 |
+
<span className="text-xs font-bold font-mono text-indigo-700 uppercase tracking-wide">Secure Privacy First Architecture</span>
|
| 57 |
+
</div>
|
| 58 |
+
<h2 className="font-display font-bold text-3xl md:text-4xl text-slate-900 tracking-tight leading-snug">
|
| 59 |
+
Why leading enterprises select <span className="text-violet-600 font-semibold">Lumina Convert</span>
|
| 60 |
+
</h2>
|
| 61 |
+
<p className="text-slate-600 text-sm md:text-base font-light leading-relaxed">
|
| 62 |
+
Most standard internet converters require uploading your confidential layouts, legal corporate records, or personal family recordings to external servers. This action exposes you to corporate espionage risks, compliance fines (HIPAA, GDPR), and general third-party server failures.
|
| 63 |
+
</p>
|
| 64 |
+
<p className="text-slate-600 text-sm md:text-base font-light leading-relaxed">
|
| 65 |
+
Lumina Convert features fully compiled on-device codecs. It requires <strong>no network connection</strong>, processes files 6x faster than online alternatives using your machine's graphics core, and keeps your private files completely private.
|
| 66 |
+
</p>
|
| 67 |
+
<div className="pt-4 flex flex-wrap gap-4">
|
| 68 |
+
<Link
|
| 69 |
+
to="/features"
|
| 70 |
+
id="home-seo-features-link"
|
| 71 |
+
className="inline-flex items-center space-x-2 py-3 px-6 rounded-full bg-slate-900 text-white hover:bg-violet-600 transition shadow-sm font-semibold text-sm cursor-pointer"
|
| 72 |
+
>
|
| 73 |
+
<span>View Full Format Technical Specifications</span>
|
| 74 |
+
</Link>
|
| 75 |
+
<Link
|
| 76 |
+
to="/privacy"
|
| 77 |
+
id="home-seo-privacy-link"
|
| 78 |
+
className="inline-flex items-center space-x-2 py-3 px-6 rounded-full border border-slate-200 hover:bg-slate-50 text-slate-700 transition font-semibold text-sm cursor-pointer"
|
| 79 |
+
>
|
| 80 |
+
<span>Read Compliance Certification</span>
|
| 81 |
+
</Link>
|
| 82 |
+
</div>
|
| 83 |
+
</div>
|
| 84 |
+
|
| 85 |
+
<div className="bg-white p-8 rounded-[32px] border border-slate-100 shadow-xl relative overflow-hidden text-left">
|
| 86 |
+
<div className="absolute top-0 right-0 w-24 h-24 bg-gradient-to-br from-violet-200/10 to-transparent rounded-full" />
|
| 87 |
+
<h4 className="text-lg font-display font-semibold text-slate-900 mb-6 flex items-center space-x-2">
|
| 88 |
+
<Sparkles className="w-5 h-5 text-violet-500" />
|
| 89 |
+
<span>Full Standalone Core Benefits</span>
|
| 90 |
+
</h4>
|
| 91 |
+
<div className="space-y-4">
|
| 92 |
+
{[
|
| 93 |
+
{
|
| 94 |
+
title: "GDPR, HIPAA, and CCPA Ready",
|
| 95 |
+
desc: "Zero records leave the computer. Perfect for auditing requirements."
|
| 96 |
+
},
|
| 97 |
+
{
|
| 98 |
+
title: "No Subscriptions or Pricing Tiers",
|
| 99 |
+
desc: "100% free with absolutely no premium blockades, caps, or ads."
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
title: "Multi-threading CPU + GPU Cores",
|
| 103 |
+
desc: "Utilize full pipeline threads of Ryzen/Intel and NVIDIA CUDA architecture."
|
| 104 |
+
},
|
| 105 |
+
{
|
| 106 |
+
title: "No Internet Connection Required",
|
| 107 |
+
desc: "Perfect for working on planes, trains, remote sites, or restricted servers."
|
| 108 |
+
}
|
| 109 |
+
].map((item, idx) => (
|
| 110 |
+
<div key={idx} className="flex gap-4">
|
| 111 |
+
<div className="w-6 h-6 rounded-full bg-violet-50 border border-violet-100 flex items-center justify-center text-violet-600 flex-shrink-0 font-bold font-mono text-xs">
|
| 112 |
+
{idx + 1}
|
| 113 |
+
</div>
|
| 114 |
+
<div>
|
| 115 |
+
<h5 className="text-slate-800 text-sm font-semibold">{item.title}</h5>
|
| 116 |
+
<p className="text-slate-500 text-xs font-light mt-0.5">{item.desc}</p>
|
| 117 |
+
</div>
|
| 118 |
+
</div>
|
| 119 |
+
))}
|
| 120 |
+
</div>
|
| 121 |
+
</div>
|
| 122 |
+
</div>
|
| 123 |
+
</section>
|
| 124 |
+
|
| 125 |
+
{/* User Reviews */}
|
| 126 |
+
<Testimonials />
|
| 127 |
+
|
| 128 |
+
{/* Support development of converter */}
|
| 129 |
+
<section className="bg-white py-12">
|
| 130 |
+
<div className="max-w-4xl mx-auto px-4 md:px-8 text-center space-y-4">
|
| 131 |
+
<div className="w-10 h-10 rounded-full bg-amber-50 text-amber-500 border border-amber-100 flex items-center justify-center mx-auto mb-2">
|
| 132 |
+
<Heart className="w-5 h-5 fill-current" />
|
| 133 |
+
</div>
|
| 134 |
+
<h3 className="font-display font-bold text-xl md:text-2xl text-slate-900 tracking-tight">Enjoying Lumina Convert?</h3>
|
| 135 |
+
<p className="text-slate-500 text-sm font-light max-w-xl mx-auto">
|
| 136 |
+
This premium companion converter app is completely free. Consider buying us a coffee or shopping on Amazon to support our server hosting, codec compilation tools, and support queues.
|
| 137 |
+
</p>
|
| 138 |
+
<div className="pt-2">
|
| 139 |
+
<Link
|
| 140 |
+
to="/support"
|
| 141 |
+
id="home-support-cta-btn"
|
| 142 |
+
className="inline-flex items-center justify-center space-x-2 py-3 px-8 rounded-full bg-amber-500 hover:bg-amber-600 transition text-white font-semibold text-sm cursor-pointer shadow-md shadow-amber-500/10"
|
| 143 |
+
>
|
| 144 |
+
<span>Support Our Developer Platform</span>
|
| 145 |
+
</Link>
|
| 146 |
+
</div>
|
| 147 |
+
</div>
|
| 148 |
+
</section>
|
| 149 |
+
</div>
|
| 150 |
+
);
|
| 151 |
+
}
|
all-file-converter/src/pages/Privacy.tsx
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useEffect } from "react";
|
| 2 |
+
import { updateSEO } from "../utils/seo";
|
| 3 |
+
import { ShieldCheck, EyeOff, Check, AlertCircle } from "lucide-react";
|
| 4 |
+
|
| 5 |
+
export default function Privacy() {
|
| 6 |
+
useEffect(() => {
|
| 7 |
+
updateSEO({
|
| 8 |
+
title: "Privacy Policy & HIPAA/GDPR Compliance | Lumina Convert",
|
| 9 |
+
description: "Read our rigorous 100% offline data privacy policies. We do not run cloud servers, track logs or utilize third-party trackers.",
|
| 10 |
+
keywords: "Lumina convert privacy policy, offline file processing security, GDPR converter compliance, HIPAA documents privacy",
|
| 11 |
+
});
|
| 12 |
+
}, []);
|
| 13 |
+
|
| 14 |
+
return (
|
| 15 |
+
<section className="py-12 bg-gradient-to-b from-[#FBFBFD] to-white min-h-screen text-left">
|
| 16 |
+
<div className="max-w-4xl mx-auto px-4 md:px-8 mt-12 pb-24">
|
| 17 |
+
{/* Badge */}
|
| 18 |
+
<div className="mb-6 flex justify-start">
|
| 19 |
+
<div className="inline-flex items-center space-x-2 bg-emerald-50 border border-emerald-100 px-3.5 py-1.5 rounded-full">
|
| 20 |
+
<ShieldCheck className="w-3.5 h-3.5 text-emerald-600" />
|
| 21 |
+
<span className="text-xs font-bold font-mono text-emerald-700 uppercase tracking-widest">
|
| 22 |
+
Lumina Compliance Registry
|
| 23 |
+
</span>
|
| 24 |
+
</div>
|
| 25 |
+
</div>
|
| 26 |
+
|
| 27 |
+
{/* Title */}
|
| 28 |
+
<h1 className="font-display text-3xl sm:text-4xl lg:text-5xl font-bold text-slate-900 tracking-tight leading-tight mb-8">
|
| 29 |
+
Data Privacy & <span className="text-emerald-600 font-semibold">Local Compliance</span>
|
| 30 |
+
</h1>
|
| 31 |
+
|
| 32 |
+
<div className="space-y-10 text-slate-600 text-sm md:text-base font-light leading-relaxed">
|
| 33 |
+
{/* Section 1 */}
|
| 34 |
+
<div className="space-y-3">
|
| 35 |
+
<h3 className="font-display font-bold text-lg text-slate-900 tracking-tight flex items-center gap-2">
|
| 36 |
+
<EyeOff className="w-5 h-5 text-emerald-500" />
|
| 37 |
+
<span>1. Zero-Cloud Guarantee</span>
|
| 38 |
+
</h3>
|
| 39 |
+
<p>
|
| 40 |
+
Lumina Convert was conceptualized to solve a critical security loophole in modern internet utilities: files being uploaded to unknown remote servers. Under our architectural framework, <strong>100% of encoding, decoding, and processing</strong> is compiled to run locally within your machine memory.
|
| 41 |
+
</p>
|
| 42 |
+
<p>
|
| 43 |
+
Your graphics core (GPU) and processor (CPU) handle the conversion cycles. No file bytes or parameters are ever sent to an external service.
|
| 44 |
+
</p>
|
| 45 |
+
</div>
|
| 46 |
+
|
| 47 |
+
{/* Section 2 */}
|
| 48 |
+
<div className="space-y-3">
|
| 49 |
+
<h3 className="font-display font-bold text-lg text-slate-900 tracking-tight flex items-center gap-2">
|
| 50 |
+
<ShieldCheck className="w-5 h-5 text-emerald-500" />
|
| 51 |
+
<span>2. HIPAA and GDPR Alignment</span>
|
| 52 |
+
</h3>
|
| 53 |
+
<p>
|
| 54 |
+
Because there is no network transit of uploaded files, corporate entities handling patient healthcare records, legal briefs, and intellectual properties do not need business associate agreements with Lumina Convert.
|
| 55 |
+
</p>
|
| 56 |
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 pt-2">
|
| 57 |
+
{[
|
| 58 |
+
{ title: "No Cloud DB Databases", desc: "No data is stored." },
|
| 59 |
+
{ title: "No Server Telemetry", desc: "No usage coordinates are fetched." },
|
| 60 |
+
{ title: "No Registration Gates", desc: "No email address databases." },
|
| 61 |
+
{ title: "No Cookie Trackers", desc: "Our web portal uses clean, cookie-less servers." }
|
| 62 |
+
].map((item, idx) => (
|
| 63 |
+
<div key={idx} className="flex gap-2 p-3 bg-slate-50 rounded-xl border border-slate-100">
|
| 64 |
+
<Check className="w-4 h-4 text-emerald-600 flex-shrink-0 mt-1" />
|
| 65 |
+
<div>
|
| 66 |
+
<h5 className="font-semibold text-slate-800 text-xs">{item.title}</h5>
|
| 67 |
+
<p className="text-slate-500 text-[11px] font-light mt-0.5">{item.desc}</p>
|
| 68 |
+
</div>
|
| 69 |
+
</div>
|
| 70 |
+
))}
|
| 71 |
+
</div>
|
| 72 |
+
</div>
|
| 73 |
+
|
| 74 |
+
{/* Section 3 */}
|
| 75 |
+
<div className="space-y-3">
|
| 76 |
+
<h3 className="font-display font-bold text-lg text-slate-900 tracking-tight flex items-center gap-2">
|
| 77 |
+
<AlertCircle className="w-5 h-5 text-emerald-500" />
|
| 78 |
+
<span>3. External Link Disclaimers</span>
|
| 79 |
+
</h3>
|
| 80 |
+
<p>
|
| 81 |
+
Our software links out to trusted affiliate domains (e.g. Amazaon Shopping program, Buy Me a Coffee) to help fund the development lifecycle. When you visit these resources, they operate under their own independent terms of service and tracker guidelines. We recommend reviewing these details.
|
| 82 |
+
</p>
|
| 83 |
+
</div>
|
| 84 |
+
|
| 85 |
+
{/* Section 4 */}
|
| 86 |
+
<div className="space-y-3">
|
| 87 |
+
<h3 className="font-display font-bold text-lg text-slate-900 tracking-tight flex items-center gap-2">
|
| 88 |
+
<span>4. Changes to This Protection Model</span>
|
| 89 |
+
</h3>
|
| 90 |
+
<p>
|
| 91 |
+
Our privacy commitment is locked. We will never introduce automatic remote logging updates or telemetry files to our converter without listing clear toggles first. Any security changes will be published in this portal.
|
| 92 |
+
</p>
|
| 93 |
+
</div>
|
| 94 |
+
</div>
|
| 95 |
+
</div>
|
| 96 |
+
</section>
|
| 97 |
+
);
|
| 98 |
+
}
|
all-file-converter/src/pages/Support.tsx
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useEffect } from "react";
|
| 2 |
+
import { updateSEO } from "../utils/seo";
|
| 3 |
+
import { Heart, Coffee, ShoppingBag, Globe, Share2, HelpCircle } from "lucide-react";
|
| 4 |
+
|
| 5 |
+
export default function Support() {
|
| 6 |
+
useEffect(() => {
|
| 7 |
+
updateSEO({
|
| 8 |
+
title: "Support Our Platform & Affiliate Program | Lumina Convert",
|
| 9 |
+
description: "Support Lumina Convert developers. 100% free offline file processing has real development and maintenance costs. Explore affiliate links or buy us a coffee.",
|
| 10 |
+
keywords: "support Lumina convert, buy me a coffee bahaduralimunnabhai, amazon affiliate search portal, offline tools developer helper",
|
| 11 |
+
});
|
| 12 |
+
}, []);
|
| 13 |
+
|
| 14 |
+
return (
|
| 15 |
+
<section className="py-12 bg-gradient-to-b from-[#FBFBFD] to-[#FAF9FE] min-h-screen">
|
| 16 |
+
<div className="max-w-4xl mx-auto px-4 md:px-8 mt-12 pb-24 text-left">
|
| 17 |
+
{/* Badge */}
|
| 18 |
+
<div className="mb-6 flex justify-center lg:justify-start">
|
| 19 |
+
<div className="inline-flex items-center space-x-2 bg-amber-50 border border-amber-100 px-3.5 py-1.5 rounded-full">
|
| 20 |
+
<Heart className="w-3.5 h-3.5 text-amber-500 fill-amber-500" />
|
| 21 |
+
<span className="text-xs font-bold font-mono text-amber-700 uppercase tracking-widest">
|
| 22 |
+
Lumina Generosity Fund
|
| 23 |
+
</span>
|
| 24 |
+
</div>
|
| 25 |
+
</div>
|
| 26 |
+
|
| 27 |
+
{/* Title */}
|
| 28 |
+
<h1 className="font-display text-3xl sm:text-4xl lg:text-5xl font-bold text-slate-900 tracking-tight leading-tight mb-5 text-center lg:text-left">
|
| 29 |
+
Support the Future of{" "}
|
| 30 |
+
<span className="bg-gradient-to-r from-amber-500 to-rose-500 bg-clip-text text-transparent font-extrabold">
|
| 31 |
+
Secure Software
|
| 32 |
+
</span>
|
| 33 |
+
</h1>
|
| 34 |
+
<p className="text-slate-600 text-base md:text-lg font-light max-w-3xl mb-12 text-center lg:text-left">
|
| 35 |
+
Lumina Convert remains 100% free with absolutely no hidden locked upgrades, subscription limits, or advertisements. If this tool saves you time, consider helping us cover local device dev licenses, server storage, and support channels.
|
| 36 |
+
</p>
|
| 37 |
+
|
| 38 |
+
{/* Support Grid */}
|
| 39 |
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 mb-16">
|
| 40 |
+
{/* Card 1: BMC */}
|
| 41 |
+
<div className="bg-white p-8 rounded-3xl border border-slate-100 shadow-md shadow-slate-100/10 flex flex-col justify-between text-left">
|
| 42 |
+
<div>
|
| 43 |
+
<div className="w-12 h-12 rounded-2xl bg-amber-50 text-amber-500 border border-amber-100 flex items-center justify-center shadow-sm mb-6">
|
| 44 |
+
<Coffee className="w-5 h-5" />
|
| 45 |
+
</div>
|
| 46 |
+
<h3 className="font-display font-bold text-lg md:text-xl text-slate-900 tracking-tight mb-2">Buy Me a Coffee</h3>
|
| 47 |
+
<p className="text-slate-500 text-xs md:text-sm font-light leading-relaxed mb-6">
|
| 48 |
+
Direct tips help maintain and compile our server builds. Send direct coffee currency tokens via Buy Me a Coffee.
|
| 49 |
+
</p>
|
| 50 |
+
</div>
|
| 51 |
+
<a
|
| 52 |
+
href="https://www.buymeacoffee.com/bahaduralimunnabhai"
|
| 53 |
+
target="_blank"
|
| 54 |
+
rel="noopener noreferrer"
|
| 55 |
+
className="w-full py-3 rounded-xl bg-amber-500 hover:bg-amber-600 transition text-white text-xs font-semibold text-center block"
|
| 56 |
+
>
|
| 57 |
+
Support via Buy Me a Coffee
|
| 58 |
+
</a>
|
| 59 |
+
</div>
|
| 60 |
+
|
| 61 |
+
{/* Card 2: Amazon / Shop */}
|
| 62 |
+
<div className="bg-white p-8 rounded-3xl border border-slate-100 shadow-md shadow-slate-100/10 flex flex-col justify-between text-left">
|
| 63 |
+
<div>
|
| 64 |
+
<div className="w-12 h-12 rounded-2xl bg-indigo-50 text-indigo-600 border border-indigo-100 flex items-center justify-center shadow-sm mb-6">
|
| 65 |
+
<ShoppingBag className="w-5 h-5" />
|
| 66 |
+
</div>
|
| 67 |
+
<h3 className="font-display font-bold text-lg md:text-xl text-slate-900 tracking-tight mb-2">Amazon Shopping Portal</h3>
|
| 68 |
+
<p className="text-slate-500 text-xs md:text-sm font-light leading-relaxed mb-6">
|
| 69 |
+
Shop on Amazon using our verified affiliate gateway at no additional cost to you. We earn a small, helpful commission on your orders.
|
| 70 |
+
</p>
|
| 71 |
+
</div>
|
| 72 |
+
<a
|
| 73 |
+
href="https://amzn.to/3Zg7ZcQ"
|
| 74 |
+
target="_blank"
|
| 75 |
+
rel="noopener noreferrer"
|
| 76 |
+
className="w-full py-3 rounded-xl bg-violet-600 hover:bg-violet-700 transition text-white text-xs font-semibold text-center block"
|
| 77 |
+
>
|
| 78 |
+
Shop via Affiliate Link
|
| 79 |
+
</a>
|
| 80 |
+
</div>
|
| 81 |
+
</div>
|
| 82 |
+
|
| 83 |
+
{/* Affiliate Disclosure Compliance Box */}
|
| 84 |
+
<div className="p-6 bg-slate-50 rounded-2xl border border-slate-205 text-slate-500 text-xs font-light leading-relaxed relative overflow-hidden">
|
| 85 |
+
<div className="flex items-center gap-2 mb-2 font-semibold text-slate-700">
|
| 86 |
+
<HelpCircle className="w-4 h-4 text-slate-400" />
|
| 87 |
+
<span>Affiliate Disclosure & Transparency</span>
|
| 88 |
+
</div>
|
| 89 |
+
<p>
|
| 90 |
+
Lumina Convert, in full conformity with regulatory fair-use frameworks and consumer integrity acts, declares that we participate in the Amazon Services LLC Associates Program. Clicking on our affiliate links contributes a small percentage of your normal shopping basket cost to our direct developer resources without modifying any prices on your products.
|
| 91 |
+
</p>
|
| 92 |
+
</div>
|
| 93 |
+
</div>
|
| 94 |
+
</section>
|
| 95 |
+
);
|
| 96 |
+
}
|
all-file-converter/src/types.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export interface FeatureItem {
|
| 2 |
+
id: string;
|
| 3 |
+
title: string;
|
| 4 |
+
description: string;
|
| 5 |
+
iconName: string;
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
export interface TestimonialItem {
|
| 9 |
+
id: string;
|
| 10 |
+
name: string;
|
| 11 |
+
role: string;
|
| 12 |
+
feedback: string;
|
| 13 |
+
avatarUrl?: string;
|
| 14 |
+
rating: number;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
export interface PricingPlan {
|
| 18 |
+
id: string;
|
| 19 |
+
name: string;
|
| 20 |
+
price: string;
|
| 21 |
+
period: string;
|
| 22 |
+
description: string;
|
| 23 |
+
features: string[];
|
| 24 |
+
isPopular?: boolean;
|
| 25 |
+
ctaText: string;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
export interface FAQItem {
|
| 29 |
+
id: string;
|
| 30 |
+
question: string;
|
| 31 |
+
answer: string;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
export interface ConversionFormat {
|
| 35 |
+
extension: string;
|
| 36 |
+
category: "document" | "image" | "video" | "audio";
|
| 37 |
+
mimeType: string;
|
| 38 |
+
}
|
all-file-converter/src/utils/seo.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Premium SEO Dynamic Header and Schema Manager
|
| 3 |
+
* Enhances search engine indexing, click-through rates, and Google ranking signals.
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
export interface SEOConfig {
|
| 7 |
+
title: string;
|
| 8 |
+
description: string;
|
| 9 |
+
keywords: string;
|
| 10 |
+
schema?: string;
|
| 11 |
+
canonicalUrl?: string;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
export function updateSEO({ title, description, keywords, schema, canonicalUrl }: SEOConfig) {
|
| 15 |
+
// Update document title
|
| 16 |
+
document.title = title;
|
| 17 |
+
|
| 18 |
+
// Update or create Meta Description
|
| 19 |
+
let metaDesc = document.querySelector('meta[name="description"]');
|
| 20 |
+
if (!metaDesc) {
|
| 21 |
+
metaDesc = document.createElement("meta");
|
| 22 |
+
metaDesc.setAttribute("name", "description");
|
| 23 |
+
document.head.appendChild(metaDesc);
|
| 24 |
+
}
|
| 25 |
+
metaDesc.setAttribute("content", description);
|
| 26 |
+
|
| 27 |
+
// Update or create Meta Keywords
|
| 28 |
+
let metaKeywords = document.querySelector('meta[name="keywords"]');
|
| 29 |
+
if (!metaKeywords) {
|
| 30 |
+
metaKeywords = document.createElement("meta");
|
| 31 |
+
metaKeywords.setAttribute("name", "keywords");
|
| 32 |
+
document.head.appendChild(metaKeywords);
|
| 33 |
+
}
|
| 34 |
+
metaKeywords.setAttribute("content", keywords);
|
| 35 |
+
|
| 36 |
+
// Open Graph Facebook/LinkedIn tags
|
| 37 |
+
let ogTitle = document.querySelector('meta[property="og:title"]');
|
| 38 |
+
if (!ogTitle) {
|
| 39 |
+
ogTitle = document.createElement("meta");
|
| 40 |
+
ogTitle.setAttribute("property", "og:title");
|
| 41 |
+
document.head.appendChild(ogTitle);
|
| 42 |
+
}
|
| 43 |
+
ogTitle.setAttribute("content", title);
|
| 44 |
+
|
| 45 |
+
let ogDesc = document.querySelector('meta[property="og:description"]');
|
| 46 |
+
if (!ogDesc) {
|
| 47 |
+
ogDesc = document.createElement("meta");
|
| 48 |
+
ogDesc.setAttribute("property", "og:description");
|
| 49 |
+
document.head.appendChild(ogDesc);
|
| 50 |
+
}
|
| 51 |
+
ogDesc.setAttribute("content", description);
|
| 52 |
+
|
| 53 |
+
// Canonical URL Link
|
| 54 |
+
const fullUrl = canonicalUrl || window.location.href;
|
| 55 |
+
let linkCanonical = document.querySelector('link[rel="canonical"]');
|
| 56 |
+
if (!linkCanonical) {
|
| 57 |
+
linkCanonical = document.createElement("link");
|
| 58 |
+
linkCanonical.setAttribute("rel", "canonical");
|
| 59 |
+
document.head.appendChild(linkCanonical);
|
| 60 |
+
}
|
| 61 |
+
linkCanonical.setAttribute("href", fullUrl);
|
| 62 |
+
|
| 63 |
+
// Structured Data Schema markup for rich snippet display
|
| 64 |
+
let schemaScript = document.getElementById("lumina-structured-data");
|
| 65 |
+
if (schemaScript) {
|
| 66 |
+
schemaScript.remove();
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
if (schema) {
|
| 70 |
+
schemaScript = document.createElement("script");
|
| 71 |
+
schemaScript.id = "lumina-structured-data";
|
| 72 |
+
schemaScript.setAttribute("type", "application/ld+json");
|
| 73 |
+
schemaScript.innerHTML = schema;
|
| 74 |
+
document.head.appendChild(schemaScript);
|
| 75 |
+
}
|
| 76 |
+
}
|
all-file-converter/tsconfig.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"compilerOptions": {
|
| 3 |
+
"target": "ES2022",
|
| 4 |
+
"experimentalDecorators": true,
|
| 5 |
+
"useDefineForClassFields": false,
|
| 6 |
+
"module": "ESNext",
|
| 7 |
+
"lib": [
|
| 8 |
+
"ES2022",
|
| 9 |
+
"DOM",
|
| 10 |
+
"DOM.Iterable"
|
| 11 |
+
],
|
| 12 |
+
"skipLibCheck": true,
|
| 13 |
+
"moduleResolution": "bundler",
|
| 14 |
+
"isolatedModules": true,
|
| 15 |
+
"moduleDetection": "force",
|
| 16 |
+
"allowJs": true,
|
| 17 |
+
"jsx": "react-jsx",
|
| 18 |
+
"paths": {
|
| 19 |
+
"@/*": [
|
| 20 |
+
"./*"
|
| 21 |
+
]
|
| 22 |
+
},
|
| 23 |
+
"allowImportingTsExtensions": true,
|
| 24 |
+
"noEmit": true
|
| 25 |
+
}
|
| 26 |
+
}
|
all-file-converter/vite.config.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import tailwindcss from '@tailwindcss/vite';
|
| 2 |
+
import react from '@vitejs/plugin-react';
|
| 3 |
+
import path from 'path';
|
| 4 |
+
import {defineConfig} from 'vite';
|
| 5 |
+
|
| 6 |
+
export default defineConfig(() => {
|
| 7 |
+
return {
|
| 8 |
+
plugins: [react(), tailwindcss()],
|
| 9 |
+
resolve: {
|
| 10 |
+
alias: {
|
| 11 |
+
'@': path.resolve(__dirname, '.'),
|
| 12 |
+
},
|
| 13 |
+
},
|
| 14 |
+
server: {
|
| 15 |
+
// HMR is disabled in AI Studio via DISABLE_HMR env var.
|
| 16 |
+
// Do not modifyâfile watching is disabled to prevent flickering during agent edits.
|
| 17 |
+
hmr: process.env.DISABLE_HMR !== 'true',
|
| 18 |
+
// Disable file watching when DISABLE_HMR is true to save CPU during agent edits.
|
| 19 |
+
watch: process.env.DISABLE_HMR === 'true' ? null : {},
|
| 20 |
+
},
|
| 21 |
+
};
|
| 22 |
+
});
|
build/AIFileConverter/AIFileConverter.pkg
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:20cb9a2ddfab505cf42110464cd4626a0dc703ef8663982a845e008d4945f1d9
|
| 3 |
+
size 434225281
|
build/AIFileConverter/Analysis-00.toc
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
build/AIFileConverter/EXE-00.toc
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
build/AIFileConverter/PKG-00.toc
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
build/AIFileConverter/PYZ-00.pyz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0c5ae32f8381bc21e941e654b873eb8396fbf48769bfd24d940baa8e98f04568
|
| 3 |
+
size 74379742
|
build/AIFileConverter/PYZ-00.toc
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
build/AIFileConverter/base_library.zip
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a318ddf625934c407b64190c9e4cf567a3fb131bbb745e2a93b009742fb9a245
|
| 3 |
+
size 1333651
|
build/AIFileConverter/localpycs/pyimod01_archive.pyc
ADDED
|
Binary file (4.86 kB). View file
|
|
|
build/AIFileConverter/localpycs/pyimod02_importers.pyc
ADDED
|
Binary file (32.2 kB). View file
|
|
|
build/AIFileConverter/localpycs/pyimod03_ctypes.pyc
ADDED
|
Binary file (6.15 kB). View file
|
|
|