Skip to content

Commit

Permalink
feat: add validations to draft gallery (#466)
Browse files Browse the repository at this point in the history
  • Loading branch information
goga-m authored Nov 17, 2023
1 parent 1be672b commit 92d014c
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 9 deletions.
4 changes: 3 additions & 1 deletion resources/js/Pages/Galleries/MyGalleries/Create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,9 @@ const Create = ({
setData("name", name);
}}
onBlur={() => {
setTitle(data.name);
if (!isTruthy(errors.name)) {
setTitle(data.name);
}
}}
/>

Expand Down
2 changes: 1 addition & 1 deletion resources/js/Pages/Galleries/hooks/useGalleryForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export const useGalleryForm = ({
setData: (field, value) => {
setData(field, value);

if (field === "name" && validateName(field)) {
if (field === "name" && validateName(String(value))) {
form.setError("name", "");
}
},
Expand Down
54 changes: 50 additions & 4 deletions resources/js/Pages/Galleries/hooks/useWalletDraftGalleries.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import uniqBy from "lodash/uniqBy";
import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useIndexedDB } from "react-indexed-db-hook";
import { isTruthy } from "@/Utils/is-truthy";

Expand Down Expand Up @@ -72,7 +73,8 @@ const isExpired = (draft: GalleryDraft): boolean => {
* the state won't re-render on changes happening in indexedDB. `allDrafts` need to be
* explicitly to update the state (applies for isLoading, isSaving, hasReachedLimit, and `drafts`).
*
* For a reactive hook, see https://dexie.org/docs/dexie-react-hooks/useLiveQuery()
* For a reactive indexedDB hook,see https://dexie.org/docs/dexie-react-hooks/useLiveQuery()
*
* @param {Properties}
* @returns {WalletDraftGalleriesState}
*/
Expand All @@ -82,6 +84,7 @@ export const useWalletDraftGalleries = ({ address }: Properties): WalletDraftGal
const [isLoading, setIsLoading] = useState(true);
const [isSaving, setIsSaving] = useState(false);
const [hasReachedLimit, setHasReachedLimit] = useState(false);
const { t } = useTranslation();

const updateDraftState = useCallback(async () => {
setIsLoading(true);
Expand All @@ -102,16 +105,21 @@ export const useWalletDraftGalleries = ({ address }: Properties): WalletDraftGal
* Add new draft gallery.
*
* @param {GalleryDraft} draft
* @returns {Promise<GalleryDraft>}
* @returns {Promise<GallerySavedDraft>}
*/
const add = async (draft: GalleryDraftUnsaved): Promise<GalleryDraft> => {
const { id: _, ...draftToSave } = draft;
const allDraftsCount = await allDrafts();

if (allDraftsCount.length >= MAX_DRAFT_LIMIT_PER_WALLET) {
throw new Error("[useWalletDraftGalleries:upsert] Reached limit");
}

const { id: _, ...draftToSave } = draft;
const errors = validate(draft);

if (errors.length > 0) {
throw new Error(`[useWalletDraftGalleries:add] Validation failed. Reason ${errors.join(",")}`);
}

setIsSaving(true);

Expand All @@ -126,17 +134,55 @@ export const useWalletDraftGalleries = ({ address }: Properties): WalletDraftGal
return await findByIdOrThrow(id);
};

/**
* Validate draft before saving. Return errors if all fail.
* Drafts can be saved if either title or nfts are set. Otherwise both are required.
*
* @param {GalleryDraftUnsaved} draft
* @returns {string[]}
*/
const validate = (draft: GalleryDraftUnsaved): string[] => {
let titleError: string | undefined;
let nftsError: string | undefined;

if (!isTruthy(draft.title.trim())) {
titleError = `[useWalletDraftGalleries:validate] ${t("validation.gallery_title_required")}`;
}

if (draft.title.trim().length > 50) {
titleError = `[useWalletDraftGalleries:validate] ${t("pages.galleries.create.title_too_long", {
max: 50,
})}`;
}

if (draft.nfts.length === 0) {
nftsError = `[useWalletDraftGalleries:validate] ${t("validation.nfts_required")}`;
}

if (isTruthy(titleError) && isTruthy(nftsError)) {
return [titleError, nftsError];
}

return [];
};

/**
* Update existing gallery.
*
* @param {GalleryDraft} draft
* @returns {Promise<GalleryDraft>}
* @returns {Promise<GallerySavedDraft>}
*/
const update = async (draft: GalleryDraftUnsaved): Promise<GalleryDraft> => {
if (!isTruthy(draft.id)) {
throw new Error("[useWalletDraftGalleries:update] Missing Id");
}

const errors = validate(draft);

if (errors.length > 0) {
throw new Error(`[useWalletDraftGalleries:update] Validation failed. Reason ${errors.join(",")}`);
}

setIsSaving(true);

await database.update({
Expand Down
9 changes: 6 additions & 3 deletions resources/js/Pages/Galleries/hooks/useWalletDraftGallery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,12 @@ export const useWalletDraftGallery = ({
throw new Error("[useWalletDraftGallery:saveDraft] Trying to save draft that belongs to another wallet.");
}

const savedDraft = await upsert({ ...draft, walletAddress: address });

setDraft(savedDraft);
try {
const savedDraft = await upsert({ ...draft, walletAddress: address });
setDraft(savedDraft);
} catch {
// Ignore any errors that occur on validation when saving.
}
};

const setCover = (image: ArrayBuffer | null, name: string | null, type: string | null): void => {
Expand Down

0 comments on commit 92d014c

Please sign in to comment.