🛠 refactor(wipe): all the repo code
3
.github/CODEOWNERS
vendored
@@ -1,3 +0,0 @@
|
|||||||
@eshanized
|
|
||||||
@alokify
|
|
||||||
@utkgaur1
|
|
69
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -1,69 +0,0 @@
|
|||||||
name: "\U0001F41B Bug Report"
|
|
||||||
description: Report an issue or possible bug
|
|
||||||
labels: []
|
|
||||||
assignees: []
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Thank you for taking the time to file a bug report! Please fill out this form as completely as possible.
|
|
||||||
|
|
||||||
✅ I am using the **latest versions of Starlight and Astro**.
|
|
||||||
✅ I am using a version of Node that supports ESM (`v14.18.0+`, or `v16.12.0+`).
|
|
||||||
- type: input
|
|
||||||
id: starlight-version
|
|
||||||
attributes:
|
|
||||||
label: What version of `starlight` are you using?
|
|
||||||
placeholder: 0.0.0
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: input
|
|
||||||
id: astro-version
|
|
||||||
attributes:
|
|
||||||
label: What version of `astro` are you using?
|
|
||||||
placeholder: 0.0.0
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: input
|
|
||||||
id: package-manager
|
|
||||||
attributes:
|
|
||||||
label: What package manager are you using?
|
|
||||||
placeholder: npm, yarn, pnpm
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: input
|
|
||||||
id: os
|
|
||||||
attributes:
|
|
||||||
label: What operating system are you using?
|
|
||||||
placeholder: Mac, Windows, Linux
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: input
|
|
||||||
id: browser
|
|
||||||
attributes:
|
|
||||||
label: What browser are you using?
|
|
||||||
placeholder: Chrome, Firefox, Safari
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
id: bug-description
|
|
||||||
attributes:
|
|
||||||
label: Describe the Bug
|
|
||||||
description: A clear and concise description of what the bug is.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: input
|
|
||||||
id: bug-reproduction
|
|
||||||
attributes:
|
|
||||||
label: Link to Minimal Reproducible Example
|
|
||||||
description: 'Use [astro.new](https://astro.new) to create a minimal reproduction of the problem. **A minimal reproduction is required** so that others can help debug your issue. If a report is vague (e.g. just a generic error message) and has no reproduction, it may be auto-closed. Not sure how to create a minimal example? [Read our guide](https://docs.astro.build/en/guides/troubleshooting/#creating-minimal-reproductions)'
|
|
||||||
placeholder: 'https://stackblitz.com/abcd1234'
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: checkboxes
|
|
||||||
id: will-pr
|
|
||||||
attributes:
|
|
||||||
label: Participation
|
|
||||||
options:
|
|
||||||
- label: I am willing to submit a pull request for this issue.
|
|
||||||
required: false
|
|
38
.github/workflows/cz.yml
vendored
@@ -1,38 +0,0 @@
|
|||||||
name: Check Conventional Commit
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check-commit-message:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Check Conventional Commit
|
|
||||||
run: |
|
|
||||||
# Define the conventional commit types with emojis
|
|
||||||
TYPES=("🚀 feat" "🐛 fix" "📝 docs" "✨ style" "🛠 refactor" "⚡️ perf" "🔬 test" "🔧 build" "🤖 ci" "🧹 chore" "⏪ revert")
|
|
||||||
|
|
||||||
# Extract the commit type and emoji from the commit message
|
|
||||||
COMMIT_MSG=$(git log --format=%B -n 1)
|
|
||||||
for type in "${TYPES[@]}"; do
|
|
||||||
type_emoji=${type}
|
|
||||||
type=${type_emoji#* }
|
|
||||||
emoji=${type_emoji% *}
|
|
||||||
if [[ $COMMIT_MSG == $emoji* ]]; then
|
|
||||||
echo "Commit message is a conventional commit"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# If we reach here, the commit message is not a conventional commit
|
|
||||||
echo "Commit message is not a conventional commit"
|
|
||||||
exit 1
|
|
24
.gitignore
vendored
@@ -1,24 +0,0 @@
|
|||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
/node_modules
|
|
||||||
dist
|
|
||||||
dist-ssr
|
|
||||||
*.local
|
|
||||||
|
|
||||||
# Editor directories and files
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/extensions.json
|
|
||||||
.idea
|
|
||||||
.DS_Store
|
|
||||||
*.suo
|
|
||||||
*.ntvs*
|
|
||||||
*.njsproj
|
|
||||||
*.sln
|
|
||||||
*.sw?
|
|
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 797 B |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 88 KiB |
Before Width: | Height: | Size: 88 KiB |
@@ -1,28 +0,0 @@
|
|||||||
import js from '@eslint/js';
|
|
||||||
import globals from 'globals';
|
|
||||||
import reactHooks from 'eslint-plugin-react-hooks';
|
|
||||||
import reactRefresh from 'eslint-plugin-react-refresh';
|
|
||||||
import tseslint from 'typescript-eslint';
|
|
||||||
|
|
||||||
export default tseslint.config(
|
|
||||||
{ ignores: ['dist'] },
|
|
||||||
{
|
|
||||||
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
|
||||||
files: ['**/*.{ts,tsx}'],
|
|
||||||
languageOptions: {
|
|
||||||
ecmaVersion: 2020,
|
|
||||||
globals: globals.browser,
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
'react-hooks': reactHooks,
|
|
||||||
'react-refresh': reactRefresh,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
...reactHooks.configs.recommended.rules,
|
|
||||||
'react-refresh/only-export-components': [
|
|
||||||
'warn',
|
|
||||||
{ allowConstantExport: true },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
115
index.html
@@ -1,115 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<!-- Favicon: A small icon displayed in the browser tab -->
|
|
||||||
<link rel="icon" href="https://snigdha-os.github.io/assets/images/favicon.ico" type="image/x-icon" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
|
|
||||||
<!-- Title of the Website: This appears in the browser tab and search results -->
|
|
||||||
<title>SNIGDHA OS | Arch-based Linux Distribution for Penetration Testing and Ethical Hacking</title>
|
|
||||||
|
|
||||||
<!-- Meta Description: A brief summary of your website's content for search engines and social media. -->
|
|
||||||
<meta
|
|
||||||
name="description"
|
|
||||||
content="SNIGDHA OS is a fast, secure, and elegant GNU/Linux desktop distribution designed for modern users. Perfect for developers, creators, and enthusiasts, especially for penetration testing and ethical hacking."
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Open Graph / Facebook Tags -->
|
|
||||||
<meta property="og:type" content="website" />
|
|
||||||
<meta property="og:title" content="SNIGDHA OS | Arch-based Linux Distribution for Penetration Testing and Ethical Hacking" />
|
|
||||||
<meta
|
|
||||||
property="og:description"
|
|
||||||
content="SNIGDHA OS is a fast, secure, and elegant GNU/Linux desktop distribution designed for modern users. Perfect for developers, creators, and enthusiasts, especially for penetration testing and ethical hacking."
|
|
||||||
/>
|
|
||||||
<meta property="og:url" content="https://snigdha-os.github.io/" />
|
|
||||||
<meta property="og:image" content="https://snigdha-os.github.io/assets/images/og-image.png" />
|
|
||||||
<meta property="og:site_name" content="SNIGDHA OS" />
|
|
||||||
|
|
||||||
<!-- Twitter Card Tags -->
|
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
|
||||||
<meta name="twitter:title" content="SNIGDHA OS | Arch-based Linux Distribution for Penetration Testing and Ethical Hacking" />
|
|
||||||
<meta
|
|
||||||
name="twitter:description"
|
|
||||||
content="SNIGDHA OS is a fast, secure, and elegant GNU/Linux desktop distribution designed for modern users. Perfect for developers, creators, and enthusiasts, especially for penetration testing and ethical hacking."
|
|
||||||
/>
|
|
||||||
<meta name="twitter:image" content="https://snigdha-os.github.io/assets/images/twitter-image.png" />
|
|
||||||
<meta name="twitter:creator" content="@snigdhaos" />
|
|
||||||
|
|
||||||
<!-- Author Meta Tag -->
|
|
||||||
<meta name="author" content="Snigdha OS Team" />
|
|
||||||
|
|
||||||
<!-- Theme Color -->
|
|
||||||
<meta name="theme-color" content="#6495ed" />
|
|
||||||
|
|
||||||
<!-- Keywords for SEO -->
|
|
||||||
<meta
|
|
||||||
name="keywords"
|
|
||||||
content="Linux, Linux Distribution, Snigdha OS, Arch Linux, Penetration Testing, Ethical Hacking, Security, Open Source, Operating System, Desktop Environment, Linux for Developers, Cybersecurity"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Robots Meta Tag -->
|
|
||||||
<meta name="robots" content="index, follow" />
|
|
||||||
|
|
||||||
<!-- Canonical URL -->
|
|
||||||
<link rel="canonical" href="https://snigdha-os.github.io/" />
|
|
||||||
|
|
||||||
<!-- Apple Touch Icon -->
|
|
||||||
<link rel="apple-touch-icon" href="https://snigdha-os.github.io/apple-touch-icon.png">
|
|
||||||
|
|
||||||
<!-- Apple Startup Image -->
|
|
||||||
<link rel="apple-touch-startup-image" href="https://snigdha-os.github.io/apple-startup-image.png">
|
|
||||||
|
|
||||||
<!-- Structured Data (JSON-LD) -->
|
|
||||||
<script type="application/ld+json">
|
|
||||||
{
|
|
||||||
"@context": "http://schema.org",
|
|
||||||
"@type": "Organization",
|
|
||||||
"name": "Snigdha OS",
|
|
||||||
"url": "https://snigdha-os.github.io/",
|
|
||||||
"logo": "https://snigdha-os.github.io/logo.png",
|
|
||||||
"contactPoint": {
|
|
||||||
"@type": "ContactPoint",
|
|
||||||
"contactType": "Customer Support",
|
|
||||||
"areaServed": "Worldwide",
|
|
||||||
"availableLanguage": "English"
|
|
||||||
},
|
|
||||||
"sameAs": [
|
|
||||||
"https://www.facebook.com/Snigdha-OS",
|
|
||||||
"https://twitter.com/SnigdhaOS",
|
|
||||||
"https://github.com/Snigdha-OS"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Google Analytics Script -->
|
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=GTM-5HXGM54C"></script>
|
|
||||||
<script>
|
|
||||||
window.dataLayer = window.dataLayer || [];
|
|
||||||
function gtag(){dataLayer.push(arguments);}
|
|
||||||
gtag('js', new Date());
|
|
||||||
gtag('config', 'GTM-5HXGM54C');
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
(function(l) {
|
|
||||||
if (l.search[1] === '/' ) {
|
|
||||||
var decoded = l.search.slice(1).split('&').map(function(s) {
|
|
||||||
return s.replace(/~and~/g, '&')
|
|
||||||
}).join('?');
|
|
||||||
window.history.replaceState(null, null,
|
|
||||||
l.pathname.slice(0, -1) + decoded + l.hash
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}(window.location))
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- Main content of the website will be rendered here by React -->
|
|
||||||
<div id="root"></div>
|
|
||||||
|
|
||||||
<!-- Entry point for the React app -->
|
|
||||||
<script type="module" src="/src/main.tsx"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
57
package.json
@@ -1,57 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "snigdhaos-web-dev",
|
|
||||||
"private": true,
|
|
||||||
"version": "1.0.0",
|
|
||||||
"type": "module",
|
|
||||||
"homepage": "https://Snigdha-OS.github.io/",
|
|
||||||
"description": "Official website source code for Snigdha OS, a lightweight Arch-based Linux distribution.",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "vite",
|
|
||||||
"build": "vite build",
|
|
||||||
"lint": "eslint .",
|
|
||||||
"preview": "vite preview",
|
|
||||||
"deploy": "npm run build && gh-pages -d dist"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"axios": "^1.7.9",
|
|
||||||
"lucide-react": "^0.344.0",
|
|
||||||
"octokit": "^3.2.1",
|
|
||||||
"react": "^18.3.1",
|
|
||||||
"react-dom": "^18.3.1",
|
|
||||||
"react-icons": "^5.4.0",
|
|
||||||
"react-router-dom": "^6.28.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@eslint/js": "^9.17.0",
|
|
||||||
"@types/react": "^18.3.18",
|
|
||||||
"@types/react-dom": "^18.3.5",
|
|
||||||
"@vitejs/plugin-react": "^4.3.4",
|
|
||||||
"autoprefixer": "^10.4.20",
|
|
||||||
"eslint": "^9.17.0",
|
|
||||||
"eslint-plugin-react-hooks": "^5.1.0",
|
|
||||||
"eslint-plugin-react-refresh": "^0.4.16",
|
|
||||||
"gh-pages": "^5.0.0",
|
|
||||||
"globals": "^15.14.0",
|
|
||||||
"postcss": "^8.4.49",
|
|
||||||
"prettier": "3.4.2",
|
|
||||||
"tailwindcss": "^3.4.17",
|
|
||||||
"typescript": "^5.7.2",
|
|
||||||
"typescript-eslint": "^8.18.2",
|
|
||||||
"vite": "^5.4.11",
|
|
||||||
"vite-plugin-sitemap": "^0.7.1"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/Snigdha-OS/snigdhaos-web-dev.git"
|
|
||||||
},
|
|
||||||
"author": "Snigdha OS Team",
|
|
||||||
"license": "MIT",
|
|
||||||
"keywords": [
|
|
||||||
"Snigdha OS",
|
|
||||||
"Linux",
|
|
||||||
"React",
|
|
||||||
"Vite",
|
|
||||||
"Arch Linux",
|
|
||||||
"Website"
|
|
||||||
]
|
|
||||||
}
|
|
3428
pnpm-lock.yaml
generated
@@ -1,13 +0,0 @@
|
|||||||
export default {
|
|
||||||
plugins: {
|
|
||||||
tailwindcss: {},
|
|
||||||
autoprefixer: {},
|
|
||||||
...(process.env.NODE_ENV === 'production'
|
|
||||||
? {
|
|
||||||
// cssnano: {
|
|
||||||
// preset: 'default',
|
|
||||||
// },
|
|
||||||
}
|
|
||||||
: {}),
|
|
||||||
},
|
|
||||||
};
|
|
124
public/404.html
@@ -1,124 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
||||||
<title>404 - Page Not Found</title>
|
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: 'Poppins', sans-serif;
|
|
||||||
background: #f7f7f7;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
height: 100vh;
|
|
||||||
color: #333;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 600px;
|
|
||||||
padding: 40px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 12px;
|
|
||||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
|
|
||||||
animation: fadeIn 1s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 7rem;
|
|
||||||
color: #ff6347;
|
|
||||||
font-weight: 700;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
animation: bounceIn 1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 2rem;
|
|
||||||
color: #555;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
color: #888;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-home {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 14px 30px;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
background-color: #ff6347;
|
|
||||||
color: #fff;
|
|
||||||
text-decoration: none;
|
|
||||||
border-radius: 8px;
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-home:hover {
|
|
||||||
background-color: #e5533d;
|
|
||||||
transform: translateY(-2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
font-size: 0.9rem;
|
|
||||||
color: #aaa;
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes bounceIn {
|
|
||||||
0% {
|
|
||||||
transform: scale(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: scale(1.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<h1>404</h1>
|
|
||||||
<h2>Oops! The page you're looking for doesn't exist.</h2>
|
|
||||||
<p class="message">We couldn't find the page you're looking for. But don't worry, you can go back to the home page.</p>
|
|
||||||
<a href="/" class="btn-home">Go Back to Home</a>
|
|
||||||
<div class="footer">
|
|
||||||
<p>Snigdha OS | 2024</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Redirect to the root index.html page after a slight delay
|
|
||||||
setTimeout(function() {
|
|
||||||
window.location.replace("/");
|
|
||||||
}, 5000); // Redirect after 5 seconds
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@@ -1 +0,0 @@
|
|||||||
/* /index.html 200
|
|
Before Width: | Height: | Size: 15 KiB |
@@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256">
|
|
||||||
<title>Snigdha OS Favicon</title>
|
|
||||||
<style>
|
|
||||||
.s0 { fill: #6495ed }
|
|
||||||
</style>
|
|
||||||
<path id="Path 7" fill-rule="evenodd" class="s0" d="m112.8 111.5q25.7 27 1.7 53.9-21.4 20.9-41.9 22.9c8.6-7.4 11-19.8 5.8-29.9q-26.1-27.2-39.2-47.7-15.1-39.6 40.9-53.8 9.4-15.5 91.4-55.6c15.4-4.4 31.8 2.8 38.9 17.2 7 14.4 2.8 31.8-10.2 41.3l-112.8 7.1q-1.9 20.7 25.4 44.6zm-35.5-43.4c-11.4 3.4-26.3 9.6-30.2 20.4-2 5.8-0.9 12.1 1.1 17.7 10.5 16.1 24.2 31.5 37.5 45.3l1 1.1 0.7 1.3c2.8 5.5 4 11.5 3.7 17.4 6-3.7 11.4-8.2 16.2-12.8 12.4-14.2 11.3-26.2-1.5-39.8-14.4-12.7-29.3-30.2-28.5-50.6zm124.1-45.1c-4.8-9.8-15.8-14.9-26.4-12.3-20.9 10.3-42.3 21.1-62.1 33.2-3.7 2.2-12.5 7.7-18.6 12.5l102.1-6.4c7.4-6.8 9.5-17.8 5-27z"/>
|
|
||||||
<path id="Path 8" fill-rule="evenodd" class="s0" d="m143.8 144.3q-25.7-26.9-1.8-53.9 21.5-20.8 42-22.8c-8.6 7.4-11 19.7-5.9 29.8q26.2 27.2 39.3 47.8 15 39.6-40.9 53.7-9.4 15.5-91.5 55.7c-15.4 4.4-31.7-2.9-38.8-17.3-7-14.4-2.8-31.7 10.1-41.3l112.8-7.1q2-20.7-25.3-44.6zm35.5 43.5c11.4-3.4 26.3-9.6 30.2-20.5 2-5.7 0.9-12-1.2-17.6-10.4-16.1-24.2-31.5-37.4-45.4l-1.1-1-0.6-1.3c-2.8-5.5-4-11.5-3.8-17.4-5.9 3.6-11.4 8.2-16.1 12.8-12.5 14.1-11.3 26.2 1.4 39.7 14.5 12.7 29.4 30.3 28.6 50.7zm-124.1 45.1c4.8 9.7 15.8 14.8 26.3 12.2 20.9-10.2 42.3-21 62.2-33.1 3.7-2.2 12.5-7.7 18.5-12.6l-102 6.5c-7.4 6.8-9.5 17.8-5 27z"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.4 KiB |
25
src/App.tsx
@@ -1,25 +0,0 @@
|
|||||||
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
|
|
||||||
import { Layout } from './components/layout/Layout';
|
|
||||||
import { Home } from './pages/Home';
|
|
||||||
import { About } from './pages/About';
|
|
||||||
import { DownloadPage } from './pages/Download';
|
|
||||||
import { Donors } from './pages/Donors';
|
|
||||||
import { Maintainers } from './pages/Maintainers';
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
return (
|
|
||||||
<Router basename="/">
|
|
||||||
<Layout>
|
|
||||||
<Routes>
|
|
||||||
<Route path="/" element={<Home />} />
|
|
||||||
<Route path="/about" element={<About />} />
|
|
||||||
<Route path="/download" element={<DownloadPage />} />
|
|
||||||
<Route path="/donors" element={<Donors />} />
|
|
||||||
<Route path="/maintainers" element={<Maintainers />} />
|
|
||||||
</Routes>
|
|
||||||
</Layout>
|
|
||||||
</Router>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App;
|
|
@@ -1,191 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { Github } from 'lucide-react'; // Importing the 'Github' icon from the 'lucide-react' library
|
|
||||||
|
|
||||||
// Define and export the Footer functional component
|
|
||||||
export function Footer() {
|
|
||||||
// Declare a state variable `githubFollowers` to store the number of GitHub followers.
|
|
||||||
// The initial value is set to `null`. The `setGithubFollowers` function is used to update this value.
|
|
||||||
const [githubFollowers, setGithubFollowers] = useState<number | null>(null);
|
|
||||||
|
|
||||||
// useEffect hook is used to run side effects. Here, it runs the effect to fetch GitHub follower count.
|
|
||||||
useEffect(() => {
|
|
||||||
// Define an asynchronous function to fetch data from the GitHub API.
|
|
||||||
async function fetchGithubFollowers() {
|
|
||||||
// Make a GET request to GitHub API for the user 'Snigdha-OS'.
|
|
||||||
const response = await fetch('https://api.github.com/users/Snigdha-OS');
|
|
||||||
|
|
||||||
// Parse the response JSON to extract the data.
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
// Check if the `followers` property exists in the fetched data.
|
|
||||||
if (data.followers !== undefined) {
|
|
||||||
// Update the state with the number of followers.
|
|
||||||
setGithubFollowers(data.followers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the `fetchGithubFollowers` function to fetch the data.
|
|
||||||
fetchGithubFollowers();
|
|
||||||
}, []); // Empty dependency array means this effect runs only once after the component mounts.
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<footer className="relative bg-[#1a202c] text-white py-16 overflow-hidden">
|
|
||||||
{/* Background Bubble Animation */}
|
|
||||||
<div className="absolute inset-0 pointer-events-none z-0">
|
|
||||||
<div className="bubble-container"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="container mx-auto px-6 relative z-10">
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-10">
|
|
||||||
{/* Snigdha OS Section */}
|
|
||||||
<div>
|
|
||||||
<h3 className="font-bold text-xl mb-6 text-[#6495ED]">Snigdha OS</h3>
|
|
||||||
<p className="text-sm text-gray-400 leading-relaxed">
|
|
||||||
Arch-based Linux Distribution for Penetration Testing and Ethical Hacking! Experience power and simplicity
|
|
||||||
like never before.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Quick Links */}
|
|
||||||
<div>
|
|
||||||
<h3 className="font-bold text-xl mb-6 text-[#6495ED]">Quick Links</h3>
|
|
||||||
<ul className="space-y-4 text-sm">
|
|
||||||
<li>
|
|
||||||
<a href="https://blog.snigdhaos.org/" className="hover:text-[#6495ED] transition-colors">
|
|
||||||
Blog <span className="text-xs text-gray-400">(Upcoming!)</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://forum.snigdhaos.org/" className="hover:text-[#6495ED] transition-colors">
|
|
||||||
Forums <span className="text-xs text-gray-400">(Maintenance!)</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#" className="hover:text-[#6495ED] transition-colors">
|
|
||||||
Community <span className="text-xs text-gray-400">(Upcoming!)</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Documentation */}
|
|
||||||
<div>
|
|
||||||
<h3 className="font-bold text-xl mb-6 text-[#6495ED]">Documentation</h3>
|
|
||||||
<ul className="space-y-4 text-sm">
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href="https://snigdha-os.github.io/documentation/category/installation"
|
|
||||||
className="hover:text-[#6495ED] transition-colors"
|
|
||||||
>
|
|
||||||
Installation Guide
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href="https://snigdha-os.github.io/documentation/category/user-guide"
|
|
||||||
className="hover:text-[#6495ED] transition-colors"
|
|
||||||
>
|
|
||||||
User Guide
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href="https://snigdha-os.github.io/documentation/introduction/release_notes"
|
|
||||||
className="hover:text-[#6495ED] transition-colors"
|
|
||||||
>
|
|
||||||
Release Notes
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Connect Section */}
|
|
||||||
<div>
|
|
||||||
<h3 className="font-bold text-xl mb-6 text-[#6495ED]">Connect</h3>
|
|
||||||
<div className="flex items-center space-x-5">
|
|
||||||
<a
|
|
||||||
href="https://github.com/Snigdha-OS"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="flex items-center space-x-3 bg-gray-800 hover:bg-[#6495ED] transition-colors px-4 py-3 rounded-lg shadow-lg"
|
|
||||||
>
|
|
||||||
<Github className="h-7 w-7 text-white" />
|
|
||||||
{githubFollowers !== null && (
|
|
||||||
<div className="text-white">
|
|
||||||
<span className="text-sm">Followers</span>
|
|
||||||
<span className="block text-lg font-bold">{githubFollowers}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Footer Logo */}
|
|
||||||
{/* <div className="flex justify-center mt-8">
|
|
||||||
<img
|
|
||||||
src="/snigdhaos-logo.svg" // Replace with your actual logo path
|
|
||||||
alt="Snigdha OS Logo"
|
|
||||||
className="h-16 w-auto"
|
|
||||||
/>
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
{/* Footer Bottom */}
|
|
||||||
<div className="mt-16 pt-8 border-t border-gray-700 text-center text-sm text-gray-400">
|
|
||||||
<p>
|
|
||||||
© {new Date().getFullYear()} <span className="text-[#6495ED]">Snigdha OS</span>. Powered by <span className="font-bold text-[#6495ED]">Tonmoy Infrastructure™. </span>
|
|
||||||
All rights reserved.
|
|
||||||
</p>
|
|
||||||
<p className="mt-2">Built with ❤️ by the Snigdha OS team.</p>
|
|
||||||
{/* <p className="mt-4 text-xs text-gray-500">
|
|
||||||
Powered by <span className="font-bold text-[#6495ED]">Tonmoy Infrastructure™</span>
|
|
||||||
</p> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Inline Styles for Bubble Animation */}
|
|
||||||
<style>{`
|
|
||||||
.bubble-container {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Creating multiple bubbles */
|
|
||||||
.bubble {
|
|
||||||
position: absolute;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: rgba(100, 149, 237, 0.7);
|
|
||||||
animation: bubble-move 6s infinite;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bubble:nth-child(1) { width: 50px; height: 50px; animation-duration: 7s; top: 80%; left: 30%; }
|
|
||||||
.bubble:nth-child(2) { width: 60px; height: 60px; animation-duration: 5s; top: 70%; left: 40%; }
|
|
||||||
.bubble:nth-child(3) { width: 40px; height: 40px; animation-duration: 6s; top: 80%; left: 50%; }
|
|
||||||
.bubble:nth-child(4) { width: 70px; height: 70px; animation-duration: 8s; top: 60%; left: 20%; }
|
|
||||||
.bubble:nth-child(5) { width: 80px; height: 80px; animation-duration: 10s; top: 90%; left: 60%; }
|
|
||||||
.bubble:nth-child(6) { width: 50px; height: 50px; animation-duration: 6s; top: 50%; left: 75%; }
|
|
||||||
|
|
||||||
@keyframes bubble-move {
|
|
||||||
0% {
|
|
||||||
transform: translateX(0) translateY(0);
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: translateX(150px) translateY(-300px);
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translateX(0) translateY(-500px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
</footer>
|
|
||||||
);
|
|
||||||
}
|
|
@@ -1,138 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Link, useLocation } from 'react-router-dom';
|
|
||||||
import { Menu, X } from 'lucide-react';
|
|
||||||
|
|
||||||
export function Header() {
|
|
||||||
// Use location hook to get the current route path for active link checking
|
|
||||||
const location = useLocation();
|
|
||||||
|
|
||||||
// State to toggle the mobile menu
|
|
||||||
const [isMenuOpen, setIsMenuOpen] = React.useState(false);
|
|
||||||
|
|
||||||
// Function to check if the current path is active for styling the active link
|
|
||||||
const isActive = (path: string) => location.pathname === path;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<header className="sticky top-0 z-50 bg-gradient-to-r from-gray-900 via-gray-800 to-gray-900 text-white shadow-md">
|
|
||||||
<div className="container mx-auto px-6">
|
|
||||||
<div className="flex items-center justify-between h-20">
|
|
||||||
{/* Logo and brand name */}
|
|
||||||
<Link to="/" className="flex items-center space-x-4 group">
|
|
||||||
<img
|
|
||||||
src="/snigdhaos-logo.svg"
|
|
||||||
alt="Snigdha OS"
|
|
||||||
className="h-12 w-12 group-hover:scale-125 transition-transform duration-300"
|
|
||||||
/>
|
|
||||||
<span className="font-extrabold text-3xl tracking-wide text-[#6495ED] group-hover:text-white transition-colors duration-300">
|
|
||||||
SNIGDHA OS
|
|
||||||
</span>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
{/* Mobile menu toggle button */}
|
|
||||||
<button
|
|
||||||
className="md:hidden p-2 rounded-lg hover:bg-gray-800 transition-all focus:outline-none focus:ring-2 focus:ring-[#6495ED]"
|
|
||||||
onClick={() => setIsMenuOpen(!isMenuOpen)} // Toggle menu open/close state
|
|
||||||
>
|
|
||||||
{isMenuOpen ? (
|
|
||||||
// If menu is open, show 'X' icon
|
|
||||||
<X className="h-7 w-7 animate-spin-reverse" />
|
|
||||||
) : (
|
|
||||||
// If menu is closed, show 'Menu' icon
|
|
||||||
<Menu className="h-7 w-7 animate-spin" />
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* Desktop navigation links (hidden on mobile) */}
|
|
||||||
<nav className="hidden md:flex space-x-10">
|
|
||||||
{/* Render navigation links */}
|
|
||||||
<NavLinks isActive={isActive} closeMenu={() => setIsMenuOpen(false)} animate />
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Mobile navigation */}
|
|
||||||
<div
|
|
||||||
className={`${
|
|
||||||
// Apply fade-in or fade-out animation based on the menu state
|
|
||||||
isMenuOpen ? 'animate-fade-in-down' : 'animate-fade-out-up'
|
|
||||||
} md:hidden overflow-hidden transition-all duration-500`}
|
|
||||||
>
|
|
||||||
{/* Only render the mobile menu if it is open */}
|
|
||||||
{isMenuOpen && (
|
|
||||||
<nav className="mt-4">
|
|
||||||
{/* Mobile menu styling */}
|
|
||||||
<div className="flex flex-col space-y-4 bg-gray-800 p-5 rounded-lg shadow-lg">
|
|
||||||
{/* Render navigation links in the mobile menu */}
|
|
||||||
<NavLinks
|
|
||||||
isActive={isActive}
|
|
||||||
closeMenu={() => setIsMenuOpen(false)}
|
|
||||||
animate
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Global Keyframe Animations (inline style tag) */}
|
|
||||||
{/* These animations control the fade-in and fade-out effects for menu items */}
|
|
||||||
<style>{`
|
|
||||||
@keyframes fade-in-down {
|
|
||||||
0% { opacity: 0; transform: translateY(-10px); }
|
|
||||||
100% { opacity: 1; transform: translateY(0); }
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fade-out-up {
|
|
||||||
0% { opacity: 1; transform: translateY(0); }
|
|
||||||
100% { opacity: 0; transform: translateY(-10px); }
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fade-in-up {
|
|
||||||
0% { opacity: 0; transform: translateY(10px); }
|
|
||||||
100% { opacity: 1; transform: translateY(0); }
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
</header>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Navigation links component
|
|
||||||
function NavLinks({
|
|
||||||
isActive, // Function to check if a link is active
|
|
||||||
closeMenu, // Function to close the mobile menu after selecting a link
|
|
||||||
animate, // Whether to apply animation for the links
|
|
||||||
}: {
|
|
||||||
isActive: (path: string) => boolean;
|
|
||||||
closeMenu: () => void;
|
|
||||||
animate?: boolean;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<ul className="space-y-4 md:space-y-0 md:flex md:space-x-10">
|
|
||||||
{/* Loop through paths and labels to create navigation links */}
|
|
||||||
{['/', '/about', '/download', '/donors', '/maintainers'].map((path, idx) => {
|
|
||||||
const labels = ['Home', 'About', 'Download', 'Donors', 'Maintainers'];
|
|
||||||
return (
|
|
||||||
<li
|
|
||||||
key={path}
|
|
||||||
className={`${
|
|
||||||
// Add animation delay if `animate` is true
|
|
||||||
animate ? `animate-fade-in-up delay-${idx * 100}` : ''
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<Link
|
|
||||||
to={path}
|
|
||||||
className={`${
|
|
||||||
// If the link is active, apply custom active styles
|
|
||||||
isActive(path)
|
|
||||||
? 'text-[#6495ED] underline underline-offset-4 decoration-2'
|
|
||||||
: 'text-gray-300 hover:text-[#6495ED]'
|
|
||||||
} font-medium transition-all duration-300 hover:scale-110`}
|
|
||||||
onClick={closeMenu} // Close the mobile menu when a link is clicked
|
|
||||||
>
|
|
||||||
{labels[idx]} {/* Display label for the link */}
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
);
|
|
||||||
}
|
|
@@ -1,26 +0,0 @@
|
|||||||
import React from 'react'; // Import the React library for creating React components.
|
|
||||||
import { Header } from './Header'; // Import the `Header` component from the specified file.
|
|
||||||
import { Footer } from './Footer'; // Import the `Footer` component from the specified file.
|
|
||||||
|
|
||||||
// Define the props type for the `Layout` component.
|
|
||||||
// `children` is a special React prop that represents the content passed between the opening and closing tags of the component.
|
|
||||||
interface LayoutProps {
|
|
||||||
children: React.ReactNode; // `children` can be any valid React node (elements, strings, numbers, fragments, etc.).
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define and export the `Layout` functional component, which accepts `LayoutProps` as props.
|
|
||||||
export function Layout({ children }: LayoutProps) {
|
|
||||||
// Render the component structure.
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col min-h-screen">
|
|
||||||
{/* The main container is styled as a flexbox with a column direction and a minimum height to fill the screen. */}
|
|
||||||
<Header /> {/* Render the `Header` component at the top of the layout. */}
|
|
||||||
<main className="flex-grow">
|
|
||||||
{/* Render the `children` prop inside the `main` section.
|
|
||||||
`flex-grow` allows this section to expand and take up the remaining available space. */}
|
|
||||||
{children}
|
|
||||||
</main>
|
|
||||||
<Footer /> {/* Render the `Footer` component at the bottom of the layout. */}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
@tailwind base;
|
|
||||||
@tailwind components;
|
|
||||||
@tailwind utilities;
|
|
10
src/main.tsx
@@ -1,10 +0,0 @@
|
|||||||
import { StrictMode } from 'react';
|
|
||||||
import { createRoot } from 'react-dom/client';
|
|
||||||
import App from './App.tsx';
|
|
||||||
import './index.css';
|
|
||||||
|
|
||||||
createRoot(document.getElementById('root')!).render(
|
|
||||||
<StrictMode>
|
|
||||||
<App />
|
|
||||||
</StrictMode>
|
|
||||||
);
|
|
@@ -1,375 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react"; // Importing React, the useEffect hook for side effects, and useState hook for managing component state.
|
|
||||||
import { Heart, Users, Shield, Package, Coffee } from "lucide-react"; // Importing icons from the `lucide-react` library for use in UI components.
|
|
||||||
|
|
||||||
interface TeamMember {
|
|
||||||
// Defining a TypeScript interface to describe the structure of team member data.
|
|
||||||
login: string; // GitHub username.
|
|
||||||
avatar_url: string; // URL to the user's avatar image.
|
|
||||||
html_url: string; // URL to the user's GitHub profile.
|
|
||||||
name: string; // User's name.
|
|
||||||
bio: string; // User's bio or description.
|
|
||||||
location: string; // User's location.
|
|
||||||
company: string; // User's associated company or organization.
|
|
||||||
}
|
|
||||||
|
|
||||||
export function About() {
|
|
||||||
const [teamMembers, setTeamMembers] = useState<TeamMember[]>([]);
|
|
||||||
// Initializing `teamMembers` state as an empty array to store the team member details.
|
|
||||||
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
// `loading` state is used to track whether the data fetching process is ongoing.
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// useEffect is a React hook that runs a side effect (in this case, fetching data) after the component renders.
|
|
||||||
|
|
||||||
const fetchTeamMembers = async () => {
|
|
||||||
// Declaring an asynchronous function to fetch team member data.
|
|
||||||
try {
|
|
||||||
// Starting the `try` block to handle potential errors during the API requests.
|
|
||||||
|
|
||||||
// List of GitHub usernames of the team members.
|
|
||||||
const teamUsernames = [
|
|
||||||
"eshanized",
|
|
||||||
"d3v1l0n",
|
|
||||||
"iconized",
|
|
||||||
"alokified",
|
|
||||||
"utkrshift",
|
|
||||||
];
|
|
||||||
|
|
||||||
// Mapping over the array of usernames and creating an array of fetch promises.
|
|
||||||
const fetchProfiles = teamUsernames.map(async (username) => {
|
|
||||||
// `fetch` sends an HTTP GET request to the GitHub API for each username.
|
|
||||||
const response = await fetch(`https://api.github.com/users/${username}`);
|
|
||||||
if (!response.ok) {
|
|
||||||
// If the HTTP response status is not OK (e.g., 404 or 500), throw an error.
|
|
||||||
throw new Error(`Failed to fetch data for ${username}`);
|
|
||||||
}
|
|
||||||
return await response.json(); // Parse the JSON response and return the data.
|
|
||||||
});
|
|
||||||
|
|
||||||
const teamData = await Promise.all(fetchProfiles);
|
|
||||||
// `Promise.all` waits for all fetch requests to resolve, resulting in an array of user data.
|
|
||||||
|
|
||||||
setTeamMembers(teamData);
|
|
||||||
// Update the `teamMembers` state with the fetched data.
|
|
||||||
} catch (error) {
|
|
||||||
// Handle any errors that occurred during the fetch process.
|
|
||||||
console.error("Error fetching team members:", error); // Log the error for debugging purposes.
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
// Set the `loading` state to false, indicating that the fetch process is complete.
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchTeamMembers();
|
|
||||||
// Call the `fetchTeamMembers` function when the component mounts.
|
|
||||||
}, []);
|
|
||||||
// The empty dependency array `[]` ensures this effect runs only once when the component mounts.
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="py-16 bg-gradient-to-b from-[#F7F9FC] to-[#E6EBF1]">
|
|
||||||
<div className="container mx-auto px-4">
|
|
||||||
|
|
||||||
{/* Mission Section */}
|
|
||||||
<section className="mb-16 text-center bg-gradient-to-r from-[#6495ed] via-[#85b1f3] to-[#eaf3fc] py-16 rounded-lg shadow-lg">
|
|
||||||
<div className="container mx-auto px-4">
|
|
||||||
<h1 className="text-5xl font-extrabold mb-6 text-white drop-shadow-lg">
|
|
||||||
About <span className="text-[#eaf3fc]">Snigdha OS</span>
|
|
||||||
</h1>
|
|
||||||
<p className="text-lg md:text-xl text-white max-w-3xl mx-auto leading-relaxed">
|
|
||||||
Snigdha OS is a modern, elegant, and efficient Linux distribution designed to be lightweight and
|
|
||||||
developer-friendly. Built on Arch Linux with the Zen kernel, it offers a powerful and secure platform
|
|
||||||
for both personal use and penetration testing.
|
|
||||||
</p>
|
|
||||||
<div className="mt-8">
|
|
||||||
<a
|
|
||||||
href="#features"
|
|
||||||
className="inline-block px-8 py-3 text-lg font-semibold bg-white text-[#6495ed] rounded-full shadow-md hover:bg-[#f0f4f8] hover:shadow-lg transition-all duration-300"
|
|
||||||
>
|
|
||||||
Learn More
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Features Section */}
|
|
||||||
<section className="mb-16">
|
|
||||||
<h2 className="text-3xl font-extrabold text-[#6495ed] mb-8 text-center">Key Features</h2>
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Package className="h-12 w-12 text-teal-500 transition-transform transform hover:scale-110" />}
|
|
||||||
title="Fast & Lightweight"
|
|
||||||
description="Snigdha OS is designed to run efficiently on both older hardware and modern systems, ensuring excellent performance with minimal resource usage."
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Shield className="h-12 w-12 text-green-500 transition-transform transform hover:scale-110" />}
|
|
||||||
title="Security First"
|
|
||||||
description="Snigdha OS focuses on providing robust security with regular updates, patches, and user privacy as top priorities."
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Coffee className="h-12 w-12 text-yellow-500 transition-transform transform hover:scale-110" />}
|
|
||||||
title="Developer Friendly"
|
|
||||||
description="Packed with a rich set of tools for developers, Snigdha OS ensures smooth development and testing, especially in security-related tasks."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Values Section */}
|
|
||||||
<section className="mb-16">
|
|
||||||
<h2 className="text-3xl font-extrabold text-[#6495ed] mb-8 text-center">Our Core Values</h2>
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
||||||
<ValueCard
|
|
||||||
icon={<Heart className="h-12 w-12 text-red-500 transition-transform transform hover:scale-110" />}
|
|
||||||
title="Passion for Open Source"
|
|
||||||
description="Our community-driven approach means that Snigdha OS is constantly evolving, with contributions from developers and users worldwide."
|
|
||||||
/>
|
|
||||||
<ValueCard
|
|
||||||
icon={<Users className="h-12 w-12 text-blue-500 transition-transform transform hover:scale-110" />}
|
|
||||||
title="Community Empowerment"
|
|
||||||
description="We believe in empowering the community by encouraging collaboration, innovation, and open dialogue around the development of Snigdha OS."
|
|
||||||
/>
|
|
||||||
<ValueCard
|
|
||||||
icon={<Shield className="h-12 w-12 text-green-500 transition-transform transform hover:scale-110" />}
|
|
||||||
title="Security & Privacy"
|
|
||||||
description="Snigdha OS is built with the philosophy of safeguarding user data and ensuring that privacy remains a top priority."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Roadmap Section */}
|
|
||||||
<section className="mb-16">
|
|
||||||
<h2 className="text-3xl font-extrabold text-[#6495ed] mb-8 text-center">Roadmap</h2>
|
|
||||||
<div className="space-y-6">
|
|
||||||
<TimelineItem
|
|
||||||
year="Q1 2025"
|
|
||||||
title="User Interface Overhaul"
|
|
||||||
description="Introducing a more intuitive and modern user interface with customizable features."
|
|
||||||
/>
|
|
||||||
<TimelineItem
|
|
||||||
year="Q2 2025"
|
|
||||||
title="Security Enhancements"
|
|
||||||
description="Improving system-level security, including advanced encryption support and better intrusion detection mechanisms."
|
|
||||||
/>
|
|
||||||
<TimelineItem
|
|
||||||
year="Q3 2025"
|
|
||||||
title="Developer Tools Expansion"
|
|
||||||
description="Snigdha OS will include more developer tools, including cloud-based IDEs and enhanced testing environments for penetration testers."
|
|
||||||
/>
|
|
||||||
<TimelineItem
|
|
||||||
year="Q4 2025"
|
|
||||||
title="More Community Contributions"
|
|
||||||
description="Increasing community-driven contributions with better documentation and support for new architectures."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Contribution Guidelines Section */}
|
|
||||||
<section className="mb-16">
|
|
||||||
<h2 className="text-3xl font-extrabold text-[#6495ed] mb-8 text-center">How You Can Contribute</h2>
|
|
||||||
<div className="text-center max-w-3xl mx-auto text-lg text-gray-600 mb-8">
|
|
||||||
<p>
|
|
||||||
Whether you are a developer, designer, or simply passionate about Snigdha OS, there are many ways you can help the project grow. Contribute code, submit bug reports, or help improve the documentation.
|
|
||||||
</p>
|
|
||||||
<a
|
|
||||||
href="https://github.com/Snigdha-OS/Snigdha-OS"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="mt-4 inline-block px-6 py-3 bg-[#6495ed] text-white text-lg font-semibold rounded-lg hover:bg-[#5a82cc]"
|
|
||||||
>
|
|
||||||
View Contribution Guidelines
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Success Stories Section */}
|
|
||||||
<section className="mb-16">
|
|
||||||
<h2 className="text-3xl font-extrabold text-[#6495ed] mb-8 text-center">Success Stories</h2>
|
|
||||||
<div className="space-y-8">
|
|
||||||
<SuccessStory
|
|
||||||
title="A Developer's Dream"
|
|
||||||
description="Alex, a full-stack developer, shares how Snigdha OS transformed their workflow, offering a fast and secure environment to write code and run tests."
|
|
||||||
link="https://github.com/alexdev"
|
|
||||||
/>
|
|
||||||
<SuccessStory
|
|
||||||
title="In the Classroom"
|
|
||||||
description="Local schools have adopted Snigdha OS to give students an affordable, powerful, and secure OS for their coding and programming classes."
|
|
||||||
link="https://github.com/education-department"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Community & Resources Section */}
|
|
||||||
<section className="mb-16">
|
|
||||||
<h2 className="text-3xl font-extrabold text-[#6495ed] mb-8 text-center">Community & Resources</h2>
|
|
||||||
<div className="text-center max-w-2xl mx-auto text-lg text-gray-600 mb-8">
|
|
||||||
<p>
|
|
||||||
Join the Snigdha OS community to stay updated, contribute, and collaborate on new features. You can connect with us through our forums and GitHub.
|
|
||||||
</p>
|
|
||||||
<div className="flex justify-center gap-8 mt-6">
|
|
||||||
<a
|
|
||||||
href="https://github.com/Snigdha-OS"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="text-[#6495ed] hover:text-[#5a82cc]"
|
|
||||||
>
|
|
||||||
GitHub Repository
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="https://www.snigdhaos.com/community"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="text-[#6495ed] hover:text-[#5a82cc]"
|
|
||||||
>
|
|
||||||
Community Forum
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Leadership Team Section */}
|
|
||||||
<section>
|
|
||||||
<h2 className="text-3xl font-extrabold text-[#6495ed] mb-8 text-center">
|
|
||||||
Meet the Leadership Team
|
|
||||||
</h2>
|
|
||||||
{loading ? (
|
|
||||||
<p className="text-center text-gray-600">Loading team members...</p>
|
|
||||||
) : (
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
|
||||||
{teamMembers.map((member) => (
|
|
||||||
<TeamMemberCard
|
|
||||||
key={member.login}
|
|
||||||
name={member.name || member.login}
|
|
||||||
image={member.avatar_url}
|
|
||||||
profileUrl={member.html_url}
|
|
||||||
bio={member.bio || "Passionate about Linux and open-source software."}
|
|
||||||
location={member.location || "India"}
|
|
||||||
company={member.company || "TONMOY INFRASTRUCTURE"}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function FeatureCard({
|
|
||||||
icon,
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
}: {
|
|
||||||
icon: React.ReactNode;
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div className="text-center p-6 bg-white rounded-lg shadow-lg hover:shadow-xl transition-shadow transform hover:scale-105 hover:bg-gray-50">
|
|
||||||
<div className="flex justify-center mb-4">{icon}</div>
|
|
||||||
<h3 className="text-xl font-semibold text-[#6495ed] mb-2">{title}</h3>
|
|
||||||
<p className="text-gray-700">{description}</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ValueCard({
|
|
||||||
icon,
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
}: {
|
|
||||||
icon: React.ReactNode;
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div className="text-center p-6 bg-white rounded-lg shadow-lg hover:shadow-xl transition-shadow transform hover:scale-105 hover:bg-gray-50">
|
|
||||||
<div className="flex justify-center mb-4">{icon}</div>
|
|
||||||
<h3 className="text-xl font-semibold text-[#6495ed] mb-2">{title}</h3>
|
|
||||||
<p className="text-gray-700">{description}</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function SuccessStory({
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
link,
|
|
||||||
}: {
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
link: string;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div className="bg-white p-8 rounded-lg shadow-lg hover:shadow-xl transition-shadow">
|
|
||||||
<h3 className="text-2xl font-semibold text-[#6495ed]">{title}</h3>
|
|
||||||
<p className="text-gray-700 my-4">{description}</p>
|
|
||||||
<a
|
|
||||||
href={link}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="text-[#6495ed] hover:text-[#5a82cc]"
|
|
||||||
>
|
|
||||||
Read More
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function TimelineItem({
|
|
||||||
year,
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
}: {
|
|
||||||
year: string;
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div className="flex">
|
|
||||||
<div className="w-24 font-semibold text-green-600">{year}</div>
|
|
||||||
<div>
|
|
||||||
<h3 className="font-semibold mb-1 text-[#6495ed]">{title}</h3>
|
|
||||||
<p className="text-gray-700">{description}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function TeamMemberCard({
|
|
||||||
name,
|
|
||||||
image,
|
|
||||||
profileUrl,
|
|
||||||
bio,
|
|
||||||
location,
|
|
||||||
company,
|
|
||||||
}: {
|
|
||||||
name: string;
|
|
||||||
image: string;
|
|
||||||
profileUrl: string;
|
|
||||||
bio: string;
|
|
||||||
location: string;
|
|
||||||
company: string;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div className="text-center bg-white p-6 rounded-lg shadow-lg hover:shadow-2xl transition-shadow transform hover:scale-105">
|
|
||||||
<img
|
|
||||||
src={image}
|
|
||||||
alt={name}
|
|
||||||
className="w-32 h-32 rounded-full mx-auto mb-4 object-cover border-4 border-[#6495ed]"
|
|
||||||
/>
|
|
||||||
<h3 className="font-semibold text-lg text-gray-800 mb-2">{name}</h3>
|
|
||||||
<p className="text-gray-600 text-sm">{bio}</p>
|
|
||||||
<p className="text-gray-500 text-sm mt-2">{location}</p>
|
|
||||||
<p className="text-gray-500 text-sm mt-1">{company}</p>
|
|
||||||
<a
|
|
||||||
href={profileUrl}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="text-[#6495ed] hover:text-[#5a82cc] mt-2 inline-block"
|
|
||||||
>
|
|
||||||
View Profile
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@@ -1,214 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { Heart, PieChart } from 'lucide-react';
|
|
||||||
import { FaRupeeSign } from 'react-icons/fa';
|
|
||||||
|
|
||||||
async function getGitHubUserData(username: string): Promise<{ name: string; avatar_url: string }> {
|
|
||||||
try {
|
|
||||||
const response = await fetch(`https://api.github.com/users/${username}`);
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`User not found: ${username}`);
|
|
||||||
}
|
|
||||||
const data = await response.json();
|
|
||||||
return {
|
|
||||||
name: data.name || username, // Use GitHub name or fallback to username
|
|
||||||
avatar_url: data.avatar_url || '',
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
return { name: username, avatar_url: '' }; // Return username if there is an error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function useGitHubDonors(usernames: string[]): { [key: string]: { name: string; avatar_url: string } } {
|
|
||||||
const [donors, setDonors] = useState<{ [key: string]: { name: string; avatar_url: string } }>({});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const fetchDonors = async () => {
|
|
||||||
const donorData: { [key: string]: { name: string; avatar_url: string } } = {};
|
|
||||||
for (let username of usernames) {
|
|
||||||
const data = await getGitHubUserData(username);
|
|
||||||
donorData[username] = data;
|
|
||||||
}
|
|
||||||
setDonors(donorData);
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchDonors();
|
|
||||||
}, [usernames]);
|
|
||||||
|
|
||||||
return donors;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Donors() {
|
|
||||||
const donorUsernames = [
|
|
||||||
"eshanized",
|
|
||||||
"TIAsCode",
|
|
||||||
"IXINTL",
|
|
||||||
];
|
|
||||||
|
|
||||||
const donorData = useGitHubDonors(donorUsernames);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="py-12">
|
|
||||||
<div className="container mx-auto px-4">
|
|
||||||
{/* Hero Section */}
|
|
||||||
<section className="text-center mb-16">
|
|
||||||
<Heart className="h-16 w-16 text-[#6495ed] mx-auto mb-6" />
|
|
||||||
<h1 className="text-4xl font-bold mb-6 text-[#6495ed]">Our Amazing Donors</h1>
|
|
||||||
<p className="text-xl text-gray-600 max-w-3xl mx-auto">
|
|
||||||
Snigdha OS is made possible thanks to the generous support of our donors. We are grateful for their contributions to keep our project running.
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Donor List */}
|
|
||||||
<section className="mb-16">
|
|
||||||
<h2 className="text-3xl font-bold mb-8 text-center text-[#6495ed]">Donors List</h2>
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
|
||||||
{donorUsernames.map((donor) => (
|
|
||||||
<div key={donor} className="flex items-center gap-4">
|
|
||||||
{donorData[donor]?.avatar_url ? (
|
|
||||||
<img
|
|
||||||
src={donorData[donor].avatar_url}
|
|
||||||
alt={donorData[donor].name}
|
|
||||||
className="h-12 w-12 rounded-full"
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<div className="h-12 w-12 rounded-full bg-gray-300"></div> // Placeholder if no avatar
|
|
||||||
)}
|
|
||||||
<div>
|
|
||||||
<span className="font-semibold">{donorData[donor]?.name || donor}</span>
|
|
||||||
<br />
|
|
||||||
<span className="text-sm text-gray-500">
|
|
||||||
<a
|
|
||||||
href={`https://github.com/${donor}`}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="text-blue-500 hover:underline"
|
|
||||||
>
|
|
||||||
@{donor}
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Become a Donor */}
|
|
||||||
<section className="bg-[#6495ed] rounded-lg p-8 text-center">
|
|
||||||
<h2 className="text-3xl font-bold mb-4 text-white">
|
|
||||||
<FaRupeeSign className="inline-block h-6 w-6 text-green-500 mr-2" />
|
|
||||||
Become a Donor
|
|
||||||
</h2>
|
|
||||||
<p className="text-white mb-8 max-w-2xl mx-auto">
|
|
||||||
Your support helps us maintain and improve Snigdha OS. Every donation, big or small, makes a difference in keeping our project independent and sustainable.
|
|
||||||
</p>
|
|
||||||
<button className="bg-[#6495ed] text-white px-8 py-3 rounded-[5px] hover:bg-[#6495ed] transition-colors">
|
|
||||||
Make a Donation
|
|
||||||
</button>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Yearly Report */}
|
|
||||||
<section className="mt-16">
|
|
||||||
<h2 className="text-3xl font-bold mb-8 text-[#6495ed]">
|
|
||||||
<PieChart className="inline-block h-6 w-6 text-[#6495ed] mr-2" />
|
|
||||||
Yearly Donation Report
|
|
||||||
</h2>
|
|
||||||
<div className="bg-white rounded-lg shadow-lg p-8">
|
|
||||||
<div className="space-y-6">
|
|
||||||
<YearlyStats
|
|
||||||
month="Year - 2024"
|
|
||||||
amount={15750}
|
|
||||||
donors={14}
|
|
||||||
averageDonation={1125}
|
|
||||||
/>
|
|
||||||
<div className="border-t pt-6">
|
|
||||||
<h3 className="font-bold mb-4 text-[#6495ed]">How Donations Are Used</h3>
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
||||||
<UsageCard
|
|
||||||
percentage={40}
|
|
||||||
category="Development"
|
|
||||||
description="Supporting core developers and infrastructure"
|
|
||||||
icon={<PieChart className="h-6 w-6 text-[#6495ed]" />}
|
|
||||||
/>
|
|
||||||
<UsageCard
|
|
||||||
percentage={35}
|
|
||||||
category="Server Costs"
|
|
||||||
description="Maintaining mirrors and websites"
|
|
||||||
icon={<PieChart className="h-6 w-6 text-[#6495ed]" />}
|
|
||||||
/>
|
|
||||||
<UsageCard
|
|
||||||
percentage={25}
|
|
||||||
category="Community"
|
|
||||||
description="Supporting community projects and events"
|
|
||||||
icon={<PieChart className="h-6 w-6 text-[#6495ed]" />}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
type YearlyStatsProps = {
|
|
||||||
month: string;
|
|
||||||
amount: number;
|
|
||||||
donors: number;
|
|
||||||
averageDonation: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
function YearlyStats({
|
|
||||||
month,
|
|
||||||
amount,
|
|
||||||
donors,
|
|
||||||
averageDonation,
|
|
||||||
}: YearlyStatsProps) {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h3 className="font-bold text-xl mb-4 text-[#6495ed]">{month}</h3>
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
||||||
<div className="bg-gray-50 p-4 rounded-lg">
|
|
||||||
<p className="text-sm text-gray-600">Total Donations</p>
|
|
||||||
<p className="text-2xl font-bold">₹{amount.toLocaleString()}</p>
|
|
||||||
</div>
|
|
||||||
<div className="bg-gray-50 p-4 rounded-lg">
|
|
||||||
<p className="text-sm text-gray-600">Number of Donors</p>
|
|
||||||
<p className="text-2xl font-bold">{donors}</p>
|
|
||||||
</div>
|
|
||||||
<div className="bg-gray-50 p-4 rounded-lg">
|
|
||||||
<p className="text-sm text-gray-600">Average Donation</p>
|
|
||||||
<p className="text-2xl font-bold">₹{averageDonation}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
type UsageCardProps = {
|
|
||||||
percentage: number;
|
|
||||||
category: string;
|
|
||||||
description: string;
|
|
||||||
icon: React.ReactNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
function UsageCard({
|
|
||||||
percentage,
|
|
||||||
category,
|
|
||||||
description,
|
|
||||||
icon,
|
|
||||||
}: UsageCardProps) {
|
|
||||||
return (
|
|
||||||
<div className="bg-gray-50 p-4 rounded-lg">
|
|
||||||
<div className="flex items-center mb-2">
|
|
||||||
{icon}
|
|
||||||
<span className="ml-2 text-xl font-semibold text-[#6495ed]">
|
|
||||||
{percentage}%
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<h4 className="font-regular mb-1 text-[#6495ed]">{category}</h4>
|
|
||||||
<p className="text-sm text-gray-600">{description}</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@@ -1,371 +0,0 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import { Download as DownloadIcon, Monitor, Server, HardDrive, Smartphone, Move } from 'lucide-react';
|
|
||||||
|
|
||||||
export function DownloadPage() {
|
|
||||||
const [userLocation, setUserLocation] = useState<string | null>(null);
|
|
||||||
const [userRegion, setUserRegion] = useState<string | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
async function fetchLocation() {
|
|
||||||
try {
|
|
||||||
const response = await fetch('https://ipapi.co/json/');
|
|
||||||
const data = await response.json();
|
|
||||||
setUserLocation(`${data.city}, ${data.country}`);
|
|
||||||
setUserRegion(data.country); // Store the user's country or region
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to fetch user location:', error);
|
|
||||||
setUserLocation(null);
|
|
||||||
setUserRegion(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fetchLocation();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const getSuggestedMirror = () => {
|
|
||||||
if (!userRegion) return null;
|
|
||||||
|
|
||||||
const regionMap: { [key: string]: string } = {
|
|
||||||
"united states": "north america",
|
|
||||||
"canada": "north america",
|
|
||||||
"brazil": "south america",
|
|
||||||
"argentina": "south america",
|
|
||||||
"germany": "europe",
|
|
||||||
"france": "europe",
|
|
||||||
"india": "asia",
|
|
||||||
"japan": "asia",
|
|
||||||
"south africa": "africa",
|
|
||||||
"australia": "australia",
|
|
||||||
};
|
|
||||||
|
|
||||||
const normalizedRegion = regionMap[userRegion.toLowerCase()] || userRegion.toLowerCase();
|
|
||||||
|
|
||||||
return mirrorData.find((mirror) =>
|
|
||||||
mirror.region.toLowerCase().includes(normalizedRegion)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const suggestedMirror = getSuggestedMirror();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="bg-gradient-to-b from-[#f0f4f8] to-[#e1e8f0] py-12">
|
|
||||||
<div className="container mx-auto px-4">
|
|
||||||
{/* Hero Section */}
|
|
||||||
<section className="text-center mb-16">
|
|
||||||
<h1 className="text-4xl font-extrabold mb-6 text-[#333]">
|
|
||||||
Download Snigdha OS
|
|
||||||
</h1>
|
|
||||||
<p className="text-xl text-gray-600 max-w-3xl mx-auto leading-relaxed">
|
|
||||||
Choose the edition that best suits your needs. All versions are free
|
|
||||||
to download and use, providing the best experience for developers,
|
|
||||||
students, and professionals alike.
|
|
||||||
</p>
|
|
||||||
<div className="mt-8 space-y-6">
|
|
||||||
<div className="flex justify-center items-center space-x-4">
|
|
||||||
<FeatureBadge color="#6495ed" text="Lightweight & Fast" />
|
|
||||||
<FeatureBadge color="#6495ed" text="Open Source & Free" />
|
|
||||||
<FeatureBadge color="#6495ed" text="Customizable & Secure" />
|
|
||||||
</div>
|
|
||||||
<p className="text-lg text-gray-700 max-w-4xl mx-auto mt-6">
|
|
||||||
Snigdha OS is designed to provide an unparalleled experience,
|
|
||||||
whether you're working on an older device or a high-end system.
|
|
||||||
Built with efficiency, reliability, and beauty in mind, it’s
|
|
||||||
perfect for home users, professionals, and enterprises. Download
|
|
||||||
today to unlock the full potential of your hardware.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Edition Cards */}
|
|
||||||
<section className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8 mb-16">
|
|
||||||
{editionData.map((edition, index) => (
|
|
||||||
<EditionCard key={index} {...edition} />
|
|
||||||
))}
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* System Requirements */}
|
|
||||||
<section className="mb-16">
|
|
||||||
<h2 className="text-3xl font-extrabold text-center mb-8 text-[#333]">
|
|
||||||
System Requirements
|
|
||||||
</h2>
|
|
||||||
<div className="rounded-[5px] p-10 shadow-2xl bg-white">
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-10">
|
|
||||||
<SystemRequirements
|
|
||||||
title="Minimum Requirements"
|
|
||||||
specs={[
|
|
||||||
'2GB RAM (4GB recommended)',
|
|
||||||
'20GB of disk space (100GB recommended)',
|
|
||||||
'1024×768 resolution',
|
|
||||||
]}
|
|
||||||
notes="These are the minimum requirements to run Snigdha OS smoothly. For basic tasks such as web browsing, office applications, and media playback, this setup is sufficient."
|
|
||||||
/>
|
|
||||||
<SystemRequirements
|
|
||||||
title="Recommended Requirements"
|
|
||||||
specs={[
|
|
||||||
'4GB RAM or more',
|
|
||||||
'100GB of disk space or more',
|
|
||||||
'1920×1080 resolution or higher',
|
|
||||||
]}
|
|
||||||
notes="These specifications provide an optimal experience, enabling smooth performance for multitasking, using modern applications, and running resource-intensive tasks like video editing or gaming."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Download Mirrors */}
|
|
||||||
<section className="mb-16">
|
|
||||||
<h2 className="text-3xl font-extrabold text-center mb-8 text-[#333]">
|
|
||||||
Download Mirrors
|
|
||||||
</h2>
|
|
||||||
<p className="text-lg text-gray-600 text-center mb-6 max-w-2xl mx-auto">
|
|
||||||
Select a mirror closest to your location for faster download speeds.{' '}
|
|
||||||
<br />
|
|
||||||
{userLocation ? (
|
|
||||||
<span className="text-gray-600 font-regular">
|
|
||||||
Your detected location: <span className="text-green-600 font-bold">{userLocation}</span>
|
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
<span>Detecting your location...</span>
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
||||||
{mirrorData.map((mirror, index) => (
|
|
||||||
<MirrorButton key={index} {...mirror} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
{suggestedMirror && (
|
|
||||||
<div className="mt-8 text-center">
|
|
||||||
<h3 className="text-2xl font-bold text-[#6495ed]">
|
|
||||||
Suggested Mirror for You
|
|
||||||
</h3>
|
|
||||||
<MirrorButton {...suggestedMirror} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Components
|
|
||||||
function FeatureBadge({
|
|
||||||
color,
|
|
||||||
text,
|
|
||||||
}: {
|
|
||||||
color: string;
|
|
||||||
text: string;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<span
|
|
||||||
className={`inline-block px-6 py-3 text-sm bg-[${color}] text-white rounded-[5px] shadow-md transform transition-all hover:scale-105`}
|
|
||||||
>
|
|
||||||
{text}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function EditionCard({
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
keyFeatures,
|
|
||||||
idealFor,
|
|
||||||
icon,
|
|
||||||
recommended,
|
|
||||||
}: {
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
keyFeatures: string[];
|
|
||||||
idealFor: string;
|
|
||||||
icon: React.ReactNode;
|
|
||||||
recommended?: boolean;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={`bg-white rounded-[5px] shadow-lg hover:shadow-2xl p-8 relative transition-transform transform hover:scale-105 ${
|
|
||||||
recommended ? 'border-2 border-[#6495ed]' : ''
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{recommended && (
|
|
||||||
<div className="absolute top-4 right-4 bg-[#6495ed] text-white px-3 py-2 rounded-[5px] text-sm shadow-lg">
|
|
||||||
Recommended
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="flex justify-center mb-4">{icon}</div>
|
|
||||||
<h3 className="text-2xl font-semibold mb-2 text-center text-[#333]">{title}</h3>
|
|
||||||
<p className="text-gray-600 text-center mb-4">{description}</p>
|
|
||||||
<div className="mb-4">
|
|
||||||
<h4 className="text-sm font-bold text-[#6495ed]">Key Features:</h4>
|
|
||||||
<ul className="list-disc list-inside text-gray-600 text-sm">
|
|
||||||
{keyFeatures.map((feature, index) => (
|
|
||||||
<li key={index}>{feature}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h4 className="text-sm font-bold text-[#6495ed]">Ideal For:</h4>
|
|
||||||
<p className="text-gray-600 text-sm">{idealFor}</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex justify-center mt-6">
|
|
||||||
<button className="flex items-center space-x-2 bg-[#6495ed] text-white px-8 py-3 rounded-[5px] hover:bg-[#4169e1] transition-colors transform hover:scale-105">
|
|
||||||
<DownloadIcon className="h-6 w-6" />
|
|
||||||
<span>Download</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function SystemRequirements({
|
|
||||||
title,
|
|
||||||
specs,
|
|
||||||
notes,
|
|
||||||
}: {
|
|
||||||
title: string;
|
|
||||||
specs: string[];
|
|
||||||
notes: string;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div className="bg-white shadow-lg rounded-[5px] p-8">
|
|
||||||
<h3 className="text-2xl font-semibold text-[#333]">{title}</h3>
|
|
||||||
<ul className="space-y-3 text-gray-700 mt-4">
|
|
||||||
{specs.map((spec, index) => (
|
|
||||||
<li key={index}>{spec}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
<p className="mt-4 text-gray-600 text-sm">{notes}</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function MirrorButton({
|
|
||||||
region,
|
|
||||||
speed,
|
|
||||||
host,
|
|
||||||
url,
|
|
||||||
suggested = false,
|
|
||||||
description,
|
|
||||||
}: {
|
|
||||||
region: string;
|
|
||||||
speed: string;
|
|
||||||
host: string;
|
|
||||||
url: string;
|
|
||||||
suggested?: boolean;
|
|
||||||
description: string;
|
|
||||||
}) {
|
|
||||||
const speedColor = {
|
|
||||||
'Very Fast': 'text-green-500',
|
|
||||||
Fast: 'text-blue-500',
|
|
||||||
Moderate: 'text-orange-500',
|
|
||||||
}[speed];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<a
|
|
||||||
href={url}
|
|
||||||
className={`block bg-white rounded-[5px] shadow hover:shadow-xl transition-all p-6 border-2 border-gray-200 ${suggested ? 'bg-[#e6f0ff]' : ''} hover:bg-[#f4f7ff]`}
|
|
||||||
>
|
|
||||||
<div className="text-center">
|
|
||||||
<h3 className="text-xl font-bold text-[#333]">{region}</h3>
|
|
||||||
<p className="text-sm text-gray-600">{host}</p>
|
|
||||||
</div>
|
|
||||||
<div className="text-center mt-2">
|
|
||||||
<span className={`font-semibold ${speedColor}`}>{speed}</span>
|
|
||||||
</div>
|
|
||||||
<div className="text-sm text-gray-600 mt-2">
|
|
||||||
{description}
|
|
||||||
</div>
|
|
||||||
<button className="bg-[#6495ed] text-white py-2 px-6 rounded-[5px] mt-4 transition-colors hover:bg-[#4169e1]">
|
|
||||||
Download
|
|
||||||
</button>
|
|
||||||
{suggested && (
|
|
||||||
<div className="absolute top-2 right-2 bg-[#6495ed] text-white text-xs px-2 py-1 rounded-[5px]">
|
|
||||||
Suggested Mirror
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Data for editions and mirrors
|
|
||||||
const editionData = [
|
|
||||||
{
|
|
||||||
title: 'Gnome Edition',
|
|
||||||
description: 'Modern, innovative features while being traditional and familiar.',
|
|
||||||
keyFeatures: ['Dynamic Workspaces', 'Extensible Extensions', 'Built-in Accessibility'],
|
|
||||||
idealFor: 'General users who prefer a sleek and functional desktop experience.',
|
|
||||||
icon: <Monitor className="h-12 w-12 text-[#6495ed]" />,
|
|
||||||
recommended: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'MATE Edition',
|
|
||||||
description: 'Traditional desktop experience, highly stable and reliable.',
|
|
||||||
keyFeatures: ['Low Resource Usage', 'Consistent Workflow', 'Legacy Support'],
|
|
||||||
idealFor: 'Users who value simplicity and reliability over modern features.',
|
|
||||||
icon: <Server className="h-12 w-12 text-[#6495ed]" />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Xfce Edition',
|
|
||||||
description: 'Lightweight and stable. Perfect for older computers.',
|
|
||||||
keyFeatures: ['Minimal Resource Usage', 'Fast Boot Times', 'Highly Customizable'],
|
|
||||||
idealFor: 'Users with older hardware or those who need maximum performance.',
|
|
||||||
icon: <HardDrive className="h-12 w-12 text-[#6495ed]" />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'KDE Plasma Edition',
|
|
||||||
description: 'Feature-rich, eye-catching, and offers tons of customization.',
|
|
||||||
keyFeatures: ['Cutting-edge Visuals', 'Full Customization', 'Highly Extensible'],
|
|
||||||
idealFor: 'Power users who want control and beauty in equal measure.',
|
|
||||||
icon: <Smartphone className="h-12 w-12 text-[#6495ed]" />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'i3 Window Manager Edition',
|
|
||||||
description: 'Minimal and efficient. Perfect for users who prefer keyboard-driven navigation.',
|
|
||||||
keyFeatures: ['Tiling Window Manager', 'Lightweight', 'Highly Configurable'],
|
|
||||||
idealFor: 'Users who value efficiency and are comfortable with manual configuration.',
|
|
||||||
icon: <Move className="h-12 w-12 text-[#6495ed]" />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Openbox Edition',
|
|
||||||
description: 'A fast and lightweight window manager with full customization.',
|
|
||||||
keyFeatures: ['Highly Customizable', 'Low Memory Usage', 'Simple Layout'],
|
|
||||||
idealFor: 'Users looking for a lightweight and minimal window manager.',
|
|
||||||
icon: <Move className="h-12 w-12 text-[#6495ed]" />,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const mirrorData = [
|
|
||||||
{
|
|
||||||
region: 'North America (USA)',
|
|
||||||
speed: 'Very Fast',
|
|
||||||
host: 'ExampleMirrorHost.com',
|
|
||||||
url: 'https://example.com/download',
|
|
||||||
description: 'Located in the United States, this mirror offers extremely fast download speeds for North American users.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
region: 'Europe (Germany)',
|
|
||||||
speed: 'Fast',
|
|
||||||
host: 'EU-Mirror.com',
|
|
||||||
url: 'https://eu-mirror.com/download',
|
|
||||||
description: 'This server in Germany provides good download speeds for European users.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
region: 'Asia (India)',
|
|
||||||
speed: 'Moderate',
|
|
||||||
host: 'IN-Mirror.com',
|
|
||||||
url: 'https://in-mirror.com/download',
|
|
||||||
description: 'Located in India, this mirror is suitable for users in South Asia. Speeds may vary depending on network conditions.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
region: 'South America (Brazil)',
|
|
||||||
speed: 'Fast',
|
|
||||||
host: 'BR-Mirror.com',
|
|
||||||
url: 'https://br-mirror.com/download',
|
|
||||||
description: 'This mirror in Brazil offers fast download speeds for South American users.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
region: 'Australia',
|
|
||||||
speed: 'Very Fast',
|
|
||||||
host: 'AU-Mirror.com',
|
|
||||||
url: 'https://au-mirror.com/download',
|
|
||||||
description: 'Users in Australia can enjoy very fast download speeds from this mirror.',
|
|
||||||
},
|
|
||||||
// Add more mirrors as needed
|
|
||||||
];
|
|
@@ -1,452 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Download, Shield, Terminal, Award, Users, Coffee, ArrowRight, Star, Book, Cpu, Monitor } from 'lucide-react';
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
export function Home() {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{/* Embedded CSS */}
|
|
||||||
<style>
|
|
||||||
{`
|
|
||||||
/* New Gradient Animation for Hero Section */
|
|
||||||
@keyframes gradientAnimation {
|
|
||||||
0% {
|
|
||||||
background-position: 0% 50%;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
background-position: 100% 50%;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
background-position: 0% 50%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Typing Effect for Hero Tagline */
|
|
||||||
@keyframes typing {
|
|
||||||
from {
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes blink {
|
|
||||||
50% {
|
|
||||||
border-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.typing-effect {
|
|
||||||
// font-family: monospace;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
display: inline-block;
|
|
||||||
// border-right: 3px solid;
|
|
||||||
width: 20ch; /* Adjust to fit text length */
|
|
||||||
animation: typing 7s steps(100) infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.hero-background {
|
|
||||||
background: linear-gradient(135deg, #000000, #1a1a1a, #6495ed);
|
|
||||||
background-size: 300% 300%;
|
|
||||||
animation: gradientAnimation 10s ease infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Optional: Keep the animation definition if not already present */
|
|
||||||
@keyframes gradientAnimation {
|
|
||||||
0% { background-position: 0% 50%; }
|
|
||||||
50% { background-position: 100% 50%; }
|
|
||||||
100% { background-position: 0% 50%; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* New hover effect for feature cards */
|
|
||||||
.card:hover {
|
|
||||||
transform: scale(1.07) rotate(1deg); /* Slight rotation for a dynamic effect */
|
|
||||||
transition:
|
|
||||||
transform 0.4s ease-in-out,
|
|
||||||
box-shadow 0.4s ease-in-out,
|
|
||||||
background-color 0.4s ease-in-out;
|
|
||||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3); /* Increased shadow intensity */
|
|
||||||
background-color: rgba(255, 255, 255, 0.9); /* Light tint on hover */
|
|
||||||
filter: brightness(1.1) contrast(1.05); /* Subtle brightness and contrast boost */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Optional Glow Effect for a More Eye-Catching Look */
|
|
||||||
.card:hover::after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: -5px;
|
|
||||||
left: -5px;
|
|
||||||
right: -5px;
|
|
||||||
bottom: -5px;
|
|
||||||
border-radius: 10px; /* Matches the card border radius */
|
|
||||||
box-shadow: 0 0 15px rgba(255, 255, 255, 0.4); /* Glowing effect */
|
|
||||||
pointer-events: none; /* Ensures it doesn't block interaction */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* New hover effect for hero section heading */
|
|
||||||
.hero-heading:hover {
|
|
||||||
transform: scale(1.1);
|
|
||||||
color: #ffffff;
|
|
||||||
text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* New feature card style */
|
|
||||||
.feature-card {
|
|
||||||
border: 2px solid transparent;
|
|
||||||
background: linear-gradient(145deg, #ffffff, #f0f4f8);
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 15px;
|
|
||||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1), 0 4px 15px rgba(100, 149, 237, 0.2);
|
|
||||||
transition: transform 0.4s cubic-bezier(0.19, 1, 0.22, 1), box-shadow 0.4s cubic-bezier(0.19, 1, 0.22, 1), border 0.3s ease;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: -50%;
|
|
||||||
left: -50%;
|
|
||||||
width: 200%;
|
|
||||||
height: 200%;
|
|
||||||
background: radial-gradient(circle, rgba(100, 149, 237, 0.2), rgba(0, 0, 0, 0));
|
|
||||||
transform: scale(0);
|
|
||||||
transition: transform 0.4s ease-in-out;
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card:hover::before {
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card:hover {
|
|
||||||
transform: translateY(-10px) scale(1.05);
|
|
||||||
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.15), 0 8px 20px rgba(100, 149, 237, 0.3);
|
|
||||||
border-color: #6495ed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card h4 {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #6495ed;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
z-index: 1;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card p {
|
|
||||||
font-size: 1rem;
|
|
||||||
color: #333333;
|
|
||||||
z-index: 1;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card:hover h4 {
|
|
||||||
color: #1e90ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card:hover p {
|
|
||||||
color: #555555;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* New list style for features */
|
|
||||||
.feature-list {
|
|
||||||
list-style-type: disc;
|
|
||||||
padding-left: 20px;
|
|
||||||
margin-top: 10px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
{/* Hero Section */}
|
|
||||||
<section className="bg-gradient-to-r from-[#000000] to-[#6495ed] text-white py-20 relative overflow-hidden hero-background">
|
|
||||||
<div className="absolute inset-0 -z-10">
|
|
||||||
<img
|
|
||||||
src="https://via.placeholder.com/1920x1080" // Replace with your desired background image URL
|
|
||||||
alt="Background"
|
|
||||||
className="w-full h-full object-cover opacity-30"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="container mx-auto px-4 text-center relative z-10">
|
|
||||||
{/* Main Heading */}
|
|
||||||
<h1 className="text-5xl font-extrabold mb-6 text-shadow-md leading-tight hero-heading">
|
|
||||||
UNLEASH THE FUTURE WITH
|
|
||||||
</h1>
|
|
||||||
<h1 className="text-5xl font-extrabold mb-6 text-shadow-md leading-tight hero-heading">
|
|
||||||
SNIGDHA OS 🌐
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
{/* Tagline with Typing Effect */}
|
|
||||||
<h2 className="text-2xl font-semibold mb-8 max-w-3xl mx-auto text-shadow-lg text-center">
|
|
||||||
<span className="typing-effect">~Innovation begins with freedom!</span>
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<p className="text-xl mb-8 max-w-3xl mx-auto text-shadow-lg text-justify">
|
|
||||||
Snigdha OS is an intuitive, cutting-edge Linux distribution designed for <strong>Privacy Protection 🔐</strong>, <strong>Advanced Development Tools 👩💻</strong>, and <strong>Daily Computing 💻</strong>. Empower your workflow with powerful apps and unmatched performance 🚀.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{/* Call to Action Buttons */}
|
|
||||||
<div className="flex flex-wrap justify-center space-x-6 mt-6">
|
|
||||||
<Link
|
|
||||||
to="/download"
|
|
||||||
className="border-2 border-white text-white px-8 py-4 rounded-lg font-semibold transform hover:scale-105 hover:bg-white hover:text-[#6495ed] transition-all duration-300 inline-flex items-center space-x-3"
|
|
||||||
>
|
|
||||||
<Download className="h-5 w-5" />
|
|
||||||
<span>Download Now 🚀</span>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link
|
|
||||||
to="https://snigdha-os.github.io/documentation/"
|
|
||||||
className="border-2 border-white text-white px-8 py-4 rounded-lg font-semibold transform hover:scale-105 hover:bg-white hover:text-[#6495ed] transition-all duration-300 inline-flex items-center space-x-3"
|
|
||||||
>
|
|
||||||
<Book className="h-5 w-5" />
|
|
||||||
<span>Read the Docs 📚</span>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link
|
|
||||||
to="https://forum.snigdha-os.org" // Replace with your community forum URL
|
|
||||||
className="border-2 border-white text-white px-8 py-4 rounded-lg font-semibold transform hover:scale-105 hover:bg-white hover:text-[#6495ed] transition-all duration-300 inline-flex items-center space-x-3"
|
|
||||||
>
|
|
||||||
<Users className="h-5 w-5" />
|
|
||||||
<span>Join the Community 🌍</span>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
|
||||||
{/* Features Section */}
|
|
||||||
<section className="py-16 bg-gradient-to-r from-[#f0f4f8] to-[#ffffff]">
|
|
||||||
<div className="container mx-auto px-4">
|
|
||||||
{/* Main Heading */}
|
|
||||||
<h2 className="text-4xl font-bold text-center text-[#6495ed] mb-12 tracking-tight">
|
|
||||||
Key Features ✨
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
{/* Subheading */}
|
|
||||||
<p className="text-xl text-center text-gray-700 mb-6 max-w-3xl mx-auto">
|
|
||||||
Discover the amazing features of Snigdha OS that make it the perfect choice for developers, cybersecurity professionals, and anyone looking for a fast, secure, and customizable OS.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{/* Feature Cards */}
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-12">
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Shield className="h-10 w-10 text-red-500 mx-auto" />}
|
|
||||||
title="Secure 🔒"
|
|
||||||
description="Regular security updates and a robust system architecture keep your data safe."
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Terminal className="h-10 w-10 text-green-500 mx-auto" />}
|
|
||||||
title="Powerful 💪"
|
|
||||||
description="Full access to the terminal and system components for advanced users."
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Download className="h-10 w-10 text-blue-500 mx-auto" />}
|
|
||||||
title="Free Forever 🎉"
|
|
||||||
description="Snigdha OS is free and open source. No costs, no subscriptions."
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Award className="h-10 w-10 text-yellow-500 mx-auto" />}
|
|
||||||
title="Customizable 🎨"
|
|
||||||
description="Personalize your desktop environment to suit your needs and style."
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Users className="h-10 w-10 text-pink-500 mx-auto" />}
|
|
||||||
title="Community Support 🤗"
|
|
||||||
description="A vibrant community ready to help and share knowledge."
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Star className="h-10 w-10 text-[#6495ed] mx-auto" />}
|
|
||||||
title="Feature Rich ⚡"
|
|
||||||
description="Pre-installed applications and tools for everyday use."
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Coffee className="h-10 w-10 text-brown-500 mx-auto" />}
|
|
||||||
title="Energy Efficient 🌱"
|
|
||||||
description="Optimized performance to save energy and enhance hardware longevity."
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<ArrowRight className="h-10 w-10 text-teal-500 mx-auto" />}
|
|
||||||
title="Fast Boot ⏱️"
|
|
||||||
description="Experience faster boot times and smooth transitions."
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Terminal className="h-10 w-10 text-purple-500 mx-auto" />}
|
|
||||||
title="Advanced Tools 🧰"
|
|
||||||
description="Access specialized penetration testing and ethical hacking tools."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Desktop Environments Section */}
|
|
||||||
<section className="py-16 bg-gradient-to-r from-[#f9f9f9] to-[#ffffff]">
|
|
||||||
<div className="container mx-auto px-4">
|
|
||||||
{/* Main Heading */}
|
|
||||||
<h2 className="text-4xl font-bold text-center text-[#6495ed] mb-12 tracking-tight">
|
|
||||||
Popular Desktop Environments 🌍
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
{/* Desktop Environment Cards */}
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-12">
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Monitor className="h-10 w-10 text-blue-500 mx-auto" />}
|
|
||||||
title="GNOME 🌿"
|
|
||||||
description="A clean and modern desktop environment that prioritizes simplicity and ease of use."
|
|
||||||
listItems={[
|
|
||||||
"Minimalist design focused on usability.",
|
|
||||||
"Intuitive interface with modern features.",
|
|
||||||
"Highly customizable with GNOME extensions.",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Monitor className="h-10 w-10 text-green-500 mx-auto" />}
|
|
||||||
title="KDE Plasma ⚡"
|
|
||||||
description="Highly customizable and visually appealing, perfect for power users."
|
|
||||||
listItems={[
|
|
||||||
"Rich, visually appealing desktop with full customization.",
|
|
||||||
"Multiple widgets and advanced themes.",
|
|
||||||
"Excellent performance with modern hardware.",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Monitor className="h-10 w-10 text-purple-500 mx-auto" />}
|
|
||||||
title="XFCE ⚙️"
|
|
||||||
description="Lightweight, fast, and resource-efficient, ideal for older hardware."
|
|
||||||
listItems={[
|
|
||||||
"Optimized for low resource usage.",
|
|
||||||
"Simple, clean interface with traditional design.",
|
|
||||||
"Fast boot times and low memory footprint.",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Monitor className="h-10 w-10 text-pink-500 mx-auto" />}
|
|
||||||
title="Cinnamon 🍃"
|
|
||||||
description="A modern desktop environment that provides a user-friendly interface."
|
|
||||||
listItems={[
|
|
||||||
"Traditional desktop layout with a modern touch.",
|
|
||||||
"Easy to customize and lightweight.",
|
|
||||||
"Supports multiple workspaces and desklets.",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Monitor className="h-10 w-10 text-orange-500 mx-auto" />}
|
|
||||||
title="MATE 🌻"
|
|
||||||
description="A continuation of GNOME 2, offering a more traditional desktop experience."
|
|
||||||
listItems={[
|
|
||||||
"Classic desktop environment with modern touches.",
|
|
||||||
"Low memory usage and optimized performance.",
|
|
||||||
"Supports a wide range of applications and tools.",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Monitor className="h-10 w-10 text-yellow-500 mx-auto" />}
|
|
||||||
title="LXQt 💻"
|
|
||||||
description="A lightweight and fast desktop environment designed for low-resource systems."
|
|
||||||
listItems={[
|
|
||||||
"Minimal memory footprint and fast boot times.",
|
|
||||||
"Simple interface with modern functionalities.",
|
|
||||||
"Efficient on both old and modern hardware.",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Window Managers Section */}
|
|
||||||
<section className="py-16 bg-gradient-to-r from-[#f0f4f8] to-[#ffffff]">
|
|
||||||
<div className="container mx-auto px-4">
|
|
||||||
{/* Main Heading */}
|
|
||||||
<h2 className="text-4xl font-bold text-center text-[#6495ed] mb-12 tracking-tight">
|
|
||||||
Popular Window Managers 🖥️
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
{/* Window Manager Cards */}
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-12">
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Cpu className="h-10 w-10 text-red-500 mx-auto" />}
|
|
||||||
title="i3 🖱️"
|
|
||||||
description="A tiling window manager designed for power users."
|
|
||||||
listItems={[
|
|
||||||
"Dynamic tiling for efficient workspace management.",
|
|
||||||
"Keyboard-driven interface for quick navigation.",
|
|
||||||
"Highly customizable with scripting support.",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Cpu className="h-10 w-10 text-yellow-500 mx-auto" />}
|
|
||||||
title="Awesome WM ⚡"
|
|
||||||
description="Highly configurable and extensible for personalized setups."
|
|
||||||
listItems={[
|
|
||||||
"Extensible and modular configuration.",
|
|
||||||
"Supports tiling, floating, and full-screen layouts.",
|
|
||||||
"Built-in Lua scripting for customizations.",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Cpu className="h-10 w-10 text-green-500 mx-auto" />}
|
|
||||||
title="Openbox 🔲"
|
|
||||||
description="Lightweight stacking window manager with high flexibility."
|
|
||||||
listItems={[
|
|
||||||
"Minimalist window manager focused on efficiency.",
|
|
||||||
"Highly customizable themes and behaviors.",
|
|
||||||
"Great for older hardware and resource-limited systems.",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Cpu className="h-10 w-10 text-blue-500 mx-auto" />}
|
|
||||||
title="Xmonad 💻"
|
|
||||||
description="A tiling window manager written and configured in Haskell."
|
|
||||||
listItems={[
|
|
||||||
"Written in Haskell for maximum customizability.",
|
|
||||||
"Uses dynamic tiling for flexible window management.",
|
|
||||||
"Highly customizable and extendable.",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Cpu className="h-10 w-10 text-orange-500 mx-auto" />}
|
|
||||||
title="Fluxbox 🌀"
|
|
||||||
description="A lightweight and configurable window manager based on Blackbox."
|
|
||||||
listItems={[
|
|
||||||
"Very low memory usage and high performance.",
|
|
||||||
"Highly customizable with simple configuration.",
|
|
||||||
"Supports multiple workspaces and styles.",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<FeatureCard
|
|
||||||
icon={<Cpu className="h-10 w-10 text-purple-500 mx-auto" />}
|
|
||||||
title="Herbstluftwm 🖼️"
|
|
||||||
description="A manual tiling window manager for X11 with a unique approach."
|
|
||||||
listItems={[
|
|
||||||
"Manual tiling with a highly flexible layout.",
|
|
||||||
"Written in bash and easy to configure.",
|
|
||||||
"Supports multi-monitor setups and dynamic layouts.",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const FeatureCard = ({ icon, title, description, listItems }: { icon: React.ReactNode; title: string; description: string; listItems?: string[] }) => (
|
|
||||||
<div className="feature-card p-6 rounded-lg shadow-md text-center">
|
|
||||||
<div className="mb-4">{icon}</div>
|
|
||||||
<h4 className="text-xl font-semibold text-[#6495ed]">{title}</h4>
|
|
||||||
<p className="text-gray-600 mt-2">{description}</p>
|
|
||||||
{listItems && (
|
|
||||||
<ul className="feature-list">
|
|
||||||
{listItems.map((item, index) => (
|
|
||||||
<li key={index}>{item}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
@@ -1,129 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { Github, Twitter, Globe, MapPin, Users } from 'lucide-react';
|
|
||||||
import { getMaintainers, type Maintainer } from '../services/github';
|
|
||||||
|
|
||||||
export function Maintainers() {
|
|
||||||
const [maintainers, setMaintainers] = useState<Maintainer[]>([]);
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [error, setError] = useState<string | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const fetchMaintainers = async () => {
|
|
||||||
try {
|
|
||||||
const data = await getMaintainers();
|
|
||||||
setMaintainers(data);
|
|
||||||
} catch (err) {
|
|
||||||
setError('Failed to load maintainers data');
|
|
||||||
console.error(err);
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchMaintainers();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
return (
|
|
||||||
<div className="min-h-screen flex items-center justify-center">
|
|
||||||
<div className="animate-spin rounded-full h-16 w-16 border-4 border-[#6495ed] border-t-transparent"></div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
return (
|
|
||||||
<div className="min-h-screen flex items-center justify-center">
|
|
||||||
<div className="text-center">
|
|
||||||
<p className="text-red-500 text-xl">{error}</p>
|
|
||||||
<p className="text-gray-600 mt-2">Please try again later</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="py-12">
|
|
||||||
<div className="container mx-auto px-4">
|
|
||||||
<section className="text-center mb-16">
|
|
||||||
<h1 className="text-4xl font-bold text-gray-800 mb-6">Meet Our Maintainers</h1>
|
|
||||||
<p className="text-lg text-gray-600 max-w-3xl mx-auto">
|
|
||||||
These dedicated individuals work tirelessly to make Snigdha OS one of the best Linux distributions available.
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
||||||
{maintainers.map((maintainer) => (
|
|
||||||
<MaintainerCard key={maintainer.login} maintainer={maintainer} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function MaintainerCard({ maintainer }: { maintainer: Maintainer }) {
|
|
||||||
return (
|
|
||||||
<div className="bg-white rounded-xl shadow-lg p-6 transition-transform transform hover:scale-105 hover:shadow-xl ease-in-out duration-300">
|
|
||||||
<div className="flex items-center space-x-4 mb-4">
|
|
||||||
<img
|
|
||||||
src={maintainer.avatarUrl}
|
|
||||||
alt={maintainer.name || maintainer.login}
|
|
||||||
className="w-24 h-24 rounded-full ring-2 ring-[#6495ed]"
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
<h2 className="text-2xl font-semibold text-gray-800">{maintainer.name || maintainer.login}</h2>
|
|
||||||
<p className="text-sm text-gray-500">@{maintainer.login}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{maintainer.bio && (
|
|
||||||
<p className="text-gray-700 mb-4">{maintainer.bio}</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="space-y-2 mb-4">
|
|
||||||
{maintainer.location && (
|
|
||||||
<div className="flex items-center space-x-2 text-gray-600">
|
|
||||||
<MapPin className="h-5 w-5 text-gray-600" />
|
|
||||||
<span>{maintainer.location}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="flex items-center space-x-2 text-gray-600">
|
|
||||||
<Users className="h-5 w-5 text-gray-600" />
|
|
||||||
<span>{maintainer.followers} followers | {maintainer.following} following</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex space-x-4 mt-4">
|
|
||||||
<a
|
|
||||||
href={`https://github.com/${maintainer.login}`}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="text-gray-600 hover:text-gray-900 transition-colors duration-200"
|
|
||||||
>
|
|
||||||
<Github className="h-6 w-6" />
|
|
||||||
</a>
|
|
||||||
{maintainer.twitterUsername && (
|
|
||||||
<a
|
|
||||||
href={`https://twitter.com/${maintainer.twitterUsername}`}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="text-[#6495ed] hover:text-[#4169e1] transition-colors duration-200"
|
|
||||||
>
|
|
||||||
<Twitter className="h-6 w-6" />
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
{maintainer.blog && (
|
|
||||||
<a
|
|
||||||
href={maintainer.blog}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="text-[#6495ed] hover:text-[#4169e1] transition-colors duration-200"
|
|
||||||
>
|
|
||||||
<Globe className="h-6 w-6" />
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@@ -1,49 +0,0 @@
|
|||||||
import { Octokit } from 'octokit';
|
|
||||||
|
|
||||||
const octokit = new Octokit();
|
|
||||||
|
|
||||||
export interface Maintainer {
|
|
||||||
login: string;
|
|
||||||
name: string | null;
|
|
||||||
avatarUrl: string;
|
|
||||||
bio: string | null;
|
|
||||||
location: string | null;
|
|
||||||
blog: string | null;
|
|
||||||
twitterUsername: string | null;
|
|
||||||
followers: number;
|
|
||||||
following: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getMaintainers(): Promise<Maintainer[]> {
|
|
||||||
const maintainerUsernames = [
|
|
||||||
'eshanized',
|
|
||||||
'iconized',
|
|
||||||
'alokified',
|
|
||||||
'utkrshift',
|
|
||||||
'd3v1l0n',
|
|
||||||
];
|
|
||||||
|
|
||||||
const maintainers = await Promise.all(
|
|
||||||
maintainerUsernames.map(async (username) => {
|
|
||||||
try {
|
|
||||||
const { data } = await octokit.rest.users.getByUsername({ username });
|
|
||||||
return {
|
|
||||||
login: data.login,
|
|
||||||
name: data.name,
|
|
||||||
avatarUrl: data.avatar_url,
|
|
||||||
bio: data.bio,
|
|
||||||
location: data.location,
|
|
||||||
blog: data.blog,
|
|
||||||
twitterUsername: data.twitter_username,
|
|
||||||
followers: data.followers,
|
|
||||||
following: data.following,
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error fetching data for ${username}:`, error);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return maintainers.filter((m): m is Maintainer => m !== null);
|
|
||||||
}
|
|
1
src/vite-env.d.ts
vendored
@@ -1 +0,0 @@
|
|||||||
/// <reference types="vite/client" />
|
|
@@ -1,16 +0,0 @@
|
|||||||
export default {
|
|
||||||
content: [
|
|
||||||
"./src/**/*.{html,js,jsx,ts,tsx}",
|
|
||||||
],
|
|
||||||
theme: {
|
|
||||||
extend: {
|
|
||||||
colors: {
|
|
||||||
'primary': '#6495ed',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
plugins: [],
|
|
||||||
corePlugins: {
|
|
||||||
preflight: true,
|
|
||||||
},
|
|
||||||
};
|
|
@@ -1,37 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ES2020",
|
|
||||||
"useDefineForClassFields": true,
|
|
||||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
||||||
"module": "ESNext",
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"allowImportingTsExtensions": true,
|
|
||||||
"isolatedModules": true,
|
|
||||||
"moduleDetection": "force",
|
|
||||||
"noEmit": true,
|
|
||||||
"jsx": "react-jsx",
|
|
||||||
"strict": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"noUnusedParameters": true,
|
|
||||||
"noFallthroughCasesInSwitch": true,
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"skipDefaultLibCheck": true,
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"noImplicitAny": true,
|
|
||||||
"strictNullChecks": true,
|
|
||||||
"baseUrl": "./",
|
|
||||||
"paths": {
|
|
||||||
"components/*": ["src/components/*"],
|
|
||||||
"utils/*": ["src/utils/*"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"src"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"node_modules",
|
|
||||||
"build"
|
|
||||||
]
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"files": [],
|
|
||||||
"references": [
|
|
||||||
{ "path": "./tsconfig.app.json" },
|
|
||||||
{ "path": "./tsconfig.node.json" }
|
|
||||||
]
|
|
||||||
}
|
|
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ES2022",
|
|
||||||
"lib": ["ES2023"],
|
|
||||||
"module": "ESNext",
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"skipDefaultLibCheck": true,
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"isolatedModules": true,
|
|
||||||
"noEmit": true,
|
|
||||||
"strict": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"noUnusedParameters": true,
|
|
||||||
"noFallthroughCasesInSwitch": true,
|
|
||||||
"noImplicitAny": true
|
|
||||||
},
|
|
||||||
"include": ["vite.config.ts"]
|
|
||||||
}
|
|
@@ -1,25 +0,0 @@
|
|||||||
import { defineConfig } from 'vite';
|
|
||||||
import react from '@vitejs/plugin-react';
|
|
||||||
import { resolve } from 'path';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
base: '/',
|
|
||||||
plugins: [
|
|
||||||
react(),
|
|
||||||
],
|
|
||||||
optimizeDeps: {
|
|
||||||
exclude: ['lucide-react'],
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': resolve(__dirname, 'src'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
css: {
|
|
||||||
preprocessorOptions: {
|
|
||||||
scss: {
|
|
||||||
additionalData: '@import "@/styles/variables.scss";',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|