diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml index 674d628..65f8d6b 100644 --- a/.idea/dictionaries/project.xml +++ b/.idea/dictionaries/project.xml @@ -3,6 +3,7 @@ hono htmx + shadcn \ No newline at end of file diff --git a/.run/Contacts.run.xml b/.run/Contacts.run.xml index 0b107b4..8c06fce 100644 --- a/.run/Contacts.run.xml +++ b/.run/Contacts.run.xml @@ -2,6 +2,7 @@ + diff --git a/pom.xml b/pom.xml index 98d366d..2e09d12 100644 --- a/pom.xml +++ b/pom.xml @@ -127,7 +127,7 @@ bun initialize - install + install --frozen-lockfile diff --git a/src/main/java/codes/yam/contacts/ContactController.java b/src/main/java/codes/yam/contacts/ContactController.java index 2bc4550..6e59294 100644 --- a/src/main/java/codes/yam/contacts/ContactController.java +++ b/src/main/java/codes/yam/contacts/ContactController.java @@ -3,6 +3,7 @@ import jakarta.validation.Valid; import java.net.URI; import java.util.List; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; @@ -27,6 +28,9 @@ public String contacts( Model model) { model.addAttribute("contactPage", contactService.list(q, pageable)); model.addAttribute("search", q); + model.addAttribute("sort", pageable.getSort().stream() + .map(o -> o.getProperty() + "," + o.getDirection().name().toLowerCase()) + .collect(Collectors.joining(","))); return "contacts/index"; } @@ -70,7 +74,6 @@ public String createContact(@Valid @ModelAttribute Contact contact, BindingResul @DeleteMapping("/{slug}") public ResponseEntity deleteContact(@PathVariable String slug) { contactService.delete(slug); - // TODO: extract seeOther helper if this pattern repeats return ResponseEntity.status(HttpStatus.SEE_OTHER).location(URI.create("/contacts")).build(); } diff --git a/src/main/resources/application-dev.yaml b/src/main/resources/application-dev.yaml new file mode 100644 index 0000000..facd10b --- /dev/null +++ b/src/main/resources/application-dev.yaml @@ -0,0 +1,19 @@ +spring: + thymeleaf: + cache: false + prefix: file:src/main/resources/templates/ + devtools: + livereload: + enabled: true + restart: + additional-paths: src/main/resources/templates/ + additional-exclude: "**/*.html" + web: + resources: + static-locations: + - file:src/main/resources/static/ + - classpath:/static/ + cache: + period: 0 + chain: + cache: false diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 1fba6a9..8ca96fd 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -2,14 +2,11 @@ spring: application: name: Contacts thymeleaf: - cache: false - devtools: - livereload: - enabled: true + cache: true h2: console: enabled: true jpa: defer-datasource-initialization: true datasource: - url: jdbc:h2:mem:contacts;DB_CLOSE_DELAY=-1 \ No newline at end of file + url: jdbc:h2:mem:contacts;DB_CLOSE_DELAY=-1 diff --git a/src/main/resources/static/css/input.css b/src/main/resources/static/css/input.css index 94500e0..06d0a25 100644 --- a/src/main/resources/static/css/input.css +++ b/src/main/resources/static/css/input.css @@ -1,3 +1,69 @@ @import "tailwindcss"; @source "../../templates"; + @plugin "daisyui"; + +/* noinspection CssUnknownProperty */ +@plugin "daisyui/theme" { + name: "shadcn"; + default: true; + color-scheme: light; + + /* Surfaces */ + --color-base-100: oklch(100% 0 0); + --color-base-200: oklch(97.8% 0 0); + --color-base-300: oklch(94.5% 0 0); + --color-base-content: oklch(14.1% 0 0); + + /* Primary — zinc-900 */ + --color-primary: oklch(14.1% 0 0); + --color-primary-content: oklch(100% 0 0); + + /* Secondary — zinc-100 */ + --color-secondary: oklch(94.5% 0 0); + --color-secondary-content: oklch(20.5% 0 0); + + /* Accent — same as primary */ + --color-accent: oklch(14.1% 0 0); + --color-accent-content: oklch(100% 0 0); + + /* Neutral */ + --color-neutral: oklch(27.4% 0 0); + --color-neutral-content: oklch(100% 0 0); + + /* States */ + --color-error: oklch(57.7% 0.245 27.3); + --color-error-content: oklch(100% 0 0); + --color-warning: oklch(76.9% 0.188 70.1); + --color-warning-content: oklch(14.1% 0 0); + --color-success: oklch(64.8% 0.15 160); + --color-success-content: oklch(100% 0 0); + --color-info: oklch(60% 0.12 230); + --color-info-content: oklch(100% 0 0); + + /* Shape — matches shadcn's rounded-md */ + --radius-selector: 0.375rem; + --radius-field: 0.375rem; + --radius-box: 0.5rem; + + /* Flat — no depth/emboss effects */ + --depth: 0; + --noise: 0; + + --border: 1px; + + /* Button — match shadcn sizing and weight */ + --size-field: 0.225rem; /* × 10 = 2.25rem = h-9, shadcn default */ + --fontsize: 0.875rem; +} + +@layer base { + body { font-family: Geist, sans-serif; } +} + +@layer components { + .btn { + font-weight: 500; + letter-spacing: 0; + } +} diff --git a/src/main/resources/templates/contacts/edit.html b/src/main/resources/templates/contacts/edit.html index 6db3851..3e8ce28 100644 --- a/src/main/resources/templates/contacts/edit.html +++ b/src/main/resources/templates/contacts/edit.html @@ -8,21 +8,43 @@ - Edit Contact - - - Save - - - Delete Contact - - - Back - + + + + + + Back to contacts + + Edit Contact + Update contact information. + + + + + + + Save Changes + Cancel + + + + + + Danger Zone + Permanently delete this contact. This action cannot be undone. + + + Delete Contact + + + +
- Back -
Update contact information.
Permanently delete this contact. This action cannot be undone.