mirror of
https://github.com/Xevion/linkpulse.git
synced 2025-12-06 03:15:35 -06:00
completely re-initialize Vite/React configuration to dummy
This commit is contained in:
30
frontend/.gitignore
vendored
30
frontend/.gitignore
vendored
@@ -1,6 +1,24 @@
|
|||||||
.eslintcache
|
# Logs
|
||||||
.pnpm-debug.log
|
logs
|
||||||
node_modules/
|
*.log
|
||||||
coverage/
|
npm-debug.log*
|
||||||
dist/
|
yarn-debug.log*
|
||||||
tsconfig.tsbuildinfo
|
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?
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
"rsc": false,
|
"rsc": false,
|
||||||
"tsx": true,
|
"tsx": true,
|
||||||
"tailwind": {
|
"tailwind": {
|
||||||
"config": "tailwind.config.cjs",
|
"config": "tailwind.config.js",
|
||||||
"css": "src/App.css",
|
"css": "src/index.css",
|
||||||
"baseColor": "zinc",
|
"baseColor": "zinc",
|
||||||
"cssVariables": false,
|
"cssVariables": true,
|
||||||
"prefix": ""
|
"prefix": ""
|
||||||
},
|
},
|
||||||
"aliases": {
|
"aliases": {
|
||||||
|
|||||||
28
frontend/eslint.config.js
Normal file
28
frontend/eslint.config.js
Normal 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 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
@@ -1,16 +1,13 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
name="viewport"
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
<title>Vite + React + TS</title>
|
||||||
/>
|
|
||||||
<meta name="theme-color" content="#fff" />
|
|
||||||
<title>App</title>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root" class="min-w-full min-h-screen"></div>
|
<div id="root"></div>
|
||||||
<script src="/src/index.tsx" type="module"></script>
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,14 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "linkpulse",
|
"name": "linkpulse",
|
||||||
|
"private": true,
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"author": "Xevion <xevion@xevion.dev>",
|
"author": {
|
||||||
|
"name": "Xevion",
|
||||||
|
"url": "https://xevion.dev",
|
||||||
|
"email": "xevion@xevion.dev"
|
||||||
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"engines": {
|
"scripts": {
|
||||||
"node": ">=22.0.0",
|
"dev": "vite",
|
||||||
"pnpm": ">=9.0.0"
|
"build": "tsc -b && vite build",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@radix-ui/react-slot": "^1.1.0",
|
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"lucide-react": "^0.456.0",
|
"lucide-react": "^0.456.0",
|
||||||
@@ -18,46 +24,21 @@
|
|||||||
"tailwindcss-animate": "^1.0.7"
|
"tailwindcss-animate": "^1.0.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ianvs/prettier-plugin-sort-imports": "^4.2.1",
|
"@eslint/js": "^9.13.0",
|
||||||
"@swc/core": "^1.6.5",
|
|
||||||
"@types/node": "^22.9.0",
|
"@types/node": "^22.9.0",
|
||||||
"@types/react": "^18.3.3",
|
"@types/react": "^18.3.12",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.1",
|
||||||
"@vitejs/plugin-react": "^4.3.1",
|
"@vitejs/plugin-react-swc": "^3.5.0",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.20",
|
||||||
"eslint": "^9",
|
"eslint": "^9.13.0",
|
||||||
"npm-run-all2": "^6.2.0",
|
"eslint-plugin-react-hooks": "^5.0.0",
|
||||||
"postcss": "^8.4.38",
|
"eslint-plugin-react-refresh": "^0.4.14",
|
||||||
"prettier": "^3.3.2",
|
"globals": "^15.11.0",
|
||||||
"prettier-plugin-tailwindcss": "^0.6.5",
|
"postcss": "^8.4.47",
|
||||||
"tailwindcss": "^3.4.4",
|
"tailwindcss": "^3.4.14",
|
||||||
"ts-node": "^10.9.2",
|
"typescript": "~5.6.2",
|
||||||
"typescript": "^5.5.2",
|
"typescript-eslint": "^8.11.0",
|
||||||
"vite": "^5.3.1",
|
"vite": "^5.4.10",
|
||||||
"vitest": "^1.6.0"
|
"vitest": "^2.1.4"
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"preinstall": "command -v git >/dev/null 2>&1 && git config core.hooksPath git-hooks || true",
|
|
||||||
"build": "vite build",
|
|
||||||
"dev:update-deps": "rm -rf pnpm-lock.yaml node_modules/ **/node_modules && pnpm install",
|
|
||||||
"dev": "vite dev",
|
|
||||||
"format": "prettier --write .",
|
|
||||||
"lint:format": "prettier --cache --check .",
|
|
||||||
"lint": "eslint --cache .",
|
|
||||||
"test": "npm-run-all --parallel tsc:check vitest:run lint lint:format",
|
|
||||||
"tsc:check": "tsc",
|
|
||||||
"vitest:run": "vitest run"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not op_mini all"
|
|
||||||
],
|
|
||||||
"pnpm": {
|
|
||||||
"updateConfig": {
|
|
||||||
"ignoreDependencies": [
|
|
||||||
"eslint"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1670
frontend/pnpm-lock.yaml
generated
1670
frontend/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
module.exports = {
|
export default {
|
||||||
plugins: {
|
plugins: {
|
||||||
autoprefixer: {},
|
|
||||||
tailwindcss: {},
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
@@ -1,26 +1,42 @@
|
|||||||
@tailwind base;
|
#root {
|
||||||
@tailwind components;
|
max-width: 1280px;
|
||||||
@tailwind utilities;
|
margin: 0 auto;
|
||||||
|
padding: 2rem;
|
||||||
:root {
|
text-align: center;
|
||||||
--background-color: #fff;
|
|
||||||
--text-color: #111;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
.logo {
|
||||||
:root {
|
height: 6em;
|
||||||
--background-color: rgb(20, 20, 20);
|
padding: 1.5em;
|
||||||
--text-color: rgb(230, 230, 230);
|
will-change: filter;
|
||||||
|
transition: filter 300ms;
|
||||||
|
}
|
||||||
|
.logo:hover {
|
||||||
|
filter: drop-shadow(0 0 2em #646cffaa);
|
||||||
|
}
|
||||||
|
.logo.react:hover {
|
||||||
|
filter: drop-shadow(0 0 2em #61dafbaa);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes logo-spin {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
background-color: var(--background-color);
|
a:nth-of-type(2) .logo {
|
||||||
color: var(--text-color);
|
animation: logo-spin infinite 20s linear;
|
||||||
}
|
|
||||||
|
|
||||||
@layer base {
|
|
||||||
:root {
|
|
||||||
--radius: 0.5rem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
padding: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.read-the-docs {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,91 +1,33 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useState } from "react";
|
||||||
|
import "./App.css";
|
||||||
|
|
||||||
const backendUrl = import.meta.env.PROD
|
function App() {
|
||||||
? '/api'
|
const [count, setCount] = useState(0);
|
||||||
: `http://${import.meta.env.VITE_BACKEND_TARGET}/api`;
|
|
||||||
|
|
||||||
const Code = (props: JSX.IntrinsicElements['code']) => (
|
|
||||||
<code
|
|
||||||
className="border-1 2py-1 mx-1 rounded border border-pink-500 bg-neutral-100 px-1 font-mono font-light text-pink-500 dark:border-pink-400 dark:bg-neutral-700 dark:text-pink-400"
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
type SeenIP = {
|
|
||||||
last_seen: string;
|
|
||||||
ip: string;
|
|
||||||
count: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function App() {
|
|
||||||
const [seenIps, setSeenIps] = useState<SeenIP[]>([]);
|
|
||||||
const [error, setError] = useState<string | null>(null);
|
|
||||||
|
|
||||||
const refreshData = async () => {
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${backendUrl}/ips`);
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Error: ${response.statusText}`);
|
|
||||||
}
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
setSeenIps(data.ips);
|
|
||||||
setError(null); // Clear any previous errors
|
|
||||||
console.log('Data fetched:', data);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching data:', error);
|
|
||||||
setError(error.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Refresh data on component mount and every 30 seconds
|
|
||||||
useEffect(() => {
|
|
||||||
refreshData();
|
|
||||||
|
|
||||||
const interval = setInterval(
|
|
||||||
() => {
|
|
||||||
refreshData();
|
|
||||||
},
|
|
||||||
(import.meta.env.DEV ? 3 : 30) * 1000,
|
|
||||||
);
|
|
||||||
|
|
||||||
return () => clearInterval(interval);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-full min-w-full">
|
<>
|
||||||
<div className="mx-auto my-8 mt-10 w-8/12 max-w-md rounded border border-gray-200 p-4 shadow-md dark:border-neutral-600 dark:bg-neutral-800 dark:shadow-none">
|
<div>
|
||||||
<h1 className="mb-4 text-3xl">LinkPulse</h1>
|
<a href="https://vite.dev" target="_blank">
|
||||||
|
<img className="logo" alt="Vite logo" />
|
||||||
{error && (
|
</a>
|
||||||
<div className="mb-4 rounded border border-red-500 bg-red-100 p-2 text-red-700 dark:border-red-800/50 dark:bg-red-950/50 dark:text-red-400">
|
<a href="https://react.dev" target="_blank">
|
||||||
{error}
|
<img className="logo react" alt="React logo" />
|
||||||
</div>
|
</a>
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="relative overflow-x-auto">
|
|
||||||
<table className="w-full text-left text-sm text-gray-500 rtl:text-right dark:text-gray-300">
|
|
||||||
<tbody>
|
|
||||||
{error == null
|
|
||||||
? seenIps.map((ip) => (
|
|
||||||
<tr
|
|
||||||
key={ip.ip}
|
|
||||||
className="border-b bg-white last:border-0 dark:border-neutral-700 dark:bg-neutral-800"
|
|
||||||
>
|
|
||||||
<td className="py-4">
|
|
||||||
<Code>{ip.ip}</Code>
|
|
||||||
</td>
|
|
||||||
<td className="py-4">
|
|
||||||
{ip.count} time{ip.count > 1 ? 's' : ''}
|
|
||||||
</td>
|
|
||||||
<td className="py-4">{ip.last_seen}</td>
|
|
||||||
</tr>
|
|
||||||
))
|
|
||||||
: null}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<h1>Vite + React</h1>
|
||||||
|
<div className="card">
|
||||||
|
<button onClick={() => setCount((count) => count + 1)}>
|
||||||
|
count is {count}
|
||||||
|
</button>
|
||||||
|
<p>
|
||||||
|
Edit <code>src/App.tsx</code> and save to test HMR
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<p className="read-the-docs">
|
||||||
|
Click on the Vite and React logos to learn more
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default App;
|
||||||
|
|||||||
137
frontend/src/index.css
Normal file
137
frontend/src/index.css
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
:root {
|
||||||
|
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
color-scheme: light dark;
|
||||||
|
color: rgba(255, 255, 255, 0.87);
|
||||||
|
background-color: #242424;
|
||||||
|
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #646cff;
|
||||||
|
text-decoration: inherit;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #535bf2;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
place-items: center;
|
||||||
|
min-width: 320px;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 3.2em;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
padding: 0.6em 1.2em;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 500;
|
||||||
|
font-family: inherit;
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 0.25s;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
border-color: #646cff;
|
||||||
|
}
|
||||||
|
button:focus,
|
||||||
|
button:focus-visible {
|
||||||
|
outline: 4px auto -webkit-focus-ring-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
:root {
|
||||||
|
color: #213547;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #747bff;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
:root {
|
||||||
|
--background: 0 0% 100%;
|
||||||
|
--foreground: 240 10% 3.9%;
|
||||||
|
--card: 0 0% 100%;
|
||||||
|
--card-foreground: 240 10% 3.9%;
|
||||||
|
--popover: 0 0% 100%;
|
||||||
|
--popover-foreground: 240 10% 3.9%;
|
||||||
|
--primary: 240 5.9% 10%;
|
||||||
|
--primary-foreground: 0 0% 98%;
|
||||||
|
--secondary: 240 4.8% 95.9%;
|
||||||
|
--secondary-foreground: 240 5.9% 10%;
|
||||||
|
--muted: 240 4.8% 95.9%;
|
||||||
|
--muted-foreground: 240 3.8% 46.1%;
|
||||||
|
--accent: 240 4.8% 95.9%;
|
||||||
|
--accent-foreground: 240 5.9% 10%;
|
||||||
|
--destructive: 0 84.2% 60.2%;
|
||||||
|
--destructive-foreground: 0 0% 98%;
|
||||||
|
--border: 240 5.9% 90%;
|
||||||
|
--input: 240 5.9% 90%;
|
||||||
|
--ring: 240 10% 3.9%;
|
||||||
|
--chart-1: 12 76% 61%;
|
||||||
|
--chart-2: 173 58% 39%;
|
||||||
|
--chart-3: 197 37% 24%;
|
||||||
|
--chart-4: 43 74% 66%;
|
||||||
|
--chart-5: 27 87% 67%;
|
||||||
|
--radius: 0.5rem;
|
||||||
|
}
|
||||||
|
.dark {
|
||||||
|
--background: 240 10% 3.9%;
|
||||||
|
--foreground: 0 0% 98%;
|
||||||
|
--card: 240 10% 3.9%;
|
||||||
|
--card-foreground: 0 0% 98%;
|
||||||
|
--popover: 240 10% 3.9%;
|
||||||
|
--popover-foreground: 0 0% 98%;
|
||||||
|
--primary: 0 0% 98%;
|
||||||
|
--primary-foreground: 240 5.9% 10%;
|
||||||
|
--secondary: 240 3.7% 15.9%;
|
||||||
|
--secondary-foreground: 0 0% 98%;
|
||||||
|
--muted: 240 3.7% 15.9%;
|
||||||
|
--muted-foreground: 240 5% 64.9%;
|
||||||
|
--accent: 240 3.7% 15.9%;
|
||||||
|
--accent-foreground: 0 0% 98%;
|
||||||
|
--destructive: 0 62.8% 30.6%;
|
||||||
|
--destructive-foreground: 0 0% 98%;
|
||||||
|
--border: 240 3.7% 15.9%;
|
||||||
|
--input: 240 3.7% 15.9%;
|
||||||
|
--ring: 240 4.9% 83.9%;
|
||||||
|
--chart-1: 220 70% 50%;
|
||||||
|
--chart-2: 160 60% 45%;
|
||||||
|
--chart-3: 30 80% 55%;
|
||||||
|
--chart-4: 280 65% 60%;
|
||||||
|
--chart-5: 340 75% 55%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
* {
|
||||||
|
@apply border-border;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
@apply bg-background text-foreground;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import App from './App.tsx';
|
|
||||||
import './App.css';
|
|
||||||
import { StrictMode } from 'react';
|
|
||||||
import { createRoot } from 'react-dom/client';
|
|
||||||
|
|
||||||
createRoot(document.getElementById('root')!).render(
|
|
||||||
<StrictMode>
|
|
||||||
<App />
|
|
||||||
</StrictMode>,
|
|
||||||
);
|
|
||||||
10
frontend/src/main.tsx
Normal file
10
frontend/src/main.tsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { StrictMode } from 'react'
|
||||||
|
import { createRoot } from 'react-dom/client'
|
||||||
|
import './index.css'
|
||||||
|
import App from './App.tsx'
|
||||||
|
|
||||||
|
createRoot(document.getElementById('root')!).render(
|
||||||
|
<StrictMode>
|
||||||
|
<App />
|
||||||
|
</StrictMode>,
|
||||||
|
)
|
||||||
1
frontend/src/vite-env.d.ts
vendored
Normal file
1
frontend/src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
|
||||||
module.exports = {
|
|
||||||
content: ['./src/**/*.{js,jsx,ts,tsx}', './*.html'],
|
|
||||||
darkMode: ['media', 'class'],
|
|
||||||
mode: 'jit',
|
|
||||||
theme: {
|
|
||||||
extend: {
|
|
||||||
fontFamily: {
|
|
||||||
inter: ['Inter', 'sans-serif']
|
|
||||||
},
|
|
||||||
borderRadius: {
|
|
||||||
lg: 'var(--radius)',
|
|
||||||
md: 'calc(var(--radius) - 2px)',
|
|
||||||
sm: 'calc(var(--radius) - 4px)'
|
|
||||||
},
|
|
||||||
colors: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
plugins: [require("tailwindcss-animate")]
|
|
||||||
};
|
|
||||||
57
frontend/tailwind.config.js
Normal file
57
frontend/tailwind.config.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
export default {
|
||||||
|
darkMode: ["class"],
|
||||||
|
content: ["./index.html", "./src/**/*.{ts,tsx,js,jsx}"],
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
borderRadius: {
|
||||||
|
lg: 'var(--radius)',
|
||||||
|
md: 'calc(var(--radius) - 2px)',
|
||||||
|
sm: 'calc(var(--radius) - 4px)'
|
||||||
|
},
|
||||||
|
colors: {
|
||||||
|
background: 'hsl(var(--background))',
|
||||||
|
foreground: 'hsl(var(--foreground))',
|
||||||
|
card: {
|
||||||
|
DEFAULT: 'hsl(var(--card))',
|
||||||
|
foreground: 'hsl(var(--card-foreground))'
|
||||||
|
},
|
||||||
|
popover: {
|
||||||
|
DEFAULT: 'hsl(var(--popover))',
|
||||||
|
foreground: 'hsl(var(--popover-foreground))'
|
||||||
|
},
|
||||||
|
primary: {
|
||||||
|
DEFAULT: 'hsl(var(--primary))',
|
||||||
|
foreground: 'hsl(var(--primary-foreground))'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
DEFAULT: 'hsl(var(--secondary))',
|
||||||
|
foreground: 'hsl(var(--secondary-foreground))'
|
||||||
|
},
|
||||||
|
muted: {
|
||||||
|
DEFAULT: 'hsl(var(--muted))',
|
||||||
|
foreground: 'hsl(var(--muted-foreground))'
|
||||||
|
},
|
||||||
|
accent: {
|
||||||
|
DEFAULT: 'hsl(var(--accent))',
|
||||||
|
foreground: 'hsl(var(--accent-foreground))'
|
||||||
|
},
|
||||||
|
destructive: {
|
||||||
|
DEFAULT: 'hsl(var(--destructive))',
|
||||||
|
foreground: 'hsl(var(--destructive-foreground))'
|
||||||
|
},
|
||||||
|
border: 'hsl(var(--border))',
|
||||||
|
input: 'hsl(var(--input))',
|
||||||
|
ring: 'hsl(var(--ring))',
|
||||||
|
chart: {
|
||||||
|
'1': 'hsl(var(--chart-1))',
|
||||||
|
'2': 'hsl(var(--chart-2))',
|
||||||
|
'3': 'hsl(var(--chart-3))',
|
||||||
|
'4': 'hsl(var(--chart-4))',
|
||||||
|
'5': 'hsl(var(--chart-5))'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: [require("tailwindcss-animate")],
|
||||||
|
};
|
||||||
30
frontend/tsconfig.app.json
Normal file
30
frontend/tsconfig.app.json
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
"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,
|
||||||
|
"noUncheckedSideEffectImports": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
@@ -1,37 +1,13 @@
|
|||||||
{
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{ "path": "./tsconfig.app.json" },
|
||||||
|
{ "path": "./tsconfig.node.json" }
|
||||||
|
],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"allowJs": true,
|
|
||||||
"allowImportingTsExtensions": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"incremental": true,
|
|
||||||
"isolatedModules": true,
|
|
||||||
"jsx": "preserve",
|
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
|
||||||
"module": "nodenext",
|
|
||||||
"moduleResolution": "nodenext",
|
|
||||||
"noEmit": true,
|
|
||||||
"noImplicitOverride": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"strict": true,
|
|
||||||
"target": "es2017",
|
|
||||||
"types": ["vite/client"],
|
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"]
|
"@/*": ["./src/*"]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"exclude": ["node_modules"],
|
|
||||||
"include": ["**/*.ts", "**/*.tsx"],
|
|
||||||
"ts-node": {
|
|
||||||
"transpileOnly": true,
|
|
||||||
"transpiler": "ts-node/transpilers/swc",
|
|
||||||
"files": true,
|
|
||||||
"compilerOptions": {
|
|
||||||
"module": "esnext",
|
|
||||||
"isolatedModules": false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
frontend/tsconfig.node.json
Normal file
28
frontend/tsconfig.node.json
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
"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,
|
||||||
|
"noUncheckedSideEffectImports": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
import path from 'path';
|
import path from 'path'
|
||||||
import react from '@vitejs/plugin-react';
|
import { defineConfig } from 'vite'
|
||||||
import { defineConfig } from 'vite';
|
import react from '@vitejs/plugin-react-swc'
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': path.resolve(__dirname, './src'),
|
"@": path.resolve(__dirname, "./src"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user