Skip to content

Commit

Permalink
deck folders
Browse files Browse the repository at this point in the history
  • Loading branch information
kubk committed Jan 7, 2024
1 parent c40b085 commit bfb1690
Show file tree
Hide file tree
Showing 18 changed files with 219 additions and 110 deletions.
11 changes: 1 addition & 10 deletions functions/db/databaseTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -476,16 +476,7 @@ export interface Database {
folder_id: number
folder_title: string
folder_description: string
deck_id: number
}[]
}
get_folder_with_decks_backup: {
Args: {
usr_id: number
}
Returns: {
folder_id: number
folder_title: string
folder_author_id: number
deck_id: number
}[]
}
Expand Down
19 changes: 19 additions & 0 deletions functions/db/folder/delete-folder-by-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { EnvSafe } from "../../env/env-schema.ts";
import { getDatabase } from "../get-database.ts";
import { DatabaseException } from "../database-exception.ts";

export const deleteFolderById = async (
env: EnvSafe,
folderId: number,
): Promise<void> => {
const db = getDatabase(env);
const deleteFolderResult = await db
.from("folder")
.delete()
.eq("id", folderId)
.single();

if (deleteFolderResult.error) {
throw new DatabaseException(deleteFolderResult.error);
}
};
1 change: 1 addition & 0 deletions functions/db/folder/get-folders-with-decks-db.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const userFoldersSchema = z.object({
folder_id: z.number(),
folder_title: z.string(),
folder_description: z.string().nullable(),
folder_author_id: z.number(),
deck_id: z.number().nullable(),
});

Expand Down
35 changes: 35 additions & 0 deletions functions/delete-folder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { handleError } from "./lib/handle-error/handle-error.ts";
import { getUser } from "./services/get-user.ts";
import { createAuthFailedResponse } from "./lib/json-response/create-auth-failed-response.ts";
import { envSchema } from "./env/env-schema.ts";
import { createBadRequestResponse } from "./lib/json-response/create-bad-request-response.ts";
import { getFolderByIdAndAuthorId } from "./db/folder/get-folder-by-id-and-author-id.ts";
import { createJsonResponse } from "./lib/json-response/create-json-response.ts";
import { deleteFolderById } from "./db/folder/delete-folder-by-id.ts";

export const onRequestPost = handleError(async ({ request, env }) => {
const user = await getUser(request, env);
if (!user) {
return createAuthFailedResponse();
}
const envSafe = envSchema.parse(env);

const url = new URL(request.url);
const folderId = url.searchParams.get("folder_id");
if (!folderId) {
return createBadRequestResponse();
}

const canEdit = await getFolderByIdAndAuthorId(
envSafe,
parseInt(folderId),
user,
);
if (!canEdit) {
return createBadRequestResponse();
}

await deleteFolderById(envSafe, parseInt(folderId));

return createJsonResponse(null);
});
14 changes: 7 additions & 7 deletions functions/upsert-folder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ const requestSchema = z.object({

export type AddFolderRequest = z.infer<typeof requestSchema>;
export type AddFolderResponse = {
folder: {
id: number;
}
folders: UserFoldersDbType[];
};

Expand All @@ -36,19 +39,15 @@ export const onRequestPost = handleError(async ({ request, env }) => {

const envSafe = envSchema.parse(env);

if (input.data.id) {
const canEdit = await getFolderByIdAndAuthorId(
envSafe,
input.data.id,
user,
);
const { data } = input;
if (data.id) {
const canEdit = await getFolderByIdAndAuthorId(envSafe, data.id, user);
if (!canEdit) {
return createBadRequestResponse();
}
}

const db = getDatabase(envSafe);
const { data } = input;

const upsertFolderResult = await db
.from("folder")
Expand Down Expand Up @@ -87,6 +86,7 @@ export const onRequestPost = handleError(async ({ request, env }) => {
}

return createJsonResponse<AddFolderResponse>({
folder: upsertFolderResult.data,
folders: await getFoldersWithDecksDb(envSafe, user.id),
});
});
18 changes: 11 additions & 7 deletions src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const addDeckAccessRequest = (body: AddDeckAccessRequest) => {
);
};

export const apiDuplicateDeckRequest = (deckId: number) => {
export const duplicateDeckRequest = (deckId: number) => {
return request<CopyDeckResponse>(`/duplicate-deck?deck_id=${deckId}`, "POST");
};

Expand Down Expand Up @@ -102,34 +102,38 @@ export const addCardRequest = (body: AddCardRequest) => {
return request<AddCardResponse, AddCardRequest>("/add-card", "POST", body);
};

export const removeDeckFromMine = (body: RemoveDeckFromMineRequest) => {
export const removeDeckFromMineRequest = (body: RemoveDeckFromMineRequest) => {
return request<RemoveDeckFromMineResponse, RemoveDeckFromMineRequest>(
"/remove-deck-from-mine",
"POST",
body,
);
};

export const apiDeckCatalog = () => {
export const deckCatalogRequest = () => {
return request<DeckCatalogResponse>("/catalog-decks");
};

export const apiDeckWithCards = (deckId: number) => {
export const deckWithCardsRequest = (deckId: number) => {
return request<DeckWithCardsResponse>(`/deck-with-cards?deck_id=${deckId}`);
};

export const apiDeckCategories = () => {
export const deckCategoriesRequest = () => {
return request<DeckCategoryResponse>("/deck-categories");
};

export const apiFolderUpsert = (body: AddFolderRequest) => {
export const folderUpsertRequest = (body: AddFolderRequest) => {
return request<AddFolderResponse, AddFolderRequest>(
"/upsert-folder",
"POST",
body,
);
};

export const apiDecksMine = () => {
export const deleteFolderRequest = (folderId: number) => {
return request<null>(`/delete-folder?folder_id=${folderId}`, "POST");
};

export const decksMineRequest = () => {
return request<DecksMineResponse>("/decks-mine");
};
6 changes: 1 addition & 5 deletions src/screens/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,7 @@ import { FolderScreen } from "./folder-review/folder-screen.tsx";
export const App = observer(() => {
useRestoreFullScreenExpand();

if (
deckListStore.isSharedDeckLoading ||
deckListStore.isDeckRemoving ||
deckListStore.isReviewAllLoading
) {
if (deckListStore.isFullScreenLoaderVisible) {
return <FullScreenLoader />;
}

Expand Down
6 changes: 3 additions & 3 deletions src/screens/deck-catalog/store/deck-catalog-store.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { makeAutoObservable } from "mobx";
import { apiDeckCatalog, apiDeckCategories } from "../../../api/api.ts";
import { deckCatalogRequest, deckCategoriesRequest } from "../../../api/api.ts";
import { fromPromise, IPromiseBasedObservable } from "mobx-utils";
import { DeckCatalogResponse } from "../../../../functions/catalog-decks.ts";
import { TextField } from "../../../lib/mobx-form/text-field.ts";
Expand Down Expand Up @@ -46,8 +46,8 @@ export class DeckCatalogStore {
}

load() {
this.decks = fromPromise(decksCached(apiDeckCatalog()));
this.categories = fromPromise(categoriesCached(apiDeckCategories()));
this.decks = fromPromise(decksCached(deckCatalogRequest()));
this.categories = fromPromise(categoriesCached(deckCategoriesRequest()));
}

get filteredDecks() {
Expand Down
13 changes: 7 additions & 6 deletions src/screens/deck-review/deck-preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import { useMainButton } from "../../lib/telegram/use-main-button.tsx";
import { showConfirm } from "../../lib/telegram/show-confirm.ts";
import { ButtonSideAligned } from "../../ui/button-side-aligned.tsx";
import { useTelegramProgress } from "../../lib/telegram/use-telegram-progress.tsx";
import { apiDuplicateDeckRequest } from "../../api/api.ts";
import { duplicateDeckRequest } from "../../api/api.ts";
import { t } from "../../translations/t.ts";
import { userStore } from "../../store/user-store.ts";

export const DeckPreview = observer(() => {
const reviewStore = useReviewStore();
Expand Down Expand Up @@ -110,7 +111,7 @@ export const DeckPreview = observer(() => {
gridTemplateColumns: "repeat(auto-fit, minmax(100px, 1fr))",
})}
>
{deckListStore.canEditDeck(deck) ? (
{deckListStore.canEditDeck ? (
<ButtonSideAligned
icon={"mdi-plus-circle mdi-24px"}
outline
Expand All @@ -124,13 +125,13 @@ export const DeckPreview = observer(() => {
{t("add_card_short")}
</ButtonSideAligned>
) : null}
{deckListStore.user?.is_admin && (
{userStore.isAdmin && (
<ButtonSideAligned
icon={"mdi-content-duplicate mdi-24px"}
outline
onClick={() => {
showConfirm(t("duplicate_confirm")).then(() => {
apiDuplicateDeckRequest(deck.id).then(() => {
duplicateDeckRequest(deck.id).then(() => {
screenStore.go({ type: "main" });
});
});
Expand All @@ -139,7 +140,7 @@ export const DeckPreview = observer(() => {
{t("duplicate")}
</ButtonSideAligned>
)}
{deckListStore.canEditDeck(deck) ? (
{deckListStore.canEditDeck ? (
<ButtonSideAligned
icon={"mdi-pencil-circle mdi-24px"}
outline
Expand All @@ -164,7 +165,7 @@ export const DeckPreview = observer(() => {
</ButtonSideAligned>
) : null}

{deckListStore.canEditDeck(deck) && (
{deckListStore.canEditDeck && (
<ButtonSideAligned
icon={"mdi-share-circle mdi-24px"}
outline
Expand Down
3 changes: 2 additions & 1 deletion src/screens/deck-review/repeat-all-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import { Hint } from "../../ui/hint.tsx";
import { t } from "../../translations/t.ts";
import { WantMoreCardsButton } from "./want-more-cards-button.tsx";
import { css } from "@emotion/css";
import { userStore } from "../../store/user-store.ts";

export const RepeatAllScreen = observer(() => {
const reviewStore = useReviewStore();

useMount(() => {
reviewStore.startAllRepeatReview(
deckListStore.myDecks,
deckListStore.user?.is_speaking_card_enabled ?? false,
userStore.isSpeakingCardsEnabled,
);
});

Expand Down
4 changes: 1 addition & 3 deletions src/screens/folder-form/folder-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import { Input } from "../../ui/input.tsx";
import React from "react";
import { useBackButton } from "../../lib/telegram/use-back-button.tsx";
import { screenStore } from "../../store/screen-store.ts";
import {
useTelegramProgress
} from "../../lib/telegram/use-telegram-progress.tsx";
import { useTelegramProgress } from "../../lib/telegram/use-telegram-progress.tsx";
import { useMount } from "../../lib/react/use-mount.ts";
import { useMainButton } from "../../lib/telegram/use-main-button.tsx";
import { assert } from "../../lib/typescript/assert.ts";
Expand Down
11 changes: 6 additions & 5 deletions src/screens/folder-form/store/folder-form-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
isFormTouched,
isFormValid,
} from "../../../lib/mobx-form/form-has-error.ts";
import { apiDecksMine, apiFolderUpsert } from "../../../api/api.ts";
import { decksMineRequest, folderUpsertRequest } from "../../../api/api.ts";
import { deckListStore } from "../../../store/deck-list-store.ts";
import { ListField } from "../../../lib/mobx-form/list-field.ts";
import { fromPromise, IPromiseBasedObservable } from "mobx-utils";
Expand Down Expand Up @@ -39,7 +39,7 @@ export class FolderFormStore {
assert(screen.type === "folderForm");

this.decksMine = fromPromise(
apiDecksMine().then((response) => response.decks),
decksMineRequest().then((response) => response.decks),
);

if (screen.folderId) {
Expand Down Expand Up @@ -90,16 +90,17 @@ export class FolderFormStore {

this.isSending = true;

apiFolderUpsert({
folderUpsertRequest({
id: screen.folderId,
title: this.folderForm.title.value,
description: this.folderForm.description.value,
deckIds: this.folderForm.decks.value.map((deck) => deck.id),
})
.then(({ folders }) => {
deckListStore.optimisticUpdateFolders(folders);
.then(({ folders, folder }) => {
deckListStore.updateFolders(folders);
assert(this.folderForm);
formUnTouchAll(this.folderForm);
screenStore.go({ type: "folderPreview", folderId: folder.id });
})
.finally(
action(() => {
Expand Down
24 changes: 15 additions & 9 deletions src/screens/folder-review/folder-preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ import { useReviewStore } from "../deck-review/store/review-store-context.tsx";
import { SettingsRow } from "../user-settings/settings-row.tsx";
import { ListHeader } from "../../ui/list-header.tsx";
import { assert } from "../../lib/typescript/assert.ts";
import { userStore } from "../../store/user-store.ts";

export const FolderPreview = observer(() => {
const reviewStore = useReviewStore();

useBackButton(() => {
screenStore.back();
screenStore.go({ type: "main" });
});

useTelegramProgress(() => deckListStore.isDeckCardsLoading);
Expand All @@ -30,7 +31,10 @@ export const FolderPreview = observer(() => {
() => {
const folder = deckListStore.selectedFolder;
assert(folder);
reviewStore.startFolderReview(folder.decks);
reviewStore.startFolderReview(
folder.decks,
userStore.isSpeakingCardsEnabled,
);
},
() => deckListStore.isFolderReviewVisible,
);
Expand Down Expand Up @@ -118,7 +122,7 @@ export const FolderPreview = observer(() => {
gridTemplateColumns: "repeat(auto-fit, minmax(100px, 1fr))",
})}
>
{true ? (
{deckListStore.canEditFolder ? (
<ButtonSideAligned
icon={"mdi-pencil-circle mdi-24px"}
outline
Expand All @@ -129,13 +133,15 @@ export const FolderPreview = observer(() => {
{t("edit")}
</ButtonSideAligned>
) : null}
{true ? (
{deckListStore.canEditFolder ? (
<ButtonSideAligned
icon={"mdi-delete-circle mdi-24px"}
outline
onClick={() => {
showConfirm(t("delete_deck_confirm")).then(() => {
// deckListStore.removeDeck();
showConfirm(
"Do you want to delete the folder? Deleting folder won't remove decks inside the folder",
).then(() => {
deckListStore.deleteFolder();
});
}}
>
Expand Down Expand Up @@ -164,10 +170,10 @@ export const FolderPreview = observer(() => {
</SettingsRow>
);
})}
{folder.cardsToReview.length === 0 && (
<Hint>{t("no_cards_to_review_in_deck")}</Hint>
)}
</div>
{folder.cardsToReview.length === 0 && (
<Hint>{t("no_cards_to_review_in_deck")}</Hint>
)}
</div>
);
});
Loading

0 comments on commit bfb1690

Please sign in to comment.