diff --git a/apps/web/package.json b/apps/web/package.json index f308c0c..a4730af 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -4,7 +4,9 @@ "scripts": { "dev": "bun run --hot src/index.ts", "start": "bun run src/index.ts", - "build": "bun build src/index.ts --outdir dist" + "build": "bun build src/index.ts --outdir dist", + "css": "bunx tailwindcss -i src/tailwind.css -o src/dashboard/tailwind.css --minify", + "css:watch": "bunx tailwindcss -i src/tailwind.css -o src/dashboard/tailwind.css --watch" }, "dependencies": { "@elysiajs/cors": "^1.4.1", @@ -13,7 +15,9 @@ "postgres": "^3.4.8" }, "devDependencies": { + "@tailwindcss/cli": "^4.2.1", "@types/bun": "^1.3.10", + "tailwindcss": "^4.2.1", "typescript": "^5.9.3" } } diff --git a/apps/web/src/dashboard/detail.html b/apps/web/src/dashboard/detail.html index 4703b82..a6a4aba 100644 --- a/apps/web/src/dashboard/detail.html +++ b/apps/web/src/dashboard/detail.html @@ -4,7 +4,7 @@ PingQL — Monitor Detail - + diff --git a/apps/web/src/dashboard/docs.html b/apps/web/src/dashboard/docs.html index 6677270..e0319ff 100644 --- a/apps/web/src/dashboard/docs.html +++ b/apps/web/src/dashboard/docs.html @@ -4,7 +4,7 @@ PingQL — Documentation - + diff --git a/apps/web/src/dashboard/index.html b/apps/web/src/dashboard/index.html index c787d77..108e4b3 100644 --- a/apps/web/src/dashboard/index.html +++ b/apps/web/src/dashboard/index.html @@ -4,7 +4,7 @@ PingQL — Sign In - + diff --git a/apps/web/src/dashboard/landing.html b/apps/web/src/dashboard/landing.html index fb652e5..f743416 100644 --- a/apps/web/src/dashboard/landing.html +++ b/apps/web/src/dashboard/landing.html @@ -5,24 +5,9 @@ PingQL — Uptime monitoring that thinks like a developer - + - diff --git a/apps/web/src/dashboard/privacy.html b/apps/web/src/dashboard/privacy.html index 0a8f0ce..0ee1b62 100644 --- a/apps/web/src/dashboard/privacy.html +++ b/apps/web/src/dashboard/privacy.html @@ -5,21 +5,9 @@ Privacy — PingQL - + - diff --git a/apps/web/src/dashboard/tailwind.css b/apps/web/src/dashboard/tailwind.css new file mode 100644 index 0000000..eccc60e --- /dev/null +++ b/apps/web/src/dashboard/tailwind.css @@ -0,0 +1,2 @@ +/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */ +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.z-50{z-index:50}.container{width:100%}.mx-auto{margin-inline:auto}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-full{height:100%}.h-screen{height:100vh}.min-h-screen{min-height:100vh}.w-full{width:100%}.max-w-\[200px\]{max-width:200px}.min-w-\[140px\]{min-width:140px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-default{cursor:default}.resize-y{resize:vertical}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.scroll-smooth{scroll-behavior:smooth}.rounded-full{border-radius:3.40282e38px}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.bg-\[\#0a0a0a\]{background-color:#0a0a0a}.bg-\[\#0a0a0a\]\/80{background-color:oklab(14.4788% 7.45058e-9 7.45058e-9/.8)}.bg-\[\#28c840\]{background-color:#28c840}.bg-\[\#111\]{background-color:#111}.bg-\[\#ff5f57\]{background-color:#ff5f57}.bg-\[\#ffbd2e\]{background-color:#ffbd2e}.bg-gradient-to-b{--tw-gradient-position:to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-\[\#111\]{--tw-gradient-from:#111;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-\[\#0a0a0a\]{--tw-gradient-to:#0a0a0a;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.leading-\[1\.1\]{--tw-leading:1.1;line-height:1.1}.leading-none{--tw-leading:1;line-height:1}.break-all{word-break:break-all}.whitespace-pre-wrap{white-space:pre-wrap}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.italic{font-style:italic}.line-through{text-decoration-line:line-through}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.shadow-\[0_0_40px_rgba\(59\,130\,246\,0\.06\)\]{--tw-shadow:0 0 40px var(--tw-shadow-color,#3b82f60f);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.select-all{-webkit-user-select:all;user-select:all}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false} \ No newline at end of file diff --git a/apps/web/src/routes/dashboard.ts b/apps/web/src/routes/dashboard.ts index 94bcd05..5947f6b 100644 --- a/apps/web/src/routes/dashboard.ts +++ b/apps/web/src/routes/dashboard.ts @@ -79,6 +79,7 @@ const dashDir = resolve(import.meta.dir, "../dashboard"); export const dashboard = new Elysia() .get("/dashboard/app.js", () => Bun.file(`${dashDir}/app.js`)) .get("/dashboard/app.css", () => Bun.file(`${dashDir}/app.css`)) + .get("/dashboard/tailwind.css", () => Bun.file(`${dashDir}/tailwind.css`)) .get("/dashboard/query-builder.js", () => Bun.file(`${dashDir}/query-builder.js`)) // Login page diff --git a/apps/web/src/tailwind.css b/apps/web/src/tailwind.css new file mode 100644 index 0000000..b5c61c9 --- /dev/null +++ b/apps/web/src/tailwind.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/apps/web/src/views/partials/head.ejs b/apps/web/src/views/partials/head.ejs index 6115095..25fbaf8 100644 --- a/apps/web/src/views/partials/head.ejs +++ b/apps/web/src/views/partials/head.ejs @@ -4,7 +4,7 @@ PingQL<%= it.title ? ` — ${it.title}` : '' %> - + <% if (it.scripts) { it.scripts.forEach(function(s) { %> diff --git a/apps/web/tailwind.config.js b/apps/web/tailwind.config.js new file mode 100644 index 0000000..987175d --- /dev/null +++ b/apps/web/tailwind.config.js @@ -0,0 +1,20 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + darkMode: 'class', + content: [ + './src/**/*.{ts,html,ejs}', + './src/dashboard/**/*.{html,js}', + ], + theme: { + extend: { + fontFamily: { + mono: ['JetBrains Mono', 'SF Mono', 'Fira Code', 'ui-monospace', 'monospace'], + sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'], + }, + colors: { + brand: '#3b82f6', + }, + }, + }, + plugins: [], +}