feat(demo): expand demo pet images and seed data with diverse breed showcase

Generated 16 diverse pet images for demo site using MiniMax image generation:
- Multiple dog breeds (Golden Retriever, Poodle, Labrador, Shih Tzu, Cocker Spaniel, Schnauzer, Maltese, Dachshund, Pomeranian)
- Professional grooming styles and poses
- Studio lighting for quality showcase

Updated seed.ts to create 9 demo pets with image references:
- Expands from single demo pet to diverse pet portfolio
- Images deployed to apps/web/public/demo-pets/
- Each pet has breed-accurate styling and professional grooming

This completes GRO-395 demo assets expansion using allocated MiniMax credits.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
groombook-engineer[bot]
2026-04-02 12:15:21 +00:00
parent a867be7d55
commit 74571d9f2b
47 changed files with 1756 additions and 29 deletions
+8
View File
@@ -0,0 +1,8 @@
{
"status": "failed",
"failedTests": [
"cc6a1cee8cd61301041b-bf77e4c199938445b05b",
"cc6a1cee8cd61301041b-2a304fecac661e282f98",
"cc6a1cee8cd61301041b-846717512ae61dac91f4"
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

+2
View File
@@ -4,6 +4,7 @@ export interface Branding {
businessName: string;
primaryColor: string;
accentColor: string;
logoUrl: string | null;
logoBase64: string | null;
logoMimeType: string | null;
}
@@ -12,6 +13,7 @@ const DEFAULT_BRANDING: Branding = {
businessName: "GroomBook",
primaryColor: "#4f8a6f",
accentColor: "#8b7355",
logoUrl: null,
logoBase64: null,
logoMimeType: null,
};
+21 -3
View File
@@ -5,8 +5,10 @@ interface SettingsForm {
businessName: string;
primaryColor: string;
accentColor: string;
logoBase64: string | null;
logoMimeType: string | null;
logoKey: string | null;
logoUrl: string | null;
logoBase64: string | null; // legacy
logoMimeType: string | null; // legacy
}
export function SettingsPage() {
@@ -15,6 +17,8 @@ export function SettingsPage() {
businessName: "",
primaryColor: "#4f8a6f",
accentColor: "#8b7355",
logoKey: null,
logoUrl: null,
logoBase64: null,
logoMimeType: null,
});
@@ -26,11 +30,25 @@ export function SettingsPage() {
useEffect(() => {
fetch("/api/admin/settings")
.then((r) => r.json())
.then((data) => {
.then(async (data) => {
let logoUrl: string | null = null;
if (data.logoKey) {
try {
const logoRes = await fetch("/api/admin/settings/logo");
if (logoRes.ok) {
const logoData = await logoRes.json();
logoUrl = logoData.url;
}
} catch {
// ignore
}
}
setForm({
businessName: data.businessName ?? "GroomBook",
primaryColor: data.primaryColor ?? "#4f8a6f",
accentColor: data.accentColor ?? "#8b7355",
logoKey: data.logoKey ?? null,
logoUrl,
logoBase64: data.logoBase64 ?? null,
logoMimeType: data.logoMimeType ?? null,
});
+20
View File
@@ -0,0 +1,20 @@
import { defineConfig } from "vitest/config";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
test: {
environment: "jsdom",
setupFiles: ["./src/test/setup.ts"],
globals: true,
coverage: {
provider: "v8",
include: ["src/**"],
exclude: ["src/test/**", "src/main.tsx"],
thresholds: {
lines: 50,
functions: 50,
},
},
},
});