fix(deps): migrate tailwindcss to v4 and remove daisyui

This commit is contained in:
2025-02-03 21:54:30 +01:00
parent a88ed4bb47
commit f2951985c2
12 changed files with 1000 additions and 1450 deletions

18
input.css Normal file
View File

@@ -0,0 +1,18 @@
@import 'tailwindcss';
@source './static/**/*.js';
@source './template/**/*.templ';
@theme {
--animate-fade: fadeOut 0.25s ease-in;
@keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
}

2069
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,16 +4,15 @@
"description": "Your (almost) independent tech stack to host on a VPC.", "description": "Your (almost) independent tech stack to host on a VPC.",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"build": "mkdir -p static/js && cp -f node_modules/htmx.org/dist/htmx.min.js static/js/htmx.min.js && tailwindcss build -o static/css/tailwind.css --minify", "build": "mkdir -p static/js && cp -f node_modules/htmx.org/dist/htmx.min.js static/js/htmx.min.js && tailwindcss -i input.css -o static/css/tailwind.css --minify",
"watch": "mkdir -p static/js && cp -f node_modules/htmx.org/dist/htmx.min.js static/js/htmx.min.js && tailwindcss build -o static/css/tailwind.css --watch", "watch": "mkdir -p static/js && cp -f node_modules/htmx.org/dist/htmx.min.js static/js/htmx.min.js && tailwindcss -i input.css -o static/css/tailwind.css --watch"
"test": ""
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"htmx.org": "2.0.4", "htmx.org": "2.0.4",
"tailwindcss": "3.4.17", "tailwindcss": "4.0.3",
"daisyui": "4.12.23" "@tailwindcss/cli": "4.0.3"
} }
} }

View File

@@ -1,26 +0,0 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./template/**/*.templ", "./static/**/*.js"],
theme: {
extend: {
animation: {
fade: 'fadeOut 0.25s ease-in',
},
keyframes: _ => ({
fadeOut: {
'0%': { opacity: '1' },
'100%': { opacity: '0' },
},
}),
},
},
plugins: [
require('daisyui'),
],
daisyui: {
themes: ["retro"],
},
}

View File

@@ -12,7 +12,7 @@ templ DeleteAccountComp() {
<p class="text-xl text-red-500 mb-4"> <p class="text-xl text-red-500 mb-4">
Are you sure you want to delete your account? This action is irreversible. Are you sure you want to delete your account? This action is irreversible.
</p> </p>
<label class="input input-bordered flex items-center gap-2"> <label class="flex items-center gap-2">
<input <input
type="password" type="password"
class="grow" class="grow"
@@ -24,7 +24,7 @@ templ DeleteAccountComp() {
autocapitalize="off" autocapitalize="off"
/> />
</label> </label>
<button class="btn btn-error self-end"> <button class="self-end">
Delete Account Delete Account
</button> </button>
</form> </form>

View File

@@ -1,30 +1,30 @@
package auth package auth
templ UserComp(user string) { templ UserComp(user string) {
<div id="user-info" class="flex gap-5 items-center"> <div id="user-info" class="flex gap-5 items-center">
if user != "" { if user != "" {
<div class="group inline-block relative"> <div class="inline-block relative">
<button class="font-semibold py-2 px-4 inline-flex items-center"> <button class="font-semibold py-2 px-4 inline-flex items-center">
<span class="mr-1">{ user }</span> <span class="mr-1">{ user }</span>
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"> <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path> <path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path>
</svg> </svg>
</button> </button>
<div class="absolute hidden group-hover:block w-full"> <div class="absolute hidden group-hover:block w-full">
<ul class="menu bg-base-300 rounded-box w-fit float-right mr-4 p-3"> <ul class="w-fit float-right mr-4 p-3">
<li class="mb-1"> <li class="mb-1">
<a hx-post="/api/auth/signout" hx-target="#user-info">Sign Out</a> <a hx-post="/api/auth/signout" hx-target="#user-info">Sign Out</a>
</li> </li>
<li class="mb-1"> <li class="mb-1">
<a href="/auth/change-password">Change Password</a> <a href="/auth/change-password">Change Password</a>
</li> </li>
<li><a href="/auth/delete-account" class="text-error">Delete Account</a></li> <li><a href="/auth/delete-account" class="">Delete Account</a></li>
</ul> </ul>
</div> </div>
</div>
} else {
<a href="/auth/signup" class="">Sign Up</a>
<a href="/auth/signin" class="">Sign In</a>
}
</div> </div>
} else {
<a href="/auth/signup" class="btn btn-sm">Sign Up</a>
<a href="/auth/signin" class="btn btn-sm">Sign In</a>
}
</div>
} }

View File

@@ -12,7 +12,7 @@ templ VerifyComp() {
<p class="text-lg text-center"> <p class="text-lg text-center">
Please check your inbox/spam and click on the link to verify your account. Please check your inbox/spam and click on the link to verify your account.
</p> </p>
<button class="btn mt-8" hx-get="/api/auth/verify-resend" hx-sync="this:drop" hx-swap="outerHTML"> <button class="mt-8" hx-get="/api/auth/verify-resend" hx-sync="this:drop" hx-swap="outerHTML">
resend verification email resend verification email
</button> </button>
</div> </div>

View File

@@ -1,29 +1,29 @@
package auth package auth
templ VerifyResponseComp(isVerified bool) { templ VerifyResponseComp(isVerified bool) {
<main> <main>
<div class="flex flex-col items-center justify-center h-screen"> <div class="flex flex-col items-center justify-center h-screen">
if isVerified { if isVerified {
<h2 class="text-6xl mb-10"> <h2 class="text-6xl mb-10">
Your email has been verified Your email has been verified
</h2> </h2>
<p class="text-lg text-center"> <p class="text-lg text-center">
You have completed the verification process. Thank you! You have completed the verification process. Thank you!
</p> </p>
<a class="btn btn-primary mt-8" href="/"> <a class="mt-8" href="/">
Go Home Go Home
</a> </a>
} else { } else {
<h2 class="text-6xl mb-10"> <h2 class="text-6xl mb-10">
Error during verification Error during verification
</h2> </h2>
<p class="text-lg text-center"> <p class="text-lg text-center">
Please try again by sign up process Please try again by sign up process
</p> </p>
<a class="btn btn-primary mt-8" href="/auth/signup"> <a class="mt-8" href="/auth/signup">
Sign Up Sign Up
</a> </a>
} }
</div> </div>
</main> </main>
} }

View File

@@ -1,16 +1,16 @@
package template package template
templ Index() { templ Index() {
<div class="hero bg-base-200 h-full"> <div class="h-full">
<div class="hero-content text-center"> <div class="text-center">
<div class="max-w-md"> <div class="max-w-md">
<h1 class="text-5xl font-bold">Next Level Workout Tracker</h1> <h1 class="text-5xl font-bold">Next Level Workout Tracker</h1>
<p class="py-6"> <p class="py-6">
Ever wanted to track your workouts and see your progress over time? web-app-template is the perfect Ever wanted to track your workouts and see your progress over time? web-app-template is the perfect
solution for you. solution for you.
</p> </p>
<a href="/workout" class="btn btn-primary">Get Started</a> <a href="/workout" class="">Get Started</a>
</div>
</div> </div>
</div> </div>
</div>
} }

View File

@@ -1,45 +1,45 @@
package template package template
templ Layout(slot templ.Component, user templ.Component) { templ Layout(slot templ.Component, user templ.Component) {
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head>
<head> <meta charset="utf-8"/>
<meta charset="utf-8" /> <title>web-app-template</title>
<title>web-app-template</title> <link rel="icon" href="/static/favicon.svg"/>
<link rel="icon" href="/static/favicon.svg" /> <link rel="stylesheet" href="/static/css/tailwind.css"/>
<link rel="stylesheet" href="/static/css/tailwind.css" /> <meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta
<meta name="htmx-config" content='{ name="htmx-config"
content='{
"includeIndicatorStyles": false, "includeIndicatorStyles": false,
"selfRequestsOnly": true, "selfRequestsOnly": true,
"allowScriptTags": false "allowScriptTags": false
}' /> }'
<script src="/static/js/htmx.min.js"></script> />
<script src="/static/js/toast.js"></script> <script src="/static/js/htmx.min.js"></script>
</head> <script src="/static/js/toast.js"></script>
</head>
<body hx-headers='{"csrf-token": "CSRF_TOKEN"}'> <body hx-headers='{"csrf-token": "CSRF_TOKEN"}'>
<div class="h-screen flex flex-col"> <div class="h-screen flex flex-col">
<div class="flex justify-end items-center gap-2 py-1 px-2 h-12 md:gap-10 md:px-10 md:py-2 shadow"> <div class="flex justify-end items-center gap-2 py-1 px-2 h-12 md:gap-10 md:px-10 md:py-2 shadow-sm">
<a href="/" class="flex-1 flex gap-2"> <a href="/" class="flex-1 flex gap-2">
<img src="/static/favicon.svg" alt="web-app-template logo" /> <img src="/static/favicon.svg" alt="web-app-template logo"/>
<span>web-app-template</span> <span>web-app-template</span>
</a> </a>
@user @user
</div> </div>
<div class="flex-1"> <div class="flex-1">
if slot != nil { if slot != nil {
@slot @slot
} }
</div> </div>
</div> </div>
<div class="toast" id="toasts"> <div class="" id="toasts">
<div class="hidden alert" id="toast"> <div class="hidden" id="toast">
New message arrived. New message arrived.
</div> </div>
</div> </div>
</body> </body>
</html>
</html>
} }

View File

@@ -1,11 +1,11 @@
package template package template
templ NotFound() { templ NotFound() {
<main class="flex h-full justify-center items-center "> <main class="flex h-full justify-center items-center">
<div class="bg-error p-16 rounded-lg"> <div class="p-16 rounded-lg">
<h1 class="text-4xl text-error-content mb-5">Not Found</h1> <h1 class="text-4xl mb-5">Not Found</h1>
<p class="text-lg text-error-content mb-5">The page you are looking for does not exist.</p> <p class="text-lg mb-5">The page you are looking for does not exist.</p>
<a href="/" class="btn btn-lg btn-primary">Go back to home</a> <a href="/" class="">Go back to home</a>
</div> </div>
</main> </main>
} }

View File

@@ -1,69 +1,73 @@
package workout package workout
templ WorkoutComp(currentDate string) { templ WorkoutComp(currentDate string) {
<main class="mx-2"> <main class="mx-2">
<form class="max-w-xl mx-auto flex flex-col gap-4 justify-center mt-10" hx-post="/api/workout" <form
hx-target="#workout-placeholder" hx-swap="outerHTML"> class="max-w-xl mx-auto flex flex-col gap-4 justify-center mt-10"
<h2 class="text-4xl mb-8">Track your workout</h2> hx-post="/api/workout"
<input id="date" type="date" class="input input-bordered" value={ currentDate } name="date" /> hx-target="#workout-placeholder"
<select class="select select-bordered w-full" name="type"> hx-swap="outerHTML"
<option>Push Ups</option> >
<option>Pull Ups</option> <h2 class="text-4xl mb-8">Track your workout</h2>
</select> <input id="date" type="date" class="" value={ currentDate } name="date"/>
<input type="number" class="input input-bordered" placeholder="Sets" name="sets" /> <select class="w-full" name="type">
<input type="number" class="input input-bordered" placeholder="Reps" name="reps" /> <option>Push Ups</option>
<button class="btn btn-primary self-end">Save</button> <option>Pull Ups</option>
</form> </select>
<div hx-get="/api/workout" hx-trigger="load"></div> <input type="number" class="" placeholder="Sets" name="sets"/>
</main> <input type="number" class="" placeholder="Reps" name="reps"/>
<button class="self-end">Save</button>
</form>
<div hx-get="/api/workout" hx-trigger="load"></div>
</main>
} }
type Workout struct { type Workout struct {
Id string Id string
Date string Date string
Type string Type string
Sets string Sets string
Reps string Reps string
} }
templ WorkoutListComp(workouts []Workout) { templ WorkoutListComp(workouts []Workout) {
<div class="overflow-x-auto mx-auto max-w-screen-lg"> <div class="overflow-x-auto mx-auto max-w-lg">
<h2 class="text-4xl mt-14 mb-8">Workout history</h2> <h2 class="text-4xl mt-14 mb-8">Workout history</h2>
<table class="table table-auto max-w-full"> <table class="table table-auto max-w-full">
<thead> <thead>
<tr> <tr>
<th>Date</th> <th>Date</th>
<th>Type</th> <th>Type</th>
<th>Sets</th> <th>Sets</th>
<th>Reps</th> <th>Reps</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr class="hidden" id="workout-placeholder"></tr> <tr class="hidden" id="workout-placeholder"></tr>
for _,w := range workouts { for _,w := range workouts {
@WorkoutItemComp(w, false) @WorkoutItemComp(w, false)
} }
</tbody> </tbody>
</table> </table>
</div> </div>
} }
templ WorkoutItemComp(w Workout, includePlaceholder bool) { templ WorkoutItemComp(w Workout, includePlaceholder bool) {
if includePlaceholder { if includePlaceholder {
<tr class="hidden" id="workout-placeholder"></tr> <tr class="hidden" id="workout-placeholder"></tr>
} }
<tr> <tr>
<th>{ w.Date }</th> <th>{ w.Date }</th>
<th>{ w.Type }</th> <th>{ w.Type }</th>
<th>{ w.Sets }</th> <th>{ w.Sets }</th>
<th>{ w.Reps }</th> <th>{ w.Reps }</th>
<th> <th>
<div class="tooltip" data-tip="Delete Entry"> <div class="tooltip" data-tip="Delete Entry">
<button hx-delete={ "api/workout/" + w.Id } hx-target="closest tr" type="submit"> <button hx-delete={ "api/workout/" + w.Id } hx-target="closest tr" type="submit">
Delete Delete
</button> </button>
</div> </div>
</th> </th>
</tr> </tr>
} }