chore: initiate local to github

This commit is contained in:
eshanized
2025-01-07 12:57:29 +05:30
commit c359947d62
21 changed files with 7418 additions and 0 deletions

24
.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
# 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?

28
eslint.config.js Normal file
View File

@@ -0,0 +1,28 @@
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 },
],
},
}
);

13
index.html Normal file
View File

@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

4051
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

33
package.json Normal file
View File

@@ -0,0 +1,33 @@
{
"name": "vite-react-typescript-starter",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"lucide-react": "^0.344.0",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@eslint/js": "^9.9.1",
"@types/react": "^18.3.5",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.1",
"autoprefixer": "^10.4.18",
"eslint": "^9.9.1",
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
"eslint-plugin-react-refresh": "^0.4.11",
"globals": "^15.9.0",
"postcss": "^8.4.35",
"tailwindcss": "^3.4.1",
"typescript": "^5.5.3",
"typescript-eslint": "^8.3.0",
"vite": "^5.4.2"
}
}

2552
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

6
postcss.config.js Normal file
View File

@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

32
src/App.tsx Normal file
View File

@@ -0,0 +1,32 @@
import React, { useState } from 'react';
import Sidebar from './components/Sidebar';
import Navbar from './components/Navbar';
import Footer from './components/Footer';
import ToolDetails from './components/ToolDetails';
import { kaliTools } from './data/tools';
function App() {
const [selectedTool, setSelectedTool] = useState<string | null>(kaliTools[0].name);
const [isSidebarOpen, setSidebarOpen] = useState(true);
const currentTool = kaliTools.find(tool => tool.name === selectedTool);
return (
<div className="flex flex-col min-h-screen bg-dark-100 text-nord-4">
<Navbar isSidebarOpen={isSidebarOpen} onToggleSidebar={() => setSidebarOpen(!isSidebarOpen)} />
<div className="flex flex-1">
<Sidebar
selectedTool={selectedTool}
onSelectTool={setSelectedTool}
isOpen={isSidebarOpen}
/>
<main className={`flex-1 transition-all duration-300 ease-in-out ${isSidebarOpen ? 'ml-64' : 'ml-0'}`}>
{currentTool && <ToolDetails tool={currentTool} />}
</main>
</div>
<Footer />
</div>
);
}
export default App;

39
src/components/Footer.tsx Normal file
View File

@@ -0,0 +1,39 @@
import React from 'react';
import { Heart } from 'lucide-react';
const Footer: React.FC = () => {
return (
<footer className="bg-dark-200 border-t border-dark-300 py-6">
<div className="max-w-7xl mx-auto px-4">
<div className="flex flex-col items-center justify-center space-y-4">
<div className="flex items-center space-x-2">
<span>Made with</span>
<Heart className="w-5 h-5 text-nord-11 animate-pulse" />
<span>for the security community</span>
</div>
<div className="text-sm text-nord-4">
© {new Date().getFullYear()} Snigdha OS Tools. All rights reserved.
</div>
<div className="flex items-center space-x-3 text-sm text-nord-4">
<span>Developed by</span>
<a
href="https://github.com/eshanized"
target="_blank"
rel="noopener noreferrer"
className="flex items-center space-x-2 hover:text-primary transition-colors duration-200 group"
>
<span className="text-primary">eshanized</span>
<img
src="https://github.com/eshanized.png"
alt="eshanized"
className="w-8 h-8 rounded-full border-2 border-transparent group-hover:border-primary transition-all duration-200 shadow-lg"
/>
</a>
</div>
</div>
</div>
</footer>
);
}
export default Footer;

55
src/components/Navbar.tsx Normal file
View File

@@ -0,0 +1,55 @@
import React from 'react';
import { Menu, Terminal, Github, Coffee } from 'lucide-react';
interface NavbarProps {
isSidebarOpen: boolean;
onToggleSidebar: () => void;
}
const Navbar: React.FC<NavbarProps> = ({ isSidebarOpen, onToggleSidebar }) => {
return (
<nav className="bg-dark-200 border-b border-dark-300 fixed w-full z-10 shadow-lg">
<div className="max-w-7xl mx-auto px-4">
<div className="flex items-center justify-between h-16">
<div className="flex items-center">
<button
onClick={onToggleSidebar}
className="p-2 rounded-md hover:bg-dark-300 transition-colors duration-200"
title={isSidebarOpen ? "Close sidebar" : "Open sidebar"}
>
<Menu className={`w-6 h-6 text-primary transform transition-transform duration-300 ${
isSidebarOpen ? 'rotate-0' : 'rotate-180'
}`} />
</button>
<div className="flex items-center ml-4">
<Terminal className="h-8 w-8 text-primary" />
<span className="ml-2 text-xl font-bold text-nord-6">Snigdha OS Tools</span>
</div>
</div>
<div className="flex items-center space-x-4">
<a
href="https://github.com/kalilinux"
target="_blank"
rel="noopener noreferrer"
className="p-2 rounded-md hover:bg-dark-300 transition-colors duration-200 group"
title="View on GitHub"
>
<Github className="w-6 h-6 text-nord-4 group-hover:text-primary transition-colors duration-200" />
</a>
<a
href="https://www.kali.org/docs/"
target="_blank"
rel="noopener noreferrer"
className="p-2 rounded-md hover:bg-dark-300 transition-colors duration-200 group"
title="Documentation"
>
<Coffee className="w-6 h-6 text-nord-4 group-hover:text-primary transition-colors duration-200" />
</a>
</div>
</div>
</div>
</nav>
);
}
export default Navbar;

View File

@@ -0,0 +1,73 @@
import React, { useState } from 'react';
import { Search, FolderOpen } from 'lucide-react';
import { kaliTools } from '../data/tools';
interface SidebarProps {
selectedTool: string | null;
onSelectTool: (toolName: string) => void;
isOpen: boolean;
}
const Sidebar: React.FC<SidebarProps> = ({ selectedTool, onSelectTool, isOpen }) => {
const [searchTerm, setSearchTerm] = useState('');
const categories = Array.from(new Set(kaliTools.map(tool => tool.category)));
const filteredTools = kaliTools.filter(tool =>
tool.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
tool.category.toLowerCase().includes(searchTerm.toLowerCase())
);
const filteredCategories = categories.filter(category =>
filteredTools.some(tool => tool.category === category)
);
return (
<div className={`fixed left-0 top-16 h-[calc(100vh-4rem)] bg-dark-200 transform transition-all duration-300 ease-in-out ${
isOpen ? 'translate-x-0 w-64' : '-translate-x-full w-64'
} overflow-hidden border-r border-dark-300 shadow-xl`}>
<div className="h-full overflow-y-auto p-4">
<div className="relative mb-6">
<Search className="absolute left-3 top-2.5 w-4 h-4 text-primary" />
<input
type="text"
placeholder="Search tools..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="w-full bg-dark-300 rounded-md py-2 pl-10 pr-4 text-sm focus:outline-none focus:ring-2 focus:ring-primary text-nord-4 placeholder-primary/50 transition-colors duration-200 border border-dark-400"
/>
</div>
<div className="space-y-6">
{filteredCategories.map(category => (
<div key={category} className="transform transition-all duration-300 hover:translate-x-2">
<h2 className="flex items-center gap-2 text-primary text-sm font-semibold mb-3">
<FolderOpen className="w-4 h-4" />
{category}
</h2>
<ul className="space-y-1">
{filteredTools
.filter(tool => tool.category === category)
.map(tool => (
<li key={tool.name}>
<button
onClick={() => onSelectTool(tool.name)}
className={`w-full text-left px-3 py-2 rounded-md text-sm transition-all duration-200 ${
selectedTool === tool.name
? 'bg-primary text-nord-6 transform scale-105 shadow-md'
: 'hover:bg-dark-300 text-nord-4 hover:translate-x-1'
}`}
>
{tool.name}
</button>
</li>
))}
</ul>
</div>
))}
</div>
</div>
</div>
);
}
export default Sidebar;

View File

@@ -0,0 +1,117 @@
import React from 'react';
import { Tool } from '../data/tools';
import { Terminal, BookOpen, Command, Copy, Check, ExternalLink } from 'lucide-react';
interface ToolDetailsProps {
tool: Tool;
}
const ToolDetails: React.FC<ToolDetailsProps> = ({ tool }) => {
const [copiedStates, setCopiedStates] = React.useState<{[key: string]: boolean}>({});
const copyToClipboard = async (text: string, id: string) => {
await navigator.clipboard.writeText(text);
setCopiedStates(prev => ({ ...prev, [id]: true }));
setTimeout(() => {
setCopiedStates(prev => ({ ...prev, [id]: false }));
}, 2000);
};
return (
<div className="p-8 max-w-4xl mx-auto mt-16">
<div className="mb-8 bg-dark-200 rounded-lg p-8 shadow-lg transform hover:scale-[1.01] transition-all duration-300">
<h1 className="text-4xl font-bold mb-4 text-primary flex items-center gap-3">
{tool.name}
<span className="text-sm px-3 py-1 bg-primary/20 text-primary rounded-full">
{tool.category}
</span>
</h1>
<p className="text-nord-4 text-lg leading-relaxed">{tool.description}</p>
</div>
<div className="space-y-8">
<section className="bg-dark-200 rounded-lg p-6 shadow-lg transform hover:scale-[1.01] transition-all duration-300">
<div className="flex items-center gap-3 mb-4">
<Terminal className="w-6 h-6 text-primary" />
<h2 className="text-2xl font-semibold text-primary">Installation</h2>
</div>
<div className="bg-dark-300 rounded-lg p-4 hover:bg-dark-400 transition-colors duration-200 relative group border border-dark-400">
<code className="text-nord-13 font-mono">{tool.installation}</code>
<button
onClick={() => copyToClipboard(tool.installation, 'installation')}
className="absolute right-2 top-1/2 -translate-y-1/2 p-2 rounded-md opacity-0 group-hover:opacity-100 hover:bg-dark-300 transition-all duration-200"
title="Copy to clipboard"
>
{copiedStates['installation'] ? (
<Check className="w-4 h-4 text-nord-14" />
) : (
<Copy className="w-4 h-4 text-nord-4" />
)}
</button>
</div>
</section>
<section className="bg-dark-200 rounded-lg p-6 shadow-lg transform hover:scale-[1.01] transition-all duration-300">
<div className="flex items-center gap-3 mb-4">
<BookOpen className="w-6 h-6 text-primary" />
<h2 className="text-2xl font-semibold text-primary">Usage</h2>
</div>
<ul className="space-y-3">
{tool.usage.map((use, index) => (
<li key={index} className="flex items-start gap-2 text-nord-4 hover:text-nord-6 transition-colors duration-200">
<ExternalLink className="w-4 h-4 mt-1 flex-shrink-0 text-primary" />
<span className="leading-relaxed">{use}</span>
</li>
))}
</ul>
</section>
<section className="bg-dark-200 rounded-lg p-6 shadow-lg transform hover:scale-[1.01] transition-all duration-300">
<div className="flex items-center gap-3 mb-4">
<Command className="w-6 h-6 text-primary" />
<h2 className="text-2xl font-semibold text-primary">Commands</h2>
</div>
<div className="space-y-6">
{tool.commands.map((cmd, index) => (
<div key={index} className="border border-dark-400 rounded-lg p-4 hover:border-primary transition-colors duration-200 bg-gradient-to-br from-transparent to-dark-300/30">
<div className="bg-dark-300 rounded-md p-3 mb-3 hover:bg-dark-400 transition-colors duration-200 relative group border border-dark-400">
<code className="text-nord-14 font-mono">{cmd.command}</code>
<button
onClick={() => copyToClipboard(cmd.command, `cmd-${index}`)}
className="absolute right-2 top-1/2 -translate-y-1/2 p-2 rounded-md opacity-0 group-hover:opacity-100 hover:bg-dark-300 transition-all duration-200"
title="Copy command"
>
{copiedStates[`cmd-${index}`] ? (
<Check className="w-4 h-4 text-nord-14" />
) : (
<Copy className="w-4 h-4 text-nord-4" />
)}
</button>
</div>
<p className="text-nord-4 mb-3 pl-2 border-l-2 border-primary">{cmd.description}</p>
{cmd.example && (
<div className="bg-dark-300 rounded-md p-3 hover:bg-dark-400 transition-colors duration-200 relative group border border-dark-400">
<code className="text-nord-13 font-mono">Example: {cmd.example}</code>
<button
onClick={() => copyToClipboard(cmd.example!, `example-${index}`)}
className="absolute right-2 top-1/2 -translate-y-1/2 p-2 rounded-md opacity-0 group-hover:opacity-100 hover:bg-dark-300 transition-all duration-200"
title="Copy example"
>
{copiedStates[`example-${index}`] ? (
<Check className="w-4 h-4 text-nord-14" />
) : (
<Copy className="w-4 h-4 text-nord-4" />
)}
</button>
</div>
)}
</div>
))}
</div>
</section>
</div>
</div>
);
}
export default ToolDetails;

282
src/data/tools.ts Normal file
View File

@@ -0,0 +1,282 @@
export interface Tool {
name: string;
category: string;
description: string;
installation: string;
usage: string[];
commands: Command[];
}
interface Command {
command: string;
description: string;
example?: string;
}
export const kaliTools: Tool[] = [
{
name: "Nmap",
category: "Information Gathering",
description: "Nmap ('Network Mapper') is a free and open source utility for network discovery and security auditing. It uses raw IP packets in novel ways to determine what hosts are available on the network, what services those hosts are offering, what operating systems they are running, what type of packet filters/firewalls are in use, and dozens of other characteristics.",
installation: "sudo pacman -S nmap",
usage: [
"Network exploration and host discovery",
"Port scanning and service detection",
"OS detection and version detection",
"Vulnerability and backdoor detection",
"Network mapping and inventory"
],
commands: [
{
command: "nmap -sS [target]",
description: "Perform a TCP SYN scan (stealthy scan)",
example: "nmap -sS 192.168.1.0/24"
},
{
command: "nmap -sV -sC [target]",
description: "Detect service versions and run default scripts",
example: "nmap -sV -sC example.com"
},
{
command: "nmap -p- [target]",
description: "Scan all 65535 ports",
example: "nmap -p- 10.0.0.1"
},
{
command: "nmap -A [target]",
description: "Aggressive scan (OS detection, version detection, script scanning, and traceroute)",
example: "nmap -A 192.168.1.1"
}
]
},
{
name: "Metasploit",
category: "Exploitation Tools",
description: "The Metasploit Framework is a powerful penetration testing and exploitation framework that provides a complete environment for penetration testing and exploit development. It contains a suite of tools that can be used to test security vulnerabilities, enumerate networks, execute attacks, and evade detection.",
installation: "sudo pacman -S metasploit",
usage: [
"Vulnerability research and testing",
"Exploit development and deployment",
"Payload generation and delivery",
"Post-exploitation activities",
"Security assessment automation"
],
commands: [
{
command: "msfconsole",
description: "Start the Metasploit Framework console",
example: "msfconsole"
},
{
command: "search [term]",
description: "Search for modules, exploits, or payloads",
example: "search type:exploit platform:windows"
},
{
command: "use [module]",
description: "Select a module to use",
example: "use exploit/windows/smb/ms17_010_eternalblue"
},
{
command: "show options",
description: "Display module options",
example: "show options"
},
{
command: "set PAYLOAD [payload]",
description: "Set the payload for the exploit",
example: "set PAYLOAD windows/meterpreter/reverse_tcp"
}
]
},
{
name: "Burp Suite",
category: "Web Application Analysis",
description: "Burp Suite is an integrated platform for performing security testing of web applications. It contains various tools that work together seamlessly to support the entire testing process, from initial mapping and analysis of an application's attack surface, through to finding and exploiting security vulnerabilities.",
installation: "sudo pacman -S burpsuite",
usage: [
"Web application security testing",
"Vulnerability scanning",
"Traffic interception and modification",
"Automated crawling and scanning",
"Custom extension development"
],
commands: [
{
command: "burpsuite",
description: "Launch Burp Suite GUI",
example: "burpsuite"
},
{
command: "java -jar burpsuite_pro.jar",
description: "Launch Burp Suite Professional",
example: "java -jar burpsuite_pro.jar"
}
]
},
{
name: "Aircrack-ng",
category: "Wireless Attacks",
description: "Aircrack-ng is a complete suite of tools to assess WiFi network security. It focuses on different areas of WiFi security: monitoring, attacking, testing, and cracking. The suite includes packet capture and export of data to text files for further processing by third party tools.",
installation: "sudo pacman -S aircrack-ng",
usage: [
"WEP and WPA-PSK key cracking",
"Wireless network monitoring",
"Packet capture and injection",
"Network detection and reconnaissance",
"WiFi card testing capabilities"
],
commands: [
{
command: "airmon-ng start [interface]",
description: "Start monitor mode on wireless interface",
example: "airmon-ng start wlan0"
},
{
command: "airodump-ng [interface]",
description: "Capture packets and show nearby wireless networks",
example: "airodump-ng wlan0mon"
},
{
command: "aireplay-ng -0 [count] -a [BSSID] [interface]",
description: "Perform deauthentication attack",
example: "aireplay-ng -0 10 -a 00:11:22:33:44:55 wlan0mon"
},
{
command: "aircrack-ng [capture file]",
description: "Crack WEP/WPA keys from capture file",
example: "aircrack-ng capture-01.cap"
}
]
},
{
name: "John the Ripper",
category: "Password Attacks",
description: "John the Ripper is a fast password cracker, currently available for many flavors of Unix, Windows, and other operating systems. Its primary purpose is to detect weak Unix passwords, but it supports hundreds of hash and cipher types.",
installation: "sudo pacman -S john",
usage: [
"Password hash cracking",
"Dictionary attacks",
"Brute force attacks",
"Custom rule-based attacks",
"Password auditing"
],
commands: [
{
command: "john [password file]",
description: "Crack passwords using default mode",
example: "john passwords.txt"
},
{
command: "john --wordlist=[wordlist] [password file]",
description: "Perform dictionary attack using specified wordlist",
example: "john --wordlist=rockyou.txt hashes.txt"
},
{
command: "john --show [password file]",
description: "Show cracked passwords",
example: "john --show cracked.txt"
}
]
},
{
name: "Wireshark",
category: "Sniffing & Spoofing",
description: "Wireshark is the world's foremost and widely-used network protocol analyzer. It lets you see what's happening on your network at a microscopic level and is the de facto standard across many commercial and non-profit enterprises, government agencies, and educational institutions.",
installation: "sudo pacman -S wireshark-qt",
usage: [
"Real-time packet capture and analysis",
"Deep packet inspection",
"Protocol dissection and analysis",
"Network troubleshooting",
"Security analysis and verification"
],
commands: [
{
command: "wireshark",
description: "Launch Wireshark GUI",
example: "wireshark"
},
{
command: "tshark -i [interface]",
description: "Capture packets on specific interface using CLI",
example: "tshark -i eth0"
},
{
command: "tshark -r [file]",
description: "Read and analyze capture file",
example: "tshark -r capture.pcap"
},
{
command: "tshark -i [interface] -f [filter]",
description: "Capture with filter",
example: "tshark -i eth0 -f 'port 80'"
}
]
},
{
name: "Hydra",
category: "Password Attacks",
description: "Hydra is a parallelized login cracker which supports numerous protocols to attack. It is very fast and flexible, and new modules are easy to add. This tool makes it possible to show the institution of a system administrator the weak points of the system.",
installation: "sudo pacman -S hydra",
usage: [
"Online password cracking",
"Brute force attacks against login services",
"Dictionary attacks on multiple protocols",
"Password spraying attacks",
"Service authentication testing"
],
commands: [
{
command: "hydra -l [user] -P [wordlist] [protocol://target]",
description: "Basic password attack against a service",
example: "hydra -l admin -P passwords.txt ssh://192.168.1.1"
},
{
command: "hydra -L [users file] -P [passwords file] [service] [target]",
description: "Attack using lists of users and passwords",
example: "hydra -L users.txt -P pass.txt ftp://10.0.0.1"
},
{
command: "hydra -l [user] -p [password] [target] [service] -V",
description: "Verbose attack with single user/password",
example: "hydra -l root -p toor 192.168.1.1 ssh -V"
}
]
},
{
name: "SQLmap",
category: "Web Application Analysis",
description: "SQLmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over database servers. It comes with a powerful detection engine, many niche features, and a broad range of switches including database fingerprinting, data fetching from the database, and accessing the underlying file system.",
installation: "sudo pacman -S sqlmap",
usage: [
"Automated SQL injection detection",
"Database server fingerprinting",
"Data extraction from databases",
"File system access on database server",
"Command execution on database server"
],
commands: [
{
command: "sqlmap -u [URL]",
description: "Basic SQL injection test on URL",
example: "sqlmap -u \"http://example.com/page.php?id=1\""
},
{
command: "sqlmap -u [URL] --dbs",
description: "Enumerate databases",
example: "sqlmap -u \"http://example.com/page.php?id=1\" --dbs"
},
{
command: "sqlmap -u [URL] -D [database] --tables",
description: "List tables in specific database",
example: "sqlmap -u \"http://example.com/page.php?id=1\" -D testdb --tables"
},
{
command: "sqlmap -u [URL] --batch --random-agent",
description: "Automated scan with random User-Agent",
example: "sqlmap -u \"http://example.com/page.php?id=1\" --batch --random-agent"
}
]
}
];

3
src/index.css Normal file
View File

@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

10
src/main.tsx Normal file
View File

@@ -0,0 +1,10 @@
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
src/vite-env.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
/// <reference types="vite/client" />

36
tailwind.config.js Normal file
View File

@@ -0,0 +1,36 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {
colors: {
primary: '#6495ED',
dark: {
100: '#1a1a1a',
200: '#242424',
300: '#2d2d2d',
400: '#353535',
},
nord: {
0: '#1a1a1a', // Darker background
1: '#242424',
2: '#2d2d2d',
3: '#353535',
4: '#D8DEE9',
5: '#E5E9F0',
6: '#ECEFF4',
7: '#6495ED', // Primary color
8: '#7BA4EE', // Lighter primary
9: '#5886DE', // Darker primary
10: '#4B77CF',
11: '#BF616A',
12: '#D08770',
13: '#EBCB8B',
14: '#A3BE8C',
15: '#B48EAD',
},
},
},
},
plugins: [],
};

24
tsconfig.app.json Normal file
View File

@@ -0,0 +1,24 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}

7
tsconfig.json Normal file
View File

@@ -0,0 +1,7 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}

22
tsconfig.node.json Normal file
View File

@@ -0,0 +1,22 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["vite.config.ts"]
}

10
vite.config.ts Normal file
View File

@@ -0,0 +1,10 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
optimizeDeps: {
exclude: ['lucide-react'],
},
});