Skip to content

Commit

Permalink
Enforce the nameLowerCase index uniqueness again. (#35)
Browse files Browse the repository at this point in the history
* Add the DB migration from `v3` to `v4`.
* Add the deduplication logic for `CoffeeBeans` during import.
* Fix the dark mode UI catastrophy. By removing the present dark theme styles, until we have a real dark theme.
* Make the forms do the `CoffeeBeans` name uniqueness checks on an `input change`, not just on a `submit`.
* Add a toast explaining that the data deletion may take some time.
* Add a link to my LinkedIn on the `/other` page.
* Update the About section on the `/other` page.
* Update the `README.md`.
* Update the screenshots in `README.md`.
  • Loading branch information
dima-iholkin committed Jul 18, 2024
1 parent d8176a1 commit e265702
Show file tree
Hide file tree
Showing 55 changed files with 559 additions and 132 deletions.
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# Changelog

## [1.0.0] - 2024-07-19

### Added

- Make the forms do the `CoffeeBeans` name uniqueness checks on an `input change`, not just on a `submit`.
- Add a toast explaining that the data deletion may take some time.
- Add a link to my LinkedIn on the `/other` page.

### Changed

- Update the About section on the `/other` page.
- Update the `README.md`.
- Update the screenshots in `README.md`.

### Fixed

- Enforce the `nameLowerCase` index uniqueness again.
- With a new DB schema `v4`.
- Add the DB migration from `v3` to `v4`.
- Add the deduplication logic for `CoffeeBeans` during import.
- Fix the dark mode UI catastrophy.
- By removing the present dark theme styles, until we have a real dark theme.

## [0.28.0] - 2024-06-11

### Added
Expand Down
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,14 @@ This app is used daily. I'm maintaining and improving it when I can.
<kbd>
<img width="250" src="/_assets/recipes.png" title="screenshot showing a list of recipes in PourOverPotato app">
</kbd>
&nbsp;&nbsp;
<kbd>
<img width="250" src="/_assets/other.png" title="screenshot showing page Other in PourOverPotato app">
</kbd>
</div>

## About your data

By design all your data is saved in your browser only and on your device only, it's not sent anywhere, there is no server. You can import and export your data to and from a file.
Much later I would like to add an ability to sync data with Google Drive.

The application is in active development. Things may change and data integrity is not guaranteed. However I'll try hard to not break your data.
Unfortunately it's likely that I won't be able to develop the app much more. However it was and is in a very good and usable state since the very early versions long time ago and I will continue using it.

## Support me

Expand Down
Binary file modified _assets/coffee_beans.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed _assets/other.png
Binary file not shown.
Binary file modified _assets/recipes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pouroverpotato",
"version": "0.28.0",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "vite dev",
Expand Down
4 changes: 2 additions & 2 deletions src/lib/UI/domainComponents/cards/CoffeeBeansCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
}
h5 {
@apply text-2xl font-bold tracking-tight text-gray-900 dark:text-white;
@apply text-2xl font-bold tracking-tight text-gray-900;
overflow-wrap: anywhere;
}
Expand All @@ -66,6 +66,6 @@
}
p {
@apply font-normal text-gray-700 dark:text-gray-400;
@apply font-normal text-gray-700;
}
</style>
4 changes: 2 additions & 2 deletions src/lib/UI/domainComponents/cards/RecipeCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@
}
h5 {
@apply text-2xl font-bold tracking-tight text-gray-900 dark:text-white;
@apply text-2xl font-bold tracking-tight text-gray-900;
}
.label {
@apply inline text-base font-normal text-gray-400;
}
.content {
@apply inline font-normal dark:text-gray-400;
@apply inline font-normal;
white-space: pre-line;
}
</style>
6 changes: 2 additions & 4 deletions src/lib/UI/domainComponents/forms/CoffeeBeansSelect.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
{/if}
</div>
</div>
<p class="text-sm text-red-600 dark:text-red-500" class:mt-2={validationMessage.length > 0}>{validationMessage}</p>
<p class="text-sm text-red-600" class:mt-2={validationMessage.length > 0}>{validationMessage}</p>
</div>

<style lang="postcss">
Expand All @@ -110,13 +110,11 @@
.valid {
@apply bg-gray-50 border border-gray-300 text-gray-900 text-base rounded-lg p-2.5;
@apply focus:ring-blue-500 focus:border-blue-500;
@apply dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white;
@apply dark:focus:ring-blue-500 dark:focus:border-blue-500;
}
.invalid {
@apply bg-red-50 border border-red-500 text-red-900 placeholder-red-700 text-base rounded-lg focus:ring-red-500;
@apply focus:border-red-500 block w-full p-2.5 dark:bg-red-100 dark:border-red-400;
@apply focus:border-red-500 block w-full p-2.5;
background-color: #fef2f2;
}
Expand Down
2 changes: 0 additions & 2 deletions src/lib/UI/domainComponents/forms/FavoriteCheckbox.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
input {
@apply bg-gray-50 border-x-0 border-gray-300 h-11 text-center text-gray-900 text-base block w-full py-2.5;
@apply focus:ring-blue-500 focus:border-blue-500;
@apply dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400;
@apply dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500;
border-top-color: rgb(209, 213, 219);
border-top-style: solid;
border-top-width: 0.8px;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/UI/domainComponents/forms/TimestampPicker.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<Label for_={TIMESTAMP}>Timestamp:</Label>
<input
id={TIMESTAMP}
class="bg-gray-50 border border-gray-300 text-gray-900 text-base rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
class="bg-gray-50 border border-gray-300 text-gray-900 text-base rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5"
name={TIMESTAMP}
type="datetime-local"
bind:value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,12 @@
/* Typography: */
@apply text-base font-normal tracking-tight;
/* Colors: */
@apply text-gray-900 dark:text-white;
@apply text-gray-900;
}
select {
@apply bg-white text-gray-900 border border-gray-300 rounded-lg;
@apply focus:ring-blue-500 focus:border-blue-500;
@apply dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white;
@apply dark:focus:ring-blue-500 dark:focus:border-blue-500;
padding: 0.625rem 1rem 0.625rem 0.5rem;
}
</style>
4 changes: 1 addition & 3 deletions src/lib/UI/domainComponents/lists/SortRecipesSelect.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,12 @@
/* Typography: */
@apply text-base font-normal tracking-tight;
/* Colors: */
@apply text-gray-900 dark:text-white;
@apply text-gray-900;
}
select {
@apply bg-white text-gray-900 border border-gray-300 rounded-lg;
@apply focus:ring-blue-500 focus:border-blue-500;
@apply dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white;
@apply dark:focus:ring-blue-500 dark:focus:border-blue-500;
padding: 0.625rem 1rem 0.625rem 0.5rem;
}
</style>
46 changes: 33 additions & 13 deletions src/lib/UI/domainComponents/modals/EditCoffeeBeansModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<script lang="ts">
import { tick } from "svelte";
import { goto } from "$app/navigation";
import { editCoffeeBeans } from "$lib/database/manageCoffeeBeans";
import { checkCoffeeBeansDuplicate, editCoffeeBeans } from "$lib/database/manageCoffeeBeans";
import { routes } from "$lib/domain/constants/routes";
import { CoffeeBeans, CoffeeBeansEditSubmit } from "$lib/domain/entities/CoffeeBeans";
import Label from "$lib/UI/genericComponents/forms/Label.svelte";
Expand Down Expand Up @@ -49,7 +49,7 @@
let hasUnsavedChanges: boolean = false;
// Unsaved changes reactivity:
$: if (item && name === item.name && description === item.description) {
$: if (item && name.trim() === item.name && description.trim() === item.description) {
hasUnsavedChanges = false;
} else {
hasUnsavedChanges = true;
Expand All @@ -72,6 +72,9 @@
}
async function handleSubmit() {
// Trim the name and description in the form too:
name = name.trim();
description = description.trim();
// Validate and save the edited coffee beans:
const editedCoffeeBeans: CoffeeBeans = new CoffeeBeans({ id: item.id, name, description });
const coffeeBeansSubmit: CoffeeBeansEditSubmit | "ValidationFailed_NameMustBeAtLeast3CharsLong" =
Expand All @@ -88,7 +91,7 @@
// Guard clauses:
if (coffeeBeans === "Failure_NameAlreadyExist") {
nameValidationFailed = true;
validationMessage = "Coffee beans with this name exist already.";
validationMessage = "Coffee beans with this name already exist.";
return;
}
if (coffeeBeans === "CoffeeBeansNotFound") {
Expand Down Expand Up @@ -119,10 +122,30 @@
}
function handleInputChange() {
if (nameValidationFailed) {
nameValidationFailed = false;
if (CoffeeBeans.hasValidName({ name }) === "ValidationFailed_NameMustBeAtLeast3CharsLong") {
nameValidationFailed = true;
validationMessage = "Name must be at least 3 characters long.";
return;
}
if (name.trim().toLowerCase() === item.name.toLowerCase()) {
nameValidationFailed === false;
validationMessage = "";
return;
}
checkCoffeeBeansDuplicate(name).then((value) => {
switch (value) {
case "CoffeeBeansNotFound":
nameValidationFailed = false;
validationMessage = "";
break;
case "Failure_NameAlreadyExist":
nameValidationFailed = true;
validationMessage = `Coffee beans "${name.trim()}" already exist.`;
break;
default:
break;
}
});
}
function handleSaveButtonTabKeydown(event: KeyboardEvent) {
Expand Down Expand Up @@ -157,12 +180,12 @@
type="text"
bind:this={inputDom}
bind:value={name}
class:unsaved-changes={item.name !== undefined && item.name !== name}
class:unsaved-changes={item.name !== undefined && name.trim() !== item.name}
on:focusin={handleInputFocusIn}
on:input={handleInputChange}
on:keydown={handleEnterKey}
/>
<p class="mt-2 text-sm text-red-600 dark:text-red-500">{validationMessage}</p>
<p class="mt-2 text-sm text-red-600">{validationMessage}</p>
</div>
<div class="my-div mb-5">
<Textarea
Expand All @@ -179,7 +202,7 @@
</div>
<button
class="button-submit"
disabled={hasUnsavedChanges === false || CoffeeBeans.hasValidName({ name }) !== true}
disabled={nameValidationFailed || hasUnsavedChanges === false || CoffeeBeans.hasValidName({ name }) !== true}
type="submit"
bind:this={saveButtonDOM}
on:keydown={handleSaveButtonTabKeydown}
Expand All @@ -193,13 +216,11 @@
.input-name {
@apply bg-gray-50 border border-gray-300 text-gray-900 text-base rounded-lg block w-full p-2.5;
@apply focus:ring-blue-500 focus:border-blue-500;
@apply dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white;
@apply dark:focus:ring-blue-500 dark:focus:border-blue-500;
}
.input-name-validation-failed {
@apply border border-red-500 text-red-900 placeholder-red-700 text-base rounded-lg focus:ring-red-500;
@apply focus:border-red-500 block w-full p-2.5 dark:bg-red-100 dark:border-red-400;
@apply focus:border-red-500 block w-full p-2.5;
background-color: #fef2f2;
}
Expand All @@ -210,8 +231,7 @@
.button-submit {
@apply text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium;
@apply rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700;
@apply dark:focus:ring-blue-800;
@apply rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center;
width: 100%;
margin-left: 0;
margin-right: 0;
Expand Down
38 changes: 26 additions & 12 deletions src/lib/UI/domainComponents/modals/NewCoffeeBeansModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<script lang="ts">
import { tick } from "svelte";
import { addCoffeeBeans } from "$lib/database/manageCoffeeBeans";
import { addCoffeeBeans, checkCoffeeBeansDuplicate } from "$lib/database/manageCoffeeBeans";
import { CoffeeBeans, CoffeeBeansCreateSubmit } from "$lib/domain/entities/CoffeeBeans";
import Label from "$lib/UI/genericComponents/forms/Label.svelte";
import Textarea from "$lib/UI/genericComponents/forms/Textarea.svelte";
Expand Down Expand Up @@ -61,13 +61,31 @@
}
function handleInputChange() {
if (nameValidationFailed) {
nameValidationFailed = false;
validationMessage = "";
if (CoffeeBeans.hasValidName({ name }) === "ValidationFailed_NameMustBeAtLeast3CharsLong") {
nameValidationFailed = true;
validationMessage = "Name must be at least 3 characters long.";
return;
}
checkCoffeeBeansDuplicate(name).then((value) => {
switch (value) {
case "CoffeeBeansNotFound":
nameValidationFailed = false;
validationMessage = "";
break;
case "Failure_NameAlreadyExist":
nameValidationFailed = true;
validationMessage = `Coffee beans "${name.trim()}" already exist.`;
break;
default:
break;
}
});
}
async function handleFormSubmit() {
// Trim the name and description in the form too:
name = name.trim();
description = description.trim();
// Validate and save the new coffee beans:
const coffeeBeansSubmit: CoffeeBeansCreateSubmit | "ValidationFailed_NameMustBeAtLeast3CharsLong" =
CoffeeBeansCreateSubmit.create({ name, description });
Expand All @@ -83,7 +101,7 @@
// Guard clauses:
if (coffeeBeans === "Failure_NameAlreadyExist") {
nameValidationFailed = true;
validationMessage = "Coffee beans with this name exist already.";
validationMessage = "Coffee beans with this name already exist.";
return;
}
// Show a toast:
Expand Down Expand Up @@ -149,7 +167,7 @@
on:input={handleInputChange}
on:keydown={handleEnter}
/>
<p class="mt-2 text-sm text-red-600 dark:text-red-500">{validationMessage}</p>
<p class="mt-2 text-sm text-red-600">{validationMessage}</p>
</div>
<div class="my-div mb-5">
<Textarea
Expand All @@ -165,7 +183,7 @@
</div>
<button
class="button-submit"
disabled={CoffeeBeans.hasValidName({ name }) !== true}
disabled={nameValidationFailed || CoffeeBeans.hasValidName({ name }) !== true}
type="submit"
bind:this={saveButtonDOM}
on:keydown={handleSaveButtonTabKeydown}
Expand All @@ -179,14 +197,11 @@
.input-name {
@apply bg-gray-50 border border-gray-300 text-gray-900 text-base rounded-lg block w-full p-2.5;
@apply focus:ring-blue-500 focus:border-blue-500;
@apply dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white;
@apply dark:focus:ring-blue-500 dark:focus:border-blue-500;
}
.input-name-validation-failed {
@apply border border-red-500 text-red-900 placeholder-red-700 text-base rounded-lg block w-full p-2.5;
@apply focus:ring-red-500 focus:border-red-500;
@apply dark:bg-red-100 dark:border-red-400;
background-color: #fef2f2;
}
Expand All @@ -197,8 +212,7 @@
.button-submit {
@apply text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium;
@apply rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700;
@apply dark:focus:ring-blue-800;
@apply rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center;
width: 100%;
margin-left: 0;
margin-right: 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@
.add-demo-coffee-beans {
@apply text-yellow-400 hover:text-white border border-yellow-400 hover:bg-yellow-500 focus:ring-4;
@apply focus:outline-none focus:ring-yellow-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center;
@apply dark:border-yellow-300 dark:text-yellow-300 dark:hover:text-white dark:hover:bg-yellow-400;
@apply dark:focus:ring-yellow-900;
margin-top: 1rem;
}
</style>
3 changes: 1 addition & 2 deletions src/lib/UI/genericComponents/Card.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@

<style lang="postcss">
a {
@apply block bg-white border border-gray-200 rounded-lg shadow dark:bg-gray-800;
@apply dark:border-gray-700 dark:hover:bg-gray-700;
@apply block bg-white border border-gray-200 rounded-lg shadow;
margin-top: 12px;
margin-bottom: 12px;
padding: 1rem 1.5rem 1.5rem 1.5rem;
Expand Down
Loading

0 comments on commit e265702

Please sign in to comment.