From 17efa613bf408c6aa3ab8210355e508d868e0faa Mon Sep 17 00:00:00 2001 From: CarterPerez-dev Date: Sat, 28 Feb 2026 10:34:02 -0500 Subject: [PATCH] feat(frontend): strip auth and configure for AngelusVigil Strip the fullstack template of all auth/user/admin code and reconfigure for the AngelusVigil threat detection dashboard with 3 pages. --- .../frontend/.dockerignore | 15 + .../ai-threat-detection/frontend/.gitignore | 25 ++ .../frontend/.stylelintignore | 22 ++ .../ai-threat-detection/frontend/biome.json | 94 +++++ .../ai-threat-detection/frontend/index.html | 44 +++ .../ai-threat-detection/frontend/package.json | 50 +++ .../public/assets/android-chrome-192x192.png | Bin 0 -> 9404 bytes .../public/assets/android-chrome-512x512.png | Bin 0 -> 100370 bytes .../public/assets/apple-touch-icon.png | Bin 0 -> 8307 bytes .../frontend/public/assets/favicon-16x16.png | Bin 0 -> 279 bytes .../frontend/public/assets/favicon-32x32.png | Bin 0 -> 565 bytes .../frontend/public/assets/favicon.ico | Bin 0 -> 15406 bytes .../frontend/public/assets/site.webmanifest | 1 + .../ai-threat-detection/frontend/src/App.tsx | 35 ++ .../frontend/src/api/hooks/index.ts | 4 + .../frontend/src/api/index.ts | 7 + .../frontend/src/api/types/index.ts | 4 + .../frontend/src/components/index.tsx | 4 + .../frontend/src/config.ts | 78 +++++ .../frontend/src/core/api/api.config.ts | 24 ++ .../frontend/src/core/api/errors.ts | 100 ++++++ .../frontend/src/core/api/index.ts | 8 + .../frontend/src/core/api/query.config.ts | 98 ++++++ .../frontend/src/core/app/routers.tsx | 34 ++ .../frontend/src/core/app/shell.module.scss | 331 ++++++++++++++++++ .../frontend/src/core/app/shell.tsx | 118 +++++++ .../frontend/src/core/app/toast.module.scss | 67 ++++ .../ai-threat-detection/frontend/src/main.tsx | 15 + .../src/pages/dashboard/dashboard.module.scss | 152 ++++++++ .../frontend/src/pages/dashboard/index.tsx | 10 + .../frontend/src/pages/models/index.tsx | 10 + .../frontend/src/pages/threats/index.tsx | 10 + .../frontend/src/styles.scss | 29 ++ .../frontend/src/styles/_fonts.scss | 12 + .../frontend/src/styles/_index.scss | 8 + .../frontend/src/styles/_mixins.scss | 120 +++++++ .../frontend/src/styles/_reset.scss | 198 +++++++++++ .../frontend/src/styles/_tokens.scss | 168 +++++++++ .../frontend/stylelint.config.js | 107 ++++++ .../frontend/tsconfig.app.json | 31 ++ .../frontend/tsconfig.json | 7 + .../frontend/tsconfig.node.json | 24 ++ .../frontend/vite.config.ts | 71 ++++ 43 files changed, 2135 insertions(+) create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/.dockerignore create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/.gitignore create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/.stylelintignore create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/biome.json create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/index.html create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/package.json create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/public/assets/android-chrome-192x192.png create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/public/assets/android-chrome-512x512.png create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/public/assets/apple-touch-icon.png create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/public/assets/favicon-16x16.png create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/public/assets/favicon-32x32.png create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/public/assets/favicon.ico create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/public/assets/site.webmanifest create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/App.tsx create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/api/hooks/index.ts create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/api/index.ts create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/api/types/index.ts create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/components/index.tsx create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/config.ts create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/api.config.ts create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/errors.ts create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/index.ts create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/query.config.ts create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/routers.tsx create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/shell.module.scss create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/shell.tsx create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/toast.module.scss create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/main.tsx create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/pages/dashboard/dashboard.module.scss create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/pages/dashboard/index.tsx create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/pages/models/index.tsx create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/pages/threats/index.tsx create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/styles.scss create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_fonts.scss create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_index.scss create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_mixins.scss create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_reset.scss create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_tokens.scss create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/stylelint.config.js create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/tsconfig.app.json create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/tsconfig.json create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/tsconfig.node.json create mode 100644 PROJECTS/advanced/ai-threat-detection/frontend/vite.config.ts diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/.dockerignore b/PROJECTS/advanced/ai-threat-detection/frontend/.dockerignore new file mode 100644 index 00000000..a0256ec7 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/.dockerignore @@ -0,0 +1,15 @@ +node_modules +build +dist +.git +.gitignore +*.md +.env* +.vscode +.idea +*.log +npm-debug.log* +pnpm-debug.log* +.DS_Store +coverage +.nyc_output diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/.gitignore b/PROJECTS/advanced/ai-threat-detection/frontend/.gitignore new file mode 100644 index 00000000..61cb0c2e --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/.gitignore @@ -0,0 +1,25 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local +.vite + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/.stylelintignore b/PROJECTS/advanced/ai-threat-detection/frontend/.stylelintignore new file mode 100644 index 00000000..37da03e1 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/.stylelintignore @@ -0,0 +1,22 @@ +# ©AngelaMos | 2025 +# .stylelintignore + +# Dependencies +node_modules/ + +# Production builds +dist/ +build/ +out/ + +# JS/TS files +**/*.js +**/*.jsx +**/*.ts +**/*.tsx + +# Generated files +*.min.css + +# Error system styles - ignore from linting +src/core/app/_toastStyles.scss diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/biome.json b/PROJECTS/advanced/ai-threat-detection/frontend/biome.json new file mode 100644 index 00000000..7f29029a --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/biome.json @@ -0,0 +1,94 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.3.8/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "includes": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "**/*.json"] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 2, + "lineWidth": 82, + "lineEnding": "lf" + }, + "javascript": { + "formatter": { + "quoteStyle": "single", + "jsxQuoteStyle": "double", + "semicolons": "asNeeded", + "trailingCommas": "es5", + "arrowParentheses": "always" + } + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "complexity": { + "noExcessiveCognitiveComplexity": { + "level": "error", + "options": { "maxAllowedComplexity": 25 } + }, + "noForEach": "off", + "useLiteralKeys": "off" + }, + "correctness": { + "noUnusedVariables": "error", + "noUnusedImports": "error", + "useExhaustiveDependencies": "warn", + "useHookAtTopLevel": "error", + "noUndeclaredVariables": "error" + }, + "style": { + "useImportType": "error", + "useConst": "error", + "useTemplate": "error", + "useSelfClosingElements": "error", + "useFragmentSyntax": "error", + "noNonNullAssertion": "error", + "useConsistentArrayType": { + "level": "error", + "options": { "syntax": "shorthand" } + }, + "useNamingConvention": "off" + }, + "suspicious": { + "noExplicitAny": "error", + "noDebugger": "error", + "noConsole": "warn", + "noArrayIndexKey": "warn", + "noAssignInExpressions": "error", + "noDoubleEquals": "error", + "noRedeclare": "error", + "noVar": "error" + }, + "security": { + "noDangerouslySetInnerHtml": "error" + }, + "a11y": { + "useAltText": "error", + "useAnchorContent": "error", + "useKeyWithClickEvents": "error", + "noStaticElementInteractions": "error", + "useButtonType": "error", + "useValidAnchor": "error" + } + } + }, + "overrides": [ + { + "includes": ["src/main.tsx"], + "linter": { + "rules": { + "style": { + "noNonNullAssertion": "off" + } + } + } + } + ] +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/index.html b/PROJECTS/advanced/ai-threat-detection/frontend/index.html new file mode 100644 index 00000000..9d7b000a --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/index.html @@ -0,0 +1,44 @@ + + + + + + + + + + AngelusVigil + + + + +
+ + + diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/package.json b/PROJECTS/advanced/ai-threat-detection/frontend/package.json new file mode 100644 index 00000000..ddddc732 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/package.json @@ -0,0 +1,50 @@ +{ + "name": "frontend-template", + "private": true, + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview", + "lint": "biome check .", + "lint:fix": "biome check --write .", + "format": "biome format --write .", + "typecheck": "tsc -b", + "lint:scss": "stylelint '**/*.scss'", + "lint:scss:fix": "stylelint '**/*.scss' --fix" + }, + "dependencies": { + "@tanstack/react-query": "^5.90.20", + "axios": "^1.13.4", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "react-error-boundary": "^6.1.0", + "react-icon": "^1.0.0", + "react-icons": "^5.5.0", + "react-router-dom": "^7.13.0", + "sonner": "^2.0.7", + "zod": "^4.3.6", + "zustand": "^5.0.10" + }, + "devDependencies": { + "@biomejs/biome": "^2.3.13", + "@tanstack/react-query-devtools": "^5.91.2", + "@types/node": "^25.1.0", + "@types/react": "^19.2.10", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^5.1.2", + "sass": "^1.97.3", + "stylelint": "^17.0.0", + "stylelint-config-prettier-scss": "^1.0.0", + "stylelint-config-standard-scss": "^17.0.0", + "typescript": "~5.9.3", + "vite": "npm:rolldown-vite@7.3.1", + "vite-tsconfig-paths": "^6.0.5" + }, + "pnpm": { + "overrides": { + "vite": "npm:rolldown-vite@7.2.5" + } + } +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/public/assets/android-chrome-192x192.png b/PROJECTS/advanced/ai-threat-detection/frontend/public/assets/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..587a3c2943d25f8b89543404bff19b241440d662 GIT binary patch literal 9404 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 a(10vJbm)DiAQz+tATO;fRV@Mj_P+oTWy%Qv literal 0 HcmV?d00001 diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/public/assets/android-chrome-512x512.png b/PROJECTS/advanced/ai-threat-detection/frontend/public/assets/android-chrome-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..d4b40f140d021cea2cbdf70f387104770165ecc6 GIT binary patch literal 100370 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�_ZTBeEU~3uiXGW9p+k3I9 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

U2H; zdu<%8K6u~Z>uZRMTDbnXq);S0B{WVHKij4pIr+Qj0yjh3rH{?}(*T$FBlj)6Ezk)B zFdD#&{IKsQIUnW)oAZ0HO6D%1_r&me_m7;3Qdo)bAn-EM$Y55{Nw;T(nXy%<^n1+6 z31V#vdEf4-NE;V&f6ffe+>lIzag8HE<02F z7Pfq`8(wbFyC3Ik?$M7YzD_n<=ReRJaQC?rF$X?jcfZVQT0Txt96iNKJ`#FTKpthO zxq}Xfx;0=Fug?|U@z-~KPxMD-tqm7J8@ zfiy+nGii_;7PydRWcn)okuI))a^KGa*dK#wAoNE3yj;9x6n7 zZ6-5iaJ09@3vm3en(a8!VbVD$SIXh9#iDfA^V+|uhO^aN*G88P(7pFWYyyc?o4 z&{s*OWaGQ0K|FA6wU~4Rsd~Pi<4A4`v1Rq=#N4bgpK_e(tJxiln}0mgw@^mt#Rm=+ z3o;YLjPW|%{HDYxeE#@)1=qjla$1?oU-#R*+!l%k{=;PWAV;hE1^#(BCv}7@^1b=$ zU}ZXGe$uV3j_`-6d~zl!cxQ=l8vREkX7MB+90eZ!cN8Hd1%EHEu69&B{*}WnkjB5; z_7~GF(3jqt%&R|IlMrsmDlo1$5h_wxS8*F(*`h@S9cR~g09WhyDZ)p{-BZgujf9Hq zlWYzLt%?rdO6z@8@`uE-;n~Ep1D3pg@imf83tS9}xRWh+z)7T&N&S0Gill$Vl$uW= zdvGS%240Ws`_A2@4I_w1GrQ>PQlOM| zveFPmU;FqKzC8f%-@X9KBKr)LLtDNN+pjvN&$JdMVD?bjKHE&7?>Ev#$MOmEX$wK9cXb&EZPUhClLC z8y5Zl9V&X@wapn%>0>J{{7_!08r;4p&q1YW-Smd(6<1Uk_eQh$J-osA>w=TB+Kc=0 zFDw*&rY^ADaD(yV!Q*Imt)x^Qs97KoJH{S3j3^P6L#@tQztDYMf~Yl1qp$W7#LU?5PS>fIKSD zwhrN21VvGnNkhqjvTGyHcoZLU?nek|26;jAXUxMOVCA>S)%cMX(7Ms4b#s{s8s{C2 zCu5I#I6)Tz9_)DB>P$#X18c*kb7u|N&}9qfFE{bE8i~L?%i;dmCb8$qGm*w~>GqHV19rPJQd`{e-dMJ+{1ObF_Zhw% zpv}#CXRQVc8%@k>OBAaO#L55#(T4!{>8_Z|4QU6;c5y#pL2PrUQ^RW4sOuAqFveQe zF~yfRFV2y=VkaOUY69Gt%umU`hv?!5bT_}SxA~Q5XGHQTz*;l#-}&`T8V?Ze@w1s|Xw1aisU>}q%?S>{c zXtxRIHrQ0PonVYf6KM2>KLPQ?!~P5&c;%VrALqJDX)6_#DN!Q0mX3UVuW!z|=lsse z@jX`%_6R;f6a~7Q!ntZe=n(|LG}oV<7D0GKeO+Bo$J2uFL=pst-k~WpW4)hlJ6)gw zPDR#1y;+aFp}nYXs)j%9|5y60s;xrmQxp0z8Ih3?>_yZ2o!#0g_+ks3OJO8V1Yu4E z;mm~)84mAShWN<{jN|=?P7J_!`v9WHMvGD{_n>U2~ms9dHbA z3=|y$(m)t32ZB%rm5tvHbO*r5IBjh7l`00cUWy_y+lus6bAy*MAwi>@DECv_MqerT z*Xea|K8vC4%Oov~Btmynh2ZONY5=c?L>+k;+4Z}~+I<3Jb z8~A%3z(4sr62~pVWdho;T6F#l&w*Tk^6eNJx_?A$vWs$PvN`D>{;r9@;qS-}87Oa+ z#{LEV_C*=;3yNn4W^YE!_WF>FIQgM6Qd<6*YY}9~2MXjef4K6Ls9h@jv-Pv@kH{c> zdksoEl0VT<65E#|p7G!0c{0ZU$3U4eK6QzVc)i)PwQyE-@avR%R0-n7IjR9d)I8+kX?$yy&Z*p%dQyt)o~5ZyzK40vpR^k_dZ9p zm$@L-Mu@03!|FhVT9Eh7?R44Y_tp8lGf(<)1MWQeZ$b7;5{yaOPk&8>Iw(RvDkGJb zx61!j%A3ouRWAI?LlQdH9AqC@u<861li#75hcPBXdtIbDP=H88e6j`7^UYpOrm)7$ z9RnRdILNFxWs_eWk>K8lcsOC0aq?jp<8f$5OjvY|%E<@4IvT5`seJ~F5fiDi6sJ5a z1(BkfTKh`*{6Kv(g4{zJ?Mo)?i(#1WxbWxhqhbFV)dF9JbAfC^b+E*gg{FPWUVTg* z==au{`9eeIJ&IM!nX>7ho%L&o)gyMwfPFil{gGBFi~Hu@Z- ziHB%@=^I#QbhtNDWz+lic%hD{B)@{t{yqfSdXYR$bxiW(fq3lSe(L$P=dU3o&xW84kl(WU@U05cKgsW2kHDoEx}Dg$RGa;O zvGWCto<6%3B)|NsgzSoi?A-*icXps{WA;L_V({;)_n}U!{hQQH?alq0+U%_Ic0c0J p+rF8~^ew^d!0o^>z%jrvz%jrvz%jrv@Sny2nU`N&1J9;`zW}i};{*Tz literal 0 HcmV?d00001 diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/public/assets/site.webmanifest b/PROJECTS/advanced/ai-threat-detection/frontend/public/assets/site.webmanifest new file mode 100644 index 00000000..1dd91123 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/public/assets/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/App.tsx b/PROJECTS/advanced/ai-threat-detection/frontend/src/App.tsx new file mode 100644 index 00000000..efbd5388 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/App.tsx @@ -0,0 +1,35 @@ +// =================== +// © AngelaMos | 2026 +// App.tsx +// =================== + +import { QueryClientProvider } from '@tanstack/react-query' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' +import { RouterProvider } from 'react-router-dom' +import { Toaster } from 'sonner' + +import { queryClient } from '@/core/api' +import { router } from '@/core/app/routers' + +export default function App(): React.ReactElement { + return ( + +
+ + +
+ +
+ ) +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/api/hooks/index.ts b/PROJECTS/advanced/ai-threat-detection/frontend/src/api/hooks/index.ts new file mode 100644 index 00000000..6221af9a --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/api/hooks/index.ts @@ -0,0 +1,4 @@ +// =================== +// © AngelaMos | 2026 +// index.ts +// =================== diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/api/index.ts b/PROJECTS/advanced/ai-threat-detection/frontend/src/api/index.ts new file mode 100644 index 00000000..8eb1f51a --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/api/index.ts @@ -0,0 +1,7 @@ +// =================== +// © AngelaMos | 2026 +// index.ts +// =================== + +export * from './hooks' +export * from './types' diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/api/types/index.ts b/PROJECTS/advanced/ai-threat-detection/frontend/src/api/types/index.ts new file mode 100644 index 00000000..6221af9a --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/api/types/index.ts @@ -0,0 +1,4 @@ +// =================== +// © AngelaMos | 2026 +// index.ts +// =================== diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/components/index.tsx b/PROJECTS/advanced/ai-threat-detection/frontend/src/components/index.tsx new file mode 100644 index 00000000..9f7eeadd --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/components/index.tsx @@ -0,0 +1,4 @@ +/** + * ©AngelaMos | 2026 + * index.tsx + */ diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/config.ts b/PROJECTS/advanced/ai-threat-detection/frontend/src/config.ts new file mode 100644 index 00000000..f608e046 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/config.ts @@ -0,0 +1,78 @@ +// =================== +// © AngelaMos | 2026 +// config.ts +// =================== + +export const API_ENDPOINTS = { + HEALTH: '/health', + READY: '/ready', + THREATS: { + LIST: '/threats', + BY_ID: (id: string) => `/threats/${id}`, + }, + STATS: '/stats', + MODELS: { + STATUS: '/models/status', + RETRAIN: '/models/retrain', + }, +} as const + +export const WS_ENDPOINTS = { + ALERTS: '/ws/alerts', +} as const + +export const QUERY_KEYS = { + THREATS: { + ALL: ['threats'] as const, + LIST: (params: Record) => + [...QUERY_KEYS.THREATS.ALL, 'list', params] as const, + BY_ID: (id: string) => + [...QUERY_KEYS.THREATS.ALL, 'detail', id] as const, + }, + STATS: { + ALL: ['stats'] as const, + BY_RANGE: (range: string) => + [...QUERY_KEYS.STATS.ALL, range] as const, + }, + MODELS: { + ALL: ['models'] as const, + STATUS: () => [...QUERY_KEYS.MODELS.ALL, 'status'] as const, + }, +} as const + +export const ROUTES = { + DASHBOARD: '/', + THREATS: '/threats', + MODELS: '/models', +} as const + +export const STORAGE_KEYS = { + UI: 'ui-storage', +} as const + +export const QUERY_CONFIG = { + STALE_TIME: { + STANDARD: 1000 * 60 * 5, + FREQUENT: 1000 * 30, + STATIC: Infinity, + }, + GC_TIME: { + DEFAULT: 1000 * 60 * 30, + LONG: 1000 * 60 * 60, + }, + RETRY: { + DEFAULT: 3, + NONE: 0, + }, +} as const + +export const PAGINATION = { + DEFAULT_LIMIT: 50, + MAX_LIMIT: 100, +} as const + +export const ALERTS = { + MAX_ITEMS: 50, + RECONNECT_BASE_MS: 1000, + RECONNECT_MAX_MS: 30000, +} as const diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/api.config.ts b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/api.config.ts new file mode 100644 index 00000000..0901c75c --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/api.config.ts @@ -0,0 +1,24 @@ +// =================== +// © AngelaMos | 2026 +// api.config.ts +// =================== + +import axios, { type AxiosError, type AxiosInstance } from 'axios' +import { transformAxiosError } from './errors' + +const getBaseURL = (): string => { + return import.meta.env.VITE_API_URL ?? '/api' +} + +export const apiClient: AxiosInstance = axios.create({ + baseURL: getBaseURL(), + timeout: 15000, + headers: { 'Content-Type': 'application/json' }, +}) + +apiClient.interceptors.response.use( + (response) => response, + (error: AxiosError): Promise => { + return Promise.reject(transformAxiosError(error)) + }, +) diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/errors.ts b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/errors.ts new file mode 100644 index 00000000..786c90d4 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/errors.ts @@ -0,0 +1,100 @@ +// =================== +// © AngelaMos | 2026 +// errors.ts +// =================== + +import type { AxiosError } from 'axios' + +export const ApiErrorCode = { + NETWORK_ERROR: 'NETWORK_ERROR', + VALIDATION_ERROR: 'VALIDATION_ERROR', + NOT_FOUND: 'NOT_FOUND', + CONFLICT: 'CONFLICT', + RATE_LIMITED: 'RATE_LIMITED', + SERVER_ERROR: 'SERVER_ERROR', + UNKNOWN_ERROR: 'UNKNOWN_ERROR', +} as const + +export type ApiErrorCode = (typeof ApiErrorCode)[keyof typeof ApiErrorCode] + +export class ApiError extends Error { + readonly code: ApiErrorCode + readonly statusCode: number + readonly details?: Record + + constructor( + message: string, + code: ApiErrorCode, + statusCode: number, + details?: Record, + ) { + super(message) + this.name = 'ApiError' + this.code = code + this.statusCode = statusCode + this.details = details + } + + getUserMessage(): string { + const messages: Record = { + [ApiErrorCode.NETWORK_ERROR]: + 'Unable to connect to the server. Check your connection.', + [ApiErrorCode.VALIDATION_ERROR]: 'Invalid request parameters.', + [ApiErrorCode.NOT_FOUND]: 'The requested resource was not found.', + [ApiErrorCode.CONFLICT]: + 'This operation conflicts with an existing resource.', + [ApiErrorCode.RATE_LIMITED]: + 'Too many requests. Please wait a moment and try again.', + [ApiErrorCode.SERVER_ERROR]: + 'Something went wrong on the server. Please try again later.', + [ApiErrorCode.UNKNOWN_ERROR]: + 'An unexpected error occurred. Please try again.', + } + return messages[this.code] + } +} + +interface ApiErrorResponse { + detail?: string | { msg: string; type: string }[] + message?: string +} + +export function transformAxiosError(error: AxiosError): ApiError { + if (!error.response) { + return new ApiError('Network error', ApiErrorCode.NETWORK_ERROR, 0) + } + + const { status } = error.response + const data = error.response.data as ApiErrorResponse | undefined + let message = 'An error occurred' + const details: Record | undefined = undefined + + if (data?.detail) { + if (typeof data.detail === 'string') { + message = data.detail + } + } else if (data?.message) { + message = data.message + } + + const codeMap: Record = { + 400: ApiErrorCode.VALIDATION_ERROR, + 404: ApiErrorCode.NOT_FOUND, + 409: ApiErrorCode.CONFLICT, + 429: ApiErrorCode.RATE_LIMITED, + 500: ApiErrorCode.SERVER_ERROR, + 502: ApiErrorCode.SERVER_ERROR, + 503: ApiErrorCode.SERVER_ERROR, + 504: ApiErrorCode.SERVER_ERROR, + } + + const code = codeMap[status] || ApiErrorCode.UNKNOWN_ERROR + + return new ApiError(message, code, status, details) +} + +declare module '@tanstack/react-query' { + interface Register { + defaultError: ApiError + } +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/index.ts b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/index.ts new file mode 100644 index 00000000..f6dc3639 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/index.ts @@ -0,0 +1,8 @@ +// =================== +// © AngelaMos | 2026 +// index.ts +// =================== + +export * from './api.config' +export * from './errors' +export * from './query.config' diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/query.config.ts b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/query.config.ts new file mode 100644 index 00000000..c2559e62 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/api/query.config.ts @@ -0,0 +1,98 @@ +// =================== +// © AngelaMos | 2026 +// query.config.ts +// =================== + +import { MutationCache, QueryCache, QueryClient } from '@tanstack/react-query' +import { toast } from 'sonner' +import { QUERY_CONFIG } from '@/config' +import { ApiError, ApiErrorCode } from './errors' + +const NO_RETRY_ERROR_CODES: readonly ApiErrorCode[] = [ + ApiErrorCode.NOT_FOUND, + ApiErrorCode.VALIDATION_ERROR, +] as const + +const shouldRetryQuery = (failureCount: number, error: Error): boolean => { + if (error instanceof ApiError) { + if (NO_RETRY_ERROR_CODES.includes(error.code)) { + return false + } + } + return failureCount < QUERY_CONFIG.RETRY.DEFAULT +} + +const calculateRetryDelay = (attemptIndex: number): number => { + const baseDelay = 1000 + const maxDelay = 30000 + return Math.min(baseDelay * 2 ** attemptIndex, maxDelay) +} + +const handleQueryCacheError = ( + error: Error, + query: { state: { data: unknown } }, +): void => { + if (query.state.data !== undefined) { + const message = + error instanceof ApiError + ? error.getUserMessage() + : 'Background update failed' + toast.error(message) + } +} + +const handleMutationCacheError = ( + error: Error, + _variables: unknown, + _context: unknown, + mutation: { options: { onError?: unknown } }, +): void => { + if (mutation.options.onError === undefined) { + const message = + error instanceof ApiError ? error.getUserMessage() : 'Operation failed' + toast.error(message) + } +} + +export const QUERY_STRATEGIES = { + standard: { + staleTime: QUERY_CONFIG.STALE_TIME.STANDARD, + gcTime: QUERY_CONFIG.GC_TIME.DEFAULT, + }, + frequent: { + staleTime: QUERY_CONFIG.STALE_TIME.FREQUENT, + gcTime: QUERY_CONFIG.GC_TIME.DEFAULT, + refetchInterval: QUERY_CONFIG.STALE_TIME.FREQUENT, + }, + static: { + staleTime: QUERY_CONFIG.STALE_TIME.STATIC, + gcTime: QUERY_CONFIG.GC_TIME.LONG, + refetchOnMount: false, + refetchOnWindowFocus: false, + }, +} as const + +export type QueryStrategy = keyof typeof QUERY_STRATEGIES + +export const queryClient = new QueryClient({ + defaultOptions: { + queries: { + staleTime: QUERY_CONFIG.STALE_TIME.STANDARD, + gcTime: QUERY_CONFIG.GC_TIME.DEFAULT, + retry: shouldRetryQuery, + retryDelay: calculateRetryDelay, + refetchOnWindowFocus: true, + refetchOnMount: true, + refetchOnReconnect: true, + }, + mutations: { + retry: QUERY_CONFIG.RETRY.NONE, + }, + }, + queryCache: new QueryCache({ + onError: handleQueryCacheError, + }), + mutationCache: new MutationCache({ + onError: handleMutationCacheError, + }), +}) diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/routers.tsx b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/routers.tsx new file mode 100644 index 00000000..2cee809e --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/routers.tsx @@ -0,0 +1,34 @@ +// =================== +// © AngelaMos | 2026 +// routers.tsx +// =================== + +import { Navigate, createBrowserRouter, type RouteObject } from 'react-router-dom' +import { ROUTES } from '@/config' +import { Shell } from './shell' + +const routes: RouteObject[] = [ + { + element: , + children: [ + { + path: ROUTES.DASHBOARD, + lazy: () => import('@/pages/dashboard'), + }, + { + path: ROUTES.THREATS, + lazy: () => import('@/pages/threats'), + }, + { + path: ROUTES.MODELS, + lazy: () => import('@/pages/models'), + }, + ], + }, + { + path: '*', + element: , + }, +] + +export const router = createBrowserRouter(routes) diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/shell.module.scss b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/shell.module.scss new file mode 100644 index 00000000..53789f3c --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/shell.module.scss @@ -0,0 +1,331 @@ +// =================== +// © AngelaMos | 2026 +// shell.module.scss +// =================== + +@use '@/styles' as *; + +$sidebar-width: 240px; +$sidebar-collapsed-width: 64px; +$header-height: 56px; + +.shell { + display: flex; + min-height: 100vh; + min-height: 100dvh; +} + +.sidebar { + position: fixed; + top: 0; + left: 0; + bottom: 0; + width: $sidebar-width; + background: $bg-surface-100; + border-right: 1px solid $border-default; + display: flex; + flex-direction: column; + z-index: $z-fixed; + @include transition-fast; + + &.collapsed { + width: $sidebar-collapsed-width; + } + + @include breakpoint-down('sm') { + transform: translateX(-100%); + + &.open { + transform: translateX(0); + } + + &.collapsed { + width: $sidebar-width; + } + } +} + +.sidebarHeader { + height: $header-height; + padding: 0 $space-3; + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid $border-default; + + .sidebar.collapsed & { + justify-content: center; + padding: 0; + } +} + +.logo { + font-size: $font-size-base; + font-weight: $font-weight-semibold; + color: $text-default; + @include transition-fast; + + .sidebar.collapsed & { + display: none; + } +} + +.nav { + flex: 1; + padding: $space-3; + display: flex; + flex-direction: column; + gap: $space-1; +} + +.navItem { + display: flex; + align-items: center; + gap: $space-3; + padding: $space-2 $space-3; + border-radius: $radius-md; + font-size: $font-size-sm; + color: $text-light; + @include transition-fast; + + @include hover { + background: $bg-surface-200; + color: $text-default; + } + + &.active { + background: $bg-selection; + color: $text-default; + } + + .sidebar.collapsed & { + justify-content: center; + } +} + +.navIcon { + width: 17px; + height: 17px; + flex-shrink: 0; +} + +.navLabel { + @include transition-fast; + + .sidebar.collapsed & { + display: none; + } +} + +.adminItem { + margin-top: auto; + border-top: 1px solid $border-default; + padding-top: $space-3; +} + +.collapseBtn { + width: 45px; + height: 45px; + border-radius: $radius-md; + color: $text-light; + @include flex-center; + @include transition-fast; + + svg { + width: 23.5px; + height: 23.5px; + } + + @include hover { + background: $bg-surface-200; + color: $text-default; + } + + @include breakpoint-down('sm') { + display: none; + } +} + +.sidebarFooter { + padding: $space-3; + border-top: 1px solid $border-default; +} + +.logoutBtn { + width: 100%; + display: flex; + align-items: center; + gap: $space-3; + padding: $space-3; + border-radius: $radius-md; + font-size: $font-size-sm; + color: $text-default; + @include transition-fast; + + @include hover { + background: $bg-surface-200; + } + + .sidebar.collapsed & { + justify-content: center; + + .logoutText { + display: none; + } + } +} + +.logoutIcon { + width: 18px; + height: 18px; + flex-shrink: 0; +} + +.logoutText { + font-weight: $font-weight-medium; + @include transition-fast; +} + +.overlay { + position: fixed; + inset: 0; + background: rgb(0, 0, 0, 50%); + z-index: calc($z-fixed - 1); + display: none; + border: none; + padding: 0; + cursor: pointer; + + @include breakpoint-down('sm') { + display: block; + } +} + +.main { + flex: 1; + display: flex; + flex-direction: column; + margin-left: $sidebar-width; + min-width: 0; + @include transition-fast; + + &.collapsed { + margin-left: $sidebar-collapsed-width; + } + + @include breakpoint-down('sm') { + margin-left: 0; + + &.collapsed { + margin-left: 0; + } + } +} + +.header { + position: sticky; + top: 0; + height: $header-height; + background: $bg-surface-100; + border-bottom: 1px solid $border-default; + z-index: $z-sticky; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 $space-4; +} + +.headerLeft { + display: flex; + align-items: center; + gap: $space-3; +} + +.menuBtn { + display: none; + width: 36px; + height: 36px; + border-radius: $radius-md; + color: $text-light; + align-items: center; + justify-content: center; + @include transition-fast; + + svg { + width: 20px; + height: 20px; + } + + @include hover { + background: $bg-surface-200; + color: $text-default; + } + + @media (width <= 479px) { + display: flex; + } +} + +.pageTitle { + font-size: $font-size-base; + font-weight: $font-weight-medium; + color: $text-default; + margin-left: 7px; +} + +.headerRight { + display: flex; + align-items: center; + gap: $space-3; +} + +.avatar { + width: 32px; + height: 32px; + border-radius: $radius-full; + background: $bg-surface-300; + color: $text-light; + font-size: $font-size-sm; + font-weight: $font-weight-medium; + @include flex-center; + cursor: pointer; + @include transition-fast; + + @include hover { + filter: brightness(1.2); + } +} + +.content { + flex: 1; + overflow-y: auto; +} + +.loading { + @include flex-center; + height: 100%; + color: $text-muted; +} + +.error { + @include flex-column-center; + height: 100%; + gap: $space-4; + padding: $space-6; + color: $error-default; + + h2 { + font-size: $font-size-xl; + font-weight: $font-weight-semibold; + } + + pre { + font-family: $font-mono; + font-size: $font-size-sm; + padding: $space-4; + background: $bg-surface-200; + border-radius: $radius-lg; + overflow-x: auto; + max-width: 100%; + } +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/shell.tsx b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/shell.tsx new file mode 100644 index 00000000..7c564fb1 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/shell.tsx @@ -0,0 +1,118 @@ +// =================== +// © AngelaMos | 2026 +// shell.tsx +// =================== + +import { Suspense } from 'react' +import { ErrorBoundary } from 'react-error-boundary' +import { LuChevronLeft, LuChevronRight, LuCpu, LuLayoutDashboard, LuMenu, LuShield } from 'react-icons/lu' +import { NavLink, Outlet, useLocation } from 'react-router-dom' +import { ROUTES } from '@/config' +import { useUIStore } from '@/core/lib' +import styles from './shell.module.scss' + +const NAV_ITEMS = [ + { path: ROUTES.DASHBOARD, label: 'Dashboard', icon: LuLayoutDashboard }, + { path: ROUTES.THREATS, label: 'Threats', icon: LuShield }, + { path: ROUTES.MODELS, label: 'Models', icon: LuCpu }, +] + +function ShellErrorFallback({ error }: { error: Error }): React.ReactElement { + return ( +
+

Something went wrong

+
{error.message}
+
+ ) +} + +function ShellLoading(): React.ReactElement { + return
Loading...
+} + +function getPageTitle(pathname: string): string { + const item = NAV_ITEMS.find((i) => i.path === pathname) + return item?.label ?? 'Dashboard' +} + +export function Shell(): React.ReactElement { + const location = useLocation() + const { sidebarOpen, sidebarCollapsed, toggleSidebar, toggleSidebarCollapsed } = + useUIStore() + + const pageTitle = getPageTitle(location.pathname) + + return ( +
+ + + {sidebarOpen && ( + +

{pageTitle}

+
+ + +
+ + }> + + + +
+ + + ) +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/toast.module.scss b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/toast.module.scss new file mode 100644 index 00000000..29b3f614 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/core/app/toast.module.scss @@ -0,0 +1,67 @@ +// =================== +// © AngelaMos | 2026 +// toast.module.scss +// =================== + +@use '@/styles' as *; + +:global { + [data-sonner-toaster] { + --normal-bg: #{$bg-surface-100}; + --normal-border: #{$border-default}; + --normal-text: #{$text-default}; + + --success-bg: #{$bg-surface-100}; + --success-border: #{$border-default}; + --success-text: #{$text-default}; + + --error-bg: #{$bg-surface-100}; + --error-border: #{$error-default}; + --error-text: #{$text-default}; + + --warning-bg: #{$bg-surface-100}; + --warning-border: #{$border-default}; + --warning-text: #{$text-default}; + + --info-bg: #{$bg-surface-100}; + --info-border: #{$border-default}; + --info-text: #{$text-default}; + + font-family: $font-sans; + } + + [data-sonner-toast] { + border-radius: $radius-md; + padding: $space-3 $space-4; + font-size: $font-size-sm; + border: 1px solid $border-default; + background: $bg-surface-100; + color: $text-default; + + [data-title] { + font-weight: $font-weight-medium; + } + + [data-description] { + color: $text-light; + font-size: $font-size-xs; + } + + [data-close-button] { + background: none; + border: none; + padding: 0; + cursor: pointer; + color: $text-muted; + @include transition-fast; + + @include hover { + color: $text-default; + } + } + } + + [data-sonner-toast][data-type='error'] { + border-color: $error-default; + } +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/main.tsx b/PROJECTS/advanced/ai-threat-detection/frontend/src/main.tsx new file mode 100644 index 00000000..ac319510 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/main.tsx @@ -0,0 +1,15 @@ +// =========================== +// ©AngelaMos | 2026 +// main.tsx +// =========================== + +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import App from './App' +import './styles.scss' + +createRoot(document.getElementById('root')!).render( + + + +) diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/pages/dashboard/dashboard.module.scss b/PROJECTS/advanced/ai-threat-detection/frontend/src/pages/dashboard/dashboard.module.scss new file mode 100644 index 00000000..ec05e16e --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/pages/dashboard/dashboard.module.scss @@ -0,0 +1,152 @@ +// =================== +// © AngelaMos | 2026 +// dashboard.module.scss +// =================== + +@use '@/styles' as *; + +.page { + min-height: calc(100vh - 56px); + padding: $space-6; + background-color: $bg-default; +} + +.container { + max-width: 800px; + margin: 0 auto; +} + +.header { + margin-bottom: $space-6; +} + +.title { + font-size: $font-size-2xl; + font-weight: $font-weight-semibold; + color: $text-default; + margin-bottom: $space-2; +} + +.subtitle { + font-size: $font-size-sm; + color: $text-lighter; +} + +.userCard { + display: flex; + align-items: center; + gap: $space-4; + padding: $space-5; + background: $bg-surface-100; + border: 1px solid $border-default; + border-radius: $radius-lg; + margin-bottom: $space-8; +} + +.avatar { + width: 56px; + height: 56px; + border-radius: $radius-full; + background: $bg-surface-300; + color: $text-default; + font-size: $font-size-xl; + font-weight: $font-weight-semibold; + @include flex-center; + flex-shrink: 0; +} + +.userInfo { + @include flex-column; + gap: $space-1; + min-width: 0; +} + +.userName { + font-size: $font-size-base; + font-weight: $font-weight-medium; + color: $text-default; + @include truncate; +} + +.userEmail { + font-size: $font-size-sm; + color: $text-light; + @include truncate; +} + +.userRole { + display: inline-flex; + align-self: flex-start; + padding: $space-0-5 $space-2; + background: $bg-surface-200; + border-radius: $radius-full; + font-size: $font-size-xs; + color: $text-lighter; + text-transform: uppercase; + letter-spacing: $tracking-wide; +} + +.section { + margin-bottom: $space-8; +} + +.sectionTitle { + font-size: $font-size-sm; + font-weight: $font-weight-medium; + color: $text-light; + text-transform: uppercase; + letter-spacing: $tracking-wide; + margin-bottom: $space-4; +} + +.grid { + display: grid; + gap: $space-4; + + @include breakpoint-up('md') { + grid-template-columns: repeat(3, 1fr); + } +} + +.card { + padding: $space-4; + background: $bg-surface-100; + border: 1px solid $border-default; + border-radius: $radius-lg; +} + +.hookName { + display: inline-block; + font-size: $font-size-sm; + font-weight: $font-weight-medium; + color: $text-default; + background: $bg-surface-200; + padding: $space-1 $space-2; + border-radius: $radius-sm; + margin-bottom: $space-2; +} + +.description { + font-size: $font-size-sm; + color: $text-light; + margin-bottom: $space-2; + line-height: $line-height-relaxed; +} + +.file { + font-size: $font-size-xs; + color: $text-muted; + font-family: $font-mono; +} + +.list { + @include flex-column; + gap: $space-2; + padding-left: $space-5; + list-style: disc; + + li { + font-size: $font-size-sm; + color: $text-light; + } +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/pages/dashboard/index.tsx b/PROJECTS/advanced/ai-threat-detection/frontend/src/pages/dashboard/index.tsx new file mode 100644 index 00000000..4b1fca5d --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/pages/dashboard/index.tsx @@ -0,0 +1,10 @@ +// =================== +// © AngelaMos | 2026 +// index.tsx +// =================== + +export function Component(): React.ReactElement { + return
Dashboard
+} + +Component.displayName = 'DashboardPage' diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/pages/models/index.tsx b/PROJECTS/advanced/ai-threat-detection/frontend/src/pages/models/index.tsx new file mode 100644 index 00000000..9f0c013d --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/pages/models/index.tsx @@ -0,0 +1,10 @@ +// =================== +// © AngelaMos | 2026 +// index.tsx +// =================== + +export function Component(): React.ReactElement { + return
Models
+} + +Component.displayName = 'ModelsPage' diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/pages/threats/index.tsx b/PROJECTS/advanced/ai-threat-detection/frontend/src/pages/threats/index.tsx new file mode 100644 index 00000000..3dd9c9ac --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/pages/threats/index.tsx @@ -0,0 +1,10 @@ +// =================== +// © AngelaMos | 2026 +// index.tsx +// =================== + +export function Component(): React.ReactElement { + return
Threats
+} + +Component.displayName = 'ThreatsPage' diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/styles.scss b/PROJECTS/advanced/ai-threat-detection/frontend/src/styles.scss new file mode 100644 index 00000000..e06571ba --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/styles.scss @@ -0,0 +1,29 @@ +// =================== +// © AngelaMos | 2026 +// styles.scss +// =================== + +@forward 'styles/tokens'; +@forward 'styles/fonts'; +@forward 'styles/mixins'; + +@use 'styles/reset'; +@use 'styles/tokens' as *; +@use 'styles/fonts' as *; + +#root { + min-height: 100vh; + min-height: 100dvh; + display: flex; + flex-direction: column; + background: $bg-default; +} + +.app { + flex: 1; + display: flex; + flex-direction: column; + background: $bg-default; + color: $text-default; + font-family: $font-sans; +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_fonts.scss b/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_fonts.scss new file mode 100644 index 00000000..10d59dca --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_fonts.scss @@ -0,0 +1,12 @@ +// =================== +// © AngelaMos | 2026 +// _fonts.scss +// =================== + +@use 'tokens' as *; + +$font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', Roboto, + 'Helvetica Neue', Arial, sans-serif; + +$font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, + 'Liberation Mono', monospace; diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_index.scss b/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_index.scss new file mode 100644 index 00000000..9d5d028c --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_index.scss @@ -0,0 +1,8 @@ +// =================== +// © AngelaMos | 2026 +// _index.scss +// =================== + +@forward 'tokens'; +@forward 'fonts'; +@forward 'mixins'; diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_mixins.scss b/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_mixins.scss new file mode 100644 index 00000000..288b4e67 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_mixins.scss @@ -0,0 +1,120 @@ +// =================== +// © AngelaMos | 2026 +// _mixins.scss +// =================== + +@use 'sass:map'; +@use 'sass:list'; +@use 'tokens' as *; + +$breakpoints: ( + 'xs': $breakpoint-xs, + 'sm': $breakpoint-sm, + 'md': $breakpoint-md, + 'lg': $breakpoint-lg, + 'xl': $breakpoint-xl, + '2xl': $breakpoint-2xl, +); + +@mixin breakpoint-up($size) { + @media (min-width: map.get($breakpoints, $size)) { + @content; + } +} + +@mixin breakpoint-down($size) { + @media (width < map.get($breakpoints, $size)) { + @content; + } +} + +@mixin flex-center { + display: flex; + align-items: center; + justify-content: center; +} + +@mixin flex-between { + display: flex; + align-items: center; + justify-content: space-between; +} + +@mixin flex-column { + display: flex; + flex-direction: column; +} + +@mixin flex-column-center { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +@mixin sr-only { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0 0 0 0); + clip-path: inset(50%); + white-space: nowrap; + border: 0; +} + +@mixin truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +@mixin line-clamp($lines: 2) { + display: -webkit-box; + -webkit-line-clamp: #{$lines}; + -webkit-box-orient: vertical; + overflow: hidden; +} + +@mixin transition-fast { + transition-property: background-color, border-color, color, opacity; + transition-duration: $duration-fast; + transition-timing-function: $ease-out; +} + +@mixin transition-normal { + transition-property: background-color, border-color, color, opacity; + transition-duration: $duration-normal; + transition-timing-function: $ease-out; +} + +@mixin absolute-fill { + position: absolute; + inset: 0; +} + +@mixin absolute-center { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +@mixin hover { + @media (hover: hover) and (pointer: fine) { + &:hover { + @content; + } + } +} + +@mixin hide-scrollbar { + -ms-overflow-style: none; + scrollbar-width: none; + + &::-webkit-scrollbar { + display: none; + } +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_reset.scss b/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_reset.scss new file mode 100644 index 00000000..fb9eca5b --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_reset.scss @@ -0,0 +1,198 @@ +// =================== +// © AngelaMos | 2026 +// _reset.scss +// =================== + +@use 'tokens' as *; +@use 'fonts' as *; + +*, +*::before, +*::after { + box-sizing: border-box; +} + +* { + margin: 0; + padding: 0; + -webkit-tap-highlight-color: transparent; +} + +html { + font-size: 16px; + -moz-text-size-adjust: none; + -webkit-text-size-adjust: none; + text-size-adjust: none; + overflow-x: hidden; +} + +@media (prefers-reduced-motion: no-preference) { + html { + interpolate-size: allow-keywords; + scroll-behavior: smooth; + } +} + +body { + min-height: 100vh; + min-height: 100dvh; + line-height: $line-height-normal; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + overflow-x: hidden; + background-color: $bg-default; + color: $text-default; + font-family: $font-sans; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + line-height: $line-height-tight; + text-wrap: balance; + overflow-wrap: break-word; + font-weight: $font-weight-semibold; +} + +p { + text-wrap: pretty; + overflow-wrap: break-word; +} + +ul, +ol { + list-style: none; +} + +a { + color: inherit; + text-decoration: none; +} + +img, +picture, +video, +canvas, +svg { + display: block; + max-width: 100%; + height: auto; +} + +input, +button, +textarea, +select { + font: inherit; + color: inherit; +} + +input[type='text'], +input[type='email'], +input[type='password'], +input[type='search'], +input[type='number'], +input[type='tel'], +input[type='url'], +textarea, +select { + font-size: $font-size-sm; + appearance: none; +} + +button { + background: none; + border: none; + cursor: pointer; + text-align: inherit; + font-family: inherit; +} + +fieldset { + border: none; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +textarea:not([rows]) { + min-height: 10em; +} + +:target { + scroll-margin-block: 5ex; +} + +:focus-visible { + outline: 2px solid $border-strong; + outline-offset: 2px; +} + +:focus:not(:focus-visible) { + outline: none; +} + +[hidden] { + display: none !important; +} + +[disabled] { + cursor: not-allowed; + opacity: 0.5; +} + +dialog { + padding: 0; + border: none; + background: transparent; +} + +summary { + cursor: pointer; +} + +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } +} + +@supports (padding: max(0px)) { + body { + padding-left: max(0px, env(safe-area-inset-left)); + padding-right: max(0px, env(safe-area-inset-right)); + } +} + +::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +::-webkit-scrollbar-track { + background: transparent; +} + +::-webkit-scrollbar-thumb { + background: $border-default; + border-radius: 3px; +} + +::-webkit-scrollbar-thumb:hover { + background: $border-strong; +} + +::selection { + background-color: $bg-selection; +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_tokens.scss b/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_tokens.scss new file mode 100644 index 00000000..f3c63ba5 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/src/styles/_tokens.scss @@ -0,0 +1,168 @@ +// =================== +// © AngelaMos | 2026 +// _tokens.scss +// =================== + +// ============================================================================ +// SPACING (8px base system) +// ============================================================================ +$space-0: 0; +$space-px: 1px; +$space-0-5: 0.125rem; +$space-1: 0.25rem; +$space-1-5: 0.375rem; +$space-2: 0.5rem; +$space-2-5: 0.625rem; +$space-3: 0.75rem; +$space-3-5: 0.875rem; +$space-4: 1rem; +$space-5: 1.25rem; +$space-6: 1.5rem; +$space-7: 1.75rem; +$space-8: 2rem; +$space-9: 2.25rem; +$space-10: 2.5rem; +$space-11: 2.75rem; +$space-12: 3rem; +$space-14: 3.5rem; +$space-16: 4rem; +$space-20: 5rem; +$space-24: 6rem; +$space-28: 7rem; +$space-32: 8rem; + +// ============================================================================ +// TYPOGRAPHY SCALE +// ============================================================================ +$font-size-3xs: 0.625rem; +$font-size-2xs: 0.6875rem; +$font-size-xs: 0.75rem; +$font-size-sm: 0.875rem; +$font-size-base: 1rem; +$font-size-lg: 1.125rem; +$font-size-xl: 1.25rem; +$font-size-2xl: 1.5rem; +$font-size-3xl: 1.875rem; +$font-size-4xl: 2.25rem; +$font-size-5xl: 3rem; + +// ============================================================================ +// FONT WEIGHTS +// ============================================================================ +$font-weight-regular: 400; +$font-weight-medium: 500; +$font-weight-semibold: 600; + +// ============================================================================ +// LINE HEIGHTS +// ============================================================================ +$line-height-none: 1; +$line-height-tight: 1.2; +$line-height-snug: 1.375; +$line-height-normal: 1.5; +$line-height-relaxed: 1.625; + +// ============================================================================ +// LETTER SPACING +// ============================================================================ +$tracking-tighter: -0.05em; +$tracking-tight: -0.025em; +$tracking-normal: 0; +$tracking-wide: 0.025em; +$tracking-wider: 0.05em; + +// ============================================================================ +// COLORS +// ============================================================================ +$white: hsl(0, 0%, 100%); +$black: hsl(0, 0%, 0%); + +// Auth +$bg-page: hsl(0, 0%, 10.5%); +$bg-card: hsl(0, 0%, 6.2%); + +// Home/landing +$bg-landing: hsl(0, 0%, 10.8%); + +$bg-default: hsl(0, 0%, 7.1%); +$bg-alternative: hsl(0, 0%, 5.9%); +$bg-surface-75: hsl(0, 0%, 9%); +$bg-surface-100: hsl(0, 0%, 12.2%); +$bg-surface-200: hsl(0, 0%, 14.1%); +$bg-surface-300: hsl(0, 0%, 16.1%); +$bg-control: hsl(0, 0%, 10%); +$bg-selection: hsl(0, 0%, 19.2%); +$bg-overlay: hsl(0, 0%, 14.1%); +$bg-overlay-hover: hsl(0, 0%, 18%); + +$border-muted: hsl(0, 0%, 11.1%); +$border-default: hsl(0, 0%, 18%); +$border-strong: hsl(0, 0%, 22.4%); +$border-stronger: hsl(0, 0%, 27.1%); +$border-control: hsl(0, 0%, 22.4%); + +$text-default: hsl(0, 0%, 98%); +$text-light: hsl(0, 0%, 70.6%); +$text-lighter: hsl(0, 0%, 53.7%); +$text-muted: hsl(0, 0%, 30.2%); + +$error-default: hsl(0, 72%, 51%); +$error-light: hsl(0, 72%, 65%); + +// ============================================================================ +// BORDER RADIUS +// ============================================================================ +$radius-none: 0; +$radius-xs: 2px; +$radius-sm: 4px; +$radius-md: 6px; +$radius-lg: 8px; +$radius-xl: 12px; +$radius-full: 9999px; + +// ============================================================================ +// Z-INDEX SCALE +// ============================================================================ +$z-hide: -1; +$z-base: 0; +$z-dropdown: 100; +$z-sticky: 200; +$z-fixed: 300; +$z-overlay: 400; +$z-modal: 500; +$z-popover: 600; +$z-tooltip: 700; +$z-toast: 800; +$z-max: 9999; + +// ============================================================================ +// TRANSITIONS +// ============================================================================ +$duration-instant: 0ms; +$duration-fast: 100ms; +$duration-normal: 150ms; +$duration-slow: 200ms; + +$ease-out: cubic-bezier(0, 0, 0.2, 1); +$ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); + +// ============================================================================ +// BREAKPOINTS +// ============================================================================ +$breakpoint-xs: 360px; +$breakpoint-sm: 480px; +$breakpoint-md: 768px; +$breakpoint-lg: 1024px; +$breakpoint-xl: 1280px; +$breakpoint-2xl: 1536px; + +// ============================================================================ +// CONTAINER WIDTHS +// ============================================================================ +$container-xs: 20rem; +$container-sm: 24rem; +$container-md: 28rem; +$container-lg: 32rem; +$container-xl: 36rem; +$container-2xl: 42rem; +$container-full: 100%; diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/stylelint.config.js b/PROJECTS/advanced/ai-threat-detection/frontend/stylelint.config.js new file mode 100644 index 00000000..56ebd7bc --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/stylelint.config.js @@ -0,0 +1,107 @@ +// ©AngelaMos | 2025 +// stylelint.config.js + +/** @type {import('stylelint').Config} */ +export default { + extends: ['stylelint-config-standard-scss', 'stylelint-config-prettier-scss'], + rules: { + 'block-no-empty': true, + 'declaration-no-important': true, + 'color-no-invalid-hex': true, + 'property-no-unknown': true, + 'selector-pseudo-class-no-unknown': [ + true, + { + ignorePseudoClasses: ['global'], + }, + ], + + 'selector-class-pattern': [ + '^[a-z]([a-z0-9-]+)?(__[a-z0-9]([a-z0-9-]+)?)?(--[a-z0-9]([a-z0-9-]+)?)?$|^[a-z][a-zA-Z0-9]*$', + { + message: + 'Selector should be in BEM format (e.g., .block__element--modifier) or CSS Modules camelCase (e.g., .testButton)', + }, + ], + + 'value-keyword-case': [ + 'lower', + { + camelCaseSvgKeywords: true, + ignoreKeywords: [ + 'BlinkMacSystemFont', + 'SFMono-Regular', + 'Menlo', + 'Monaco', + 'Consolas', + 'Roboto', + 'Arial', + 'Helvetica', + 'Times', + 'Georgia', + 'Verdana', + 'Tahoma', + 'Trebuchet', + 'Impact', + 'Comic', + ], + }, + ], + + 'property-no-vendor-prefix': [ + true, + { + ignoreProperties: ['text-size-adjust', 'appearance', 'backdrop-filter'], + }, + ], + 'value-no-vendor-prefix': true, + 'selector-no-vendor-prefix': true, + + 'property-no-deprecated': [ + true, + { + ignoreProperties: ['clip'], + }, + ], + + 'container-name-pattern': null, + 'layer-name-pattern': null, + + 'scss/at-rule-no-unknown': true, + 'scss/declaration-nested-properties-no-divided-groups': true, + 'scss/dollar-variable-no-missing-interpolation': true, + 'scss/dollar-variable-empty-line-before': null, + + 'declaration-empty-line-before': null, + 'custom-property-empty-line-before': null, + + 'no-descending-specificity': null, + + 'media-feature-name-no-unknown': [ + true, + { + ignoreMediaFeatureNames: ['map'], + }, + ], + + 'color-function-notation': null, + 'hue-degree-notation': null, + }, + ignoreFiles: [ + 'node_modules/**', + 'dist/**', + 'build/**', + '**/*.js', + '**/*.ts', + '**/*.tsx', + ], + overrides: [ + { + files: ['**/styles/_reset.scss', '**/styles/_fonts.scss'], + rules: { + 'declaration-no-important': null, + 'scss/comment-no-empty': null, + }, + }, + ], +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/tsconfig.app.json b/PROJECTS/advanced/ai-threat-detection/frontend/tsconfig.app.json new file mode 100644 index 00000000..afe17f60 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/tsconfig.app.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2022", + "useDefineForClassFields": true, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "types": ["vite/client"], + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/tsconfig.json b/PROJECTS/advanced/ai-threat-detection/frontend/tsconfig.json new file mode 100644 index 00000000..1ffef600 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/tsconfig.node.json b/PROJECTS/advanced/ai-threat-detection/frontend/tsconfig.node.json new file mode 100644 index 00000000..a96b3e59 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2023", + "lib": ["ES2023"], + "module": "ESNext", + "types": ["node"], + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/PROJECTS/advanced/ai-threat-detection/frontend/vite.config.ts b/PROJECTS/advanced/ai-threat-detection/frontend/vite.config.ts new file mode 100644 index 00000000..a4ad5b31 --- /dev/null +++ b/PROJECTS/advanced/ai-threat-detection/frontend/vite.config.ts @@ -0,0 +1,71 @@ +/** + * ©AngelaMos | 2026 + * vite.config.ts + */ + +import path from 'node:path' +import react from '@vitejs/plugin-react' +import { defineConfig, loadEnv } from 'vite' +import tsconfigPaths from 'vite-tsconfig-paths' + +export default defineConfig(({ mode }) => { + const env = loadEnv(mode, path.resolve(__dirname, '..'), '') + const isDev = mode === 'development' + + return { + plugins: [react(), tsconfigPaths()], + + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, + + css: { + preprocessorOptions: { + scss: {}, + }, + }, + + server: { + port: 5173, + host: '0.0.0.0', + proxy: { + '/api': { + target: env.VITE_API_TARGET || 'http://localhost:8000', + changeOrigin: true, + rewrite: (p) => p.replace(/^\/api/, ''), + }, + }, + }, + + build: { + target: 'esnext', + cssTarget: 'chrome100', + sourcemap: isDev ? true : 'hidden', + minify: 'oxc', + rollupOptions: { + output: { + manualChunks(id: string): string | undefined { + if (id.includes('node_modules')) { + if (id.includes('react-dom') || id.includes('react-router')) { + return 'vendor-react' + } + if (id.includes('@tanstack/react-query')) { + return 'vendor-query' + } + if (id.includes('zustand')) { + return 'vendor-state' + } + } + return undefined + }, + }, + }, + }, + + preview: { + port: 4173, + }, + } +})