Coffee journaling on ATProto (alpha) alpha.arabica.social
coffee

fix: misc fixes

pdewey.com 46a20b5b 1045c338

verified
+42 -33
-1
frontend/src/components/Modal.svelte
··· 1 <script> 2 - export let label; 3 export let onSave; 4 export let onCancel; 5 export let isOpen = false;
··· 1 <script> 2 export let onSave; 3 export let onCancel; 4 export let isOpen = false;
+41 -31
frontend/src/routes/BrewForm.svelte
··· 215 <form on:submit|preventDefault={handleSubmit} class="space-y-6"> 216 <!-- Bean Selection --> 217 <div> 218 - <label class="block text-sm font-medium text-brown-900 mb-2">Coffee Bean *</label> 219 <div class="flex gap-2"> 220 <select 221 bind:value={form.bean_rkey} 222 required 223 class="flex-1 rounded-lg border-2 border-brown-300 shadow-sm focus:border-brown-600 focus:ring-brown-600 text-base py-3 px-4 truncate max-w-full bg-white" ··· 241 242 <!-- Coffee Amount --> 243 <div> 244 - <label class="block text-sm font-medium text-brown-900 mb-2">Coffee Amount (grams)</label> 245 <input 246 type="number" 247 bind:value={form.coffee_amount} 248 step="0.1" ··· 254 255 <!-- Grinder --> 256 <div> 257 - <label class="block text-sm font-medium text-brown-900 mb-2">Grinder</label> 258 <div class="flex gap-2"> 259 <select 260 bind:value={form.grinder_rkey} 261 class="flex-1 rounded-lg border-2 border-brown-300 shadow-sm focus:border-brown-600 focus:ring-brown-600 text-base py-3 px-4 truncate max-w-full bg-white" 262 > ··· 277 278 <!-- Grind Size --> 279 <div> 280 - <label class="block text-sm font-medium text-brown-900 mb-2">Grind Size</label> 281 <input 282 type="text" 283 bind:value={form.grind_size} 284 placeholder="e.g. 18, Medium, 3.5, Fine" ··· 289 290 <!-- Brew Method --> 291 <div> 292 - <label class="block text-sm font-medium text-brown-900 mb-2">Brew Method</label> 293 <div class="flex gap-2"> 294 <select 295 bind:value={form.brewer_rkey} 296 class="flex-1 rounded-lg border-2 border-brown-300 shadow-sm focus:border-brown-600 focus:ring-brown-600 text-base py-3 px-4 truncate max-w-full bg-white" 297 > ··· 312 313 <!-- Water Amount --> 314 <div> 315 - <label class="block text-sm font-medium text-brown-900 mb-2">Water Amount (ml)</label> 316 <input 317 type="number" 318 bind:value={form.water_amount} 319 step="1" ··· 324 325 <!-- Water Temperature --> 326 <div> 327 - <label class="block text-sm font-medium text-brown-900 mb-2">Water Temperature (°C)</label> 328 <input 329 type="number" 330 bind:value={form.water_temp} 331 step="0.1" ··· 336 337 <!-- Brew Time --> 338 <div> 339 - <label class="block text-sm font-medium text-brown-900 mb-2">Total Brew Time (seconds)</label> 340 <input 341 type="number" 342 bind:value={form.brew_time} 343 step="1" ··· 349 <!-- Pours --> 350 <div> 351 <div class="flex items-center justify-between mb-2"> 352 - <label class="block text-sm font-medium text-brown-900">Pour Schedule (Optional)</label> 353 <button 354 type="button" 355 on:click={addPour} ··· 391 392 <!-- Rating --> 393 <div> 394 - <label class="block text-sm font-medium text-brown-900 mb-2"> 395 Rating: <span class="font-bold">{form.rating}/10</span> 396 </label> 397 <input 398 type="range" 399 bind:value={form.rating} 400 min="0" ··· 410 411 <!-- Notes --> 412 <div> 413 - <label class="block text-sm font-medium text-brown-900 mb-2">Tasting Notes</label> 414 <textarea 415 bind:value={form.notes} 416 rows="4" 417 placeholder="Describe the flavor, aroma, body, etc." ··· 450 > 451 <div class="space-y-4"> 452 <div> 453 - <label class="block text-sm font-medium text-gray-700 mb-1">Name</label> 454 - <input type="text" bind:value={beanForm.name} class="w-full rounded border-gray-300 px-3 py-2" /> 455 </div> 456 <div> 457 - <label class="block text-sm font-medium text-gray-700 mb-1">Origin *</label> 458 - <input type="text" bind:value={beanForm.origin} required class="w-full rounded border-gray-300 px-3 py-2" /> 459 </div> 460 <div> 461 - <label class="block text-sm font-medium text-gray-700 mb-1">Roast Level *</label> 462 - <select bind:value={beanForm.roast_level} required class="w-full rounded border-gray-300 px-3 py-2"> 463 <option value="">Select...</option> 464 <option value="Light">Light</option> 465 <option value="Medium-Light">Medium-Light</option> ··· 469 </select> 470 </div> 471 <div> 472 - <label class="block text-sm font-medium text-gray-700 mb-1">Roaster</label> 473 <div class="flex gap-2"> 474 - <select bind:value={beanForm.roaster_rkey} class="flex-1 rounded border-gray-300 px-3 py-2"> 475 <option value="">Select...</option> 476 {#each roasters as roaster} 477 <option value={roaster.rkey}>{roaster.name}</option> ··· 497 > 498 <div class="space-y-4"> 499 <div> 500 - <label class="block text-sm font-medium text-gray-700 mb-1">Name *</label> 501 - <input type="text" bind:value={roasterForm.name} required class="w-full rounded border-gray-300 px-3 py-2" /> 502 </div> 503 <div> 504 - <label class="block text-sm font-medium text-gray-700 mb-1">Location</label> 505 - <input type="text" bind:value={roasterForm.location} class="w-full rounded border-gray-300 px-3 py-2" /> 506 </div> 507 </div> 508 </Modal> ··· 515 > 516 <div class="space-y-4"> 517 <div> 518 - <label class="block text-sm font-medium text-gray-700 mb-1">Name *</label> 519 - <input type="text" bind:value={grinderForm.name} required class="w-full rounded border-gray-300 px-3 py-2" /> 520 </div> 521 <div> 522 - <label class="block text-sm font-medium text-gray-700 mb-1">Type</label> 523 - <select bind:value={grinderForm.grinder_type} class="w-full rounded border-gray-300 px-3 py-2"> 524 <option value="">Select...</option> 525 <option value="Manual">Manual</option> 526 <option value="Electric">Electric</option> ··· 538 > 539 <div class="space-y-4"> 540 <div> 541 - <label class="block text-sm font-medium text-gray-700 mb-1">Name *</label> 542 - <input type="text" bind:value={brewerForm.name} required class="w-full rounded border-gray-300 px-3 py-2" /> 543 </div> 544 <div> 545 - <label class="block text-sm font-medium text-gray-700 mb-1">Type</label> 546 - <select bind:value={brewerForm.brewer_type} class="w-full rounded border-gray-300 px-3 py-2"> 547 <option value="">Select...</option> 548 <option value="Pour Over">Pour Over</option> 549 <option value="French Press">French Press</option>
··· 215 <form on:submit|preventDefault={handleSubmit} class="space-y-6"> 216 <!-- Bean Selection --> 217 <div> 218 + <label for="bean-select" class="block text-sm font-medium text-brown-900 mb-2">Coffee Bean *</label> 219 <div class="flex gap-2"> 220 <select 221 + id="bean-select" 222 bind:value={form.bean_rkey} 223 required 224 class="flex-1 rounded-lg border-2 border-brown-300 shadow-sm focus:border-brown-600 focus:ring-brown-600 text-base py-3 px-4 truncate max-w-full bg-white" ··· 242 243 <!-- Coffee Amount --> 244 <div> 245 + <label for="coffee-amount" class="block text-sm font-medium text-brown-900 mb-2">Coffee Amount (grams)</label> 246 <input 247 + id="coffee-amount" 248 type="number" 249 bind:value={form.coffee_amount} 250 step="0.1" ··· 256 257 <!-- Grinder --> 258 <div> 259 + <label for="grinder-select" class="block text-sm font-medium text-brown-900 mb-2">Grinder</label> 260 <div class="flex gap-2"> 261 <select 262 + id="grinder-select" 263 bind:value={form.grinder_rkey} 264 class="flex-1 rounded-lg border-2 border-brown-300 shadow-sm focus:border-brown-600 focus:ring-brown-600 text-base py-3 px-4 truncate max-w-full bg-white" 265 > ··· 280 281 <!-- Grind Size --> 282 <div> 283 + <label for="grind-size" class="block text-sm font-medium text-brown-900 mb-2">Grind Size</label> 284 <input 285 + id="grind-size" 286 type="text" 287 bind:value={form.grind_size} 288 placeholder="e.g. 18, Medium, 3.5, Fine" ··· 293 294 <!-- Brew Method --> 295 <div> 296 + <label for="brewer-select" class="block text-sm font-medium text-brown-900 mb-2">Brew Method</label> 297 <div class="flex gap-2"> 298 <select 299 + id="brewer-select" 300 bind:value={form.brewer_rkey} 301 class="flex-1 rounded-lg border-2 border-brown-300 shadow-sm focus:border-brown-600 focus:ring-brown-600 text-base py-3 px-4 truncate max-w-full bg-white" 302 > ··· 317 318 <!-- Water Amount --> 319 <div> 320 + <label for="water-amount" class="block text-sm font-medium text-brown-900 mb-2">Water Amount (ml)</label> 321 <input 322 + id="water-amount" 323 type="number" 324 bind:value={form.water_amount} 325 step="1" ··· 330 331 <!-- Water Temperature --> 332 <div> 333 + <label for="water-temp" class="block text-sm font-medium text-brown-900 mb-2">Water Temperature (°C)</label> 334 <input 335 + id="water-temp" 336 type="number" 337 bind:value={form.water_temp} 338 step="0.1" ··· 343 344 <!-- Brew Time --> 345 <div> 346 + <label for="brew-time" class="block text-sm font-medium text-brown-900 mb-2">Total Brew Time (seconds)</label> 347 <input 348 + id="brew-time" 349 type="number" 350 bind:value={form.brew_time} 351 step="1" ··· 357 <!-- Pours --> 358 <div> 359 <div class="flex items-center justify-between mb-2"> 360 + <span class="block text-sm font-medium text-brown-900">Pour Schedule (Optional)</span> 361 <button 362 type="button" 363 on:click={addPour} ··· 399 400 <!-- Rating --> 401 <div> 402 + <label for="rating" class="block text-sm font-medium text-brown-900 mb-2"> 403 Rating: <span class="font-bold">{form.rating}/10</span> 404 </label> 405 <input 406 + id="rating" 407 type="range" 408 bind:value={form.rating} 409 min="0" ··· 419 420 <!-- Notes --> 421 <div> 422 + <label for="notes" class="block text-sm font-medium text-brown-900 mb-2">Tasting Notes</label> 423 <textarea 424 + id="notes" 425 bind:value={form.notes} 426 rows="4" 427 placeholder="Describe the flavor, aroma, body, etc." ··· 460 > 461 <div class="space-y-4"> 462 <div> 463 + <label for="bean-name" class="block text-sm font-medium text-gray-700 mb-1">Name</label> 464 + <input id="bean-name" type="text" bind:value={beanForm.name} class="w-full rounded border-gray-300 px-3 py-2" /> 465 </div> 466 <div> 467 + <label for="bean-origin" class="block text-sm font-medium text-gray-700 mb-1">Origin *</label> 468 + <input id="bean-origin" type="text" bind:value={beanForm.origin} required class="w-full rounded border-gray-300 px-3 py-2" /> 469 </div> 470 <div> 471 + <label for="bean-roast-level" class="block text-sm font-medium text-gray-700 mb-1">Roast Level *</label> 472 + <select id="bean-roast-level" bind:value={beanForm.roast_level} required class="w-full rounded border-gray-300 px-3 py-2"> 473 <option value="">Select...</option> 474 <option value="Light">Light</option> 475 <option value="Medium-Light">Medium-Light</option> ··· 479 </select> 480 </div> 481 <div> 482 + <label for="bean-roaster" class="block text-sm font-medium text-gray-700 mb-1">Roaster</label> 483 <div class="flex gap-2"> 484 + <select id="bean-roaster" bind:value={beanForm.roaster_rkey} class="flex-1 rounded border-gray-300 px-3 py-2"> 485 <option value="">Select...</option> 486 {#each roasters as roaster} 487 <option value={roaster.rkey}>{roaster.name}</option> ··· 507 > 508 <div class="space-y-4"> 509 <div> 510 + <label for="roaster-name" class="block text-sm font-medium text-gray-700 mb-1">Name *</label> 511 + <input id="roaster-name" type="text" bind:value={roasterForm.name} required class="w-full rounded border-gray-300 px-3 py-2" /> 512 </div> 513 <div> 514 + <label for="roaster-location" class="block text-sm font-medium text-gray-700 mb-1">Location</label> 515 + <input id="roaster-location" type="text" bind:value={roasterForm.location} class="w-full rounded border-gray-300 px-3 py-2" /> 516 </div> 517 </div> 518 </Modal> ··· 525 > 526 <div class="space-y-4"> 527 <div> 528 + <label for="grinder-name" class="block text-sm font-medium text-gray-700 mb-1">Name *</label> 529 + <input id="grinder-name" type="text" bind:value={grinderForm.name} required class="w-full rounded border-gray-300 px-3 py-2" /> 530 </div> 531 <div> 532 + <label for="grinder-type" class="block text-sm font-medium text-gray-700 mb-1">Type</label> 533 + <select id="grinder-type" bind:value={grinderForm.grinder_type} class="w-full rounded border-gray-300 px-3 py-2"> 534 <option value="">Select...</option> 535 <option value="Manual">Manual</option> 536 <option value="Electric">Electric</option> ··· 548 > 549 <div class="space-y-4"> 550 <div> 551 + <label for="brewer-name" class="block text-sm font-medium text-gray-700 mb-1">Name *</label> 552 + <input id="brewer-name" type="text" bind:value={brewerForm.name} required class="w-full rounded border-gray-300 px-3 py-2" /> 553 </div> 554 <div> 555 + <label for="brewer-type" class="block text-sm font-medium text-gray-700 mb-1">Type</label> 556 + <select id="brewer-type" bind:value={brewerForm.brewer_type} class="w-full rounded border-gray-300 px-3 py-2"> 557 <option value="">Select...</option> 558 <option value="Pour Over">Pour Over</option> 559 <option value="French Press">French Press</option>
+1 -1
web/static/app/index.html
··· 18 <!-- Web Manifest --> 19 <link rel="manifest" href="/static/manifest.json"> 20 <meta name="theme-color" content="#78350f"> 21 - <script type="module" crossorigin src="/static/app/assets/index-PnQOiph1.js"></script> 22 <link rel="stylesheet" crossorigin href="/static/app/assets/index-C3lHx5fe.css"> 23 </head> 24 <body class="bg-brown-50 text-brown-900 min-h-screen">
··· 18 <!-- Web Manifest --> 19 <link rel="manifest" href="/static/manifest.json"> 20 <meta name="theme-color" content="#78350f"> 21 + <script type="module" crossorigin src="/static/app/assets/index-D8yIXtJi.js"></script> 22 <link rel="stylesheet" crossorigin href="/static/app/assets/index-C3lHx5fe.css"> 23 </head> 24 <body class="bg-brown-50 text-brown-900 min-h-screen">