From b21ec1b7aca8e825f296a2419ae70f0d73066a66 Mon Sep 17 00:00:00 2001 From: Thiago Chaves Date: Mon, 29 Aug 2022 00:29:01 +0300 Subject: [PATCH] Add settings, cards list, card preview views * Settings view is no longer the card creation view * Add icons for the two settings options --- public/icons/file-plus.svg | 9 ++++ public/icons/list.svg | 11 ++++ src/components/Page/Page.tsx | 10 +++- .../SettingsSection/SettingsSectionLink.tsx | 26 ++++++++++ src/components/SettingsSection/index.ts | 1 + src/hooks/index.ts | 3 ++ src/hooks/useExpressionById.ts | 9 ++++ src/hooks/useExpressionQueryId.ts | 7 +++ src/hooks/useExpressions.ts | 9 ++++ src/model/routing.ts | 8 ++- .../ExpressionCardListView.tsx | 50 +++++++++++++++++++ src/views/ExpressionCardListView/index.ts | 1 + .../ExpressionCardView/ExpressionCardView.tsx | 20 ++++++++ src/views/ExpressionCardView/index.ts | 1 + src/views/SettingsView/SettingsView.tsx | 21 ++++++++ src/views/SettingsView/index.ts | 1 + 16 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 public/icons/file-plus.svg create mode 100644 public/icons/list.svg create mode 100644 src/components/SettingsSection/SettingsSectionLink.tsx create mode 100644 src/components/SettingsSection/index.ts create mode 100644 src/hooks/useExpressionById.ts create mode 100644 src/hooks/useExpressionQueryId.ts create mode 100644 src/hooks/useExpressions.ts create mode 100644 src/views/ExpressionCardListView/ExpressionCardListView.tsx create mode 100644 src/views/ExpressionCardListView/index.ts create mode 100644 src/views/ExpressionCardView/ExpressionCardView.tsx create mode 100644 src/views/ExpressionCardView/index.ts create mode 100644 src/views/SettingsView/SettingsView.tsx create mode 100644 src/views/SettingsView/index.ts diff --git a/public/icons/file-plus.svg b/public/icons/file-plus.svg new file mode 100644 index 0000000..c9a0fdb --- /dev/null +++ b/public/icons/file-plus.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/icons/list.svg b/public/icons/list.svg new file mode 100644 index 0000000..9da4f57 --- /dev/null +++ b/public/icons/list.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/components/Page/Page.tsx b/src/components/Page/Page.tsx index a0c01f6..37c7257 100644 --- a/src/components/Page/Page.tsx +++ b/src/components/Page/Page.tsx @@ -6,7 +6,10 @@ import { ExpressionSetListView, } from "../../views"; import { AddExpressionView } from "../../views/AddExpressionView"; +import { ExpressionCardListView } from "../../views/ExpressionCardListView"; +import { ExpressionCardView } from "../../views/ExpressionCardView"; import { HomeView } from "../../views/HomeView"; +import { SettingsView } from "../../views/SettingsView"; export function Page() { const { route } = useContext(AppRouting); @@ -22,7 +25,12 @@ export function Page() { case AppPath.ExpressionSetsPractice: return ; case AppPath.Settings: - // TODO this should split onto more views + return ; + case AppPath.CreateCards: return ; + case AppPath.CardsList: + return ; + case AppPath.CardView: + return ; } } diff --git a/src/components/SettingsSection/SettingsSectionLink.tsx b/src/components/SettingsSection/SettingsSectionLink.tsx new file mode 100644 index 0000000..9bff87d --- /dev/null +++ b/src/components/SettingsSection/SettingsSectionLink.tsx @@ -0,0 +1,26 @@ +import { useContext } from "react"; +import { AppPath, AppRouting } from "../../model/routing"; + +export interface SettingsSectionLinkProps { + text: string; + iconUrl?: string; + page: AppPath; +} + +export function SettingsSectionLink({ + text, + iconUrl, + page, +}: SettingsSectionLinkProps) { + const { setRoute } = useContext(AppRouting); + return ( +
  • setRoute({ path: page })}> +
    +
    + {iconUrl && } +

    {text}

    +
    +
    +
  • + ); +} diff --git a/src/components/SettingsSection/index.ts b/src/components/SettingsSection/index.ts new file mode 100644 index 0000000..045c9f8 --- /dev/null +++ b/src/components/SettingsSection/index.ts @@ -0,0 +1 @@ +export * from "./SettingsSectionLink"; diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 2158ec8..ba7648a 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -1,5 +1,8 @@ export * from "./useExpressionCategories"; +export * from "./useExpressionById"; export * from "./useExpressionFilterQueryIds"; +export * from "./useExpressionQueryId"; +export * from "./useExpressions"; export * from "./useExpressionSet"; export * from "./useExpressionSetQueryId"; export * from "./useExpressionSets"; diff --git a/src/hooks/useExpressionById.ts b/src/hooks/useExpressionById.ts new file mode 100644 index 0000000..3af7ccc --- /dev/null +++ b/src/hooks/useExpressionById.ts @@ -0,0 +1,9 @@ +import { useLiveQuery } from "dexie-react-hooks"; +import { database, IndexedExpression } from "../model"; + +export function useExpressionById(id?: number): IndexedExpression | undefined { + return useLiveQuery(() => { + if (id === undefined) return undefined; + return database.expressions.where({ id }).first(); + }, [id]); +} diff --git a/src/hooks/useExpressionQueryId.ts b/src/hooks/useExpressionQueryId.ts new file mode 100644 index 0000000..2476b20 --- /dev/null +++ b/src/hooks/useExpressionQueryId.ts @@ -0,0 +1,7 @@ +import { useContext } from "react"; +import { AppRouting } from "../model/routing"; + +export function useExpressionQueryId(): number | undefined { + const { route } = useContext(AppRouting); + return route.options?.expression_card_id; +} diff --git a/src/hooks/useExpressions.ts b/src/hooks/useExpressions.ts new file mode 100644 index 0000000..162dfea --- /dev/null +++ b/src/hooks/useExpressions.ts @@ -0,0 +1,9 @@ +import { useLiveQuery } from "dexie-react-hooks"; +import { database } from "../model"; + +export function useExpressions() { + return useLiveQuery( + () => database.expressions.toArray(), + [database.expressions] + ); +} diff --git a/src/model/routing.ts b/src/model/routing.ts index 0fd872c..adef827 100644 --- a/src/model/routing.ts +++ b/src/model/routing.ts @@ -7,10 +7,16 @@ export enum AppPath { ExpressionSetsPractice = "expression-sets/practice", ExpressionSetsDetails = "expression-sets/details", Settings = "settings", - CreateCards = "settings", // TODO split from settings + CardsList = "settings/cards", + CardView = "settings/view-card", + CreateCards = "settings/create-cards", } export interface RouteOptions { + // Used in cards view + expression_card_id?: number; + + // Used in practice view expression_set_id?: number; expression_id_filters?: number[]; } diff --git a/src/views/ExpressionCardListView/ExpressionCardListView.tsx b/src/views/ExpressionCardListView/ExpressionCardListView.tsx new file mode 100644 index 0000000..ba5324e --- /dev/null +++ b/src/views/ExpressionCardListView/ExpressionCardListView.tsx @@ -0,0 +1,50 @@ +import { useContext, useMemo } from "react"; +import { ExpressionCard } from "../../components"; +import { useExpressions } from "../../hooks"; +import { IndexedExpression } from "../../model"; +import { AppPath, AppRouting } from "../../model/routing"; +import { ErrorView } from "../ErrorView"; + +export function ExpressionCardListView() { + const { setRoute } = useContext(AppRouting); + const expressions = useExpressions(); + const expression_list = useMemo( + () => (expressions || []).concat().sort(sort_function), + [expressions] + ); + + if (!expressions) return null; // LOADING + if (!expressions.length) { + return ; + } + + return ( +
    +
      + {expression_list.map(({ prompt, id, description }) => ( +
    • + setRoute({ + path: AppPath.CardView, + options: { expression_card_id: id }, + }) + } + > + +
    • + ))} +
    +
    + ); +} + +function sort_function(a: IndexedExpression, b: IndexedExpression) { + if (a.prompt < b.prompt) return -1; + if (a.prompt > b.prompt) return 1; + return 0; +} diff --git a/src/views/ExpressionCardListView/index.ts b/src/views/ExpressionCardListView/index.ts new file mode 100644 index 0000000..a06c500 --- /dev/null +++ b/src/views/ExpressionCardListView/index.ts @@ -0,0 +1 @@ +export * from "./ExpressionCardListView"; diff --git a/src/views/ExpressionCardView/ExpressionCardView.tsx b/src/views/ExpressionCardView/ExpressionCardView.tsx new file mode 100644 index 0000000..e250b99 --- /dev/null +++ b/src/views/ExpressionCardView/ExpressionCardView.tsx @@ -0,0 +1,20 @@ +import { ExpressionCard } from "../../components"; +import { ExpressionDescription } from "../../components/ExpressionDescription"; +import { useExpressionById, useExpressionQueryId } from "../../hooks"; +import { ErrorView } from "../ErrorView"; + +export function ExpressionCardView() { + const expression_id = useExpressionQueryId(); + const expression = useExpressionById(expression_id); + if (!expression) return ; + return ( +
    + } + show_description + /> +
    + ); +} diff --git a/src/views/ExpressionCardView/index.ts b/src/views/ExpressionCardView/index.ts new file mode 100644 index 0000000..afd407e --- /dev/null +++ b/src/views/ExpressionCardView/index.ts @@ -0,0 +1 @@ +export * from "./ExpressionCardView"; diff --git a/src/views/SettingsView/SettingsView.tsx b/src/views/SettingsView/SettingsView.tsx new file mode 100644 index 0000000..40e3afb --- /dev/null +++ b/src/views/SettingsView/SettingsView.tsx @@ -0,0 +1,21 @@ +import { SettingsSectionLink } from "../../components/SettingsSection"; +import { AppPath } from "../../model/routing"; + +export function SettingsView() { + return ( +
    +
      + + +
    +
    + ); +} diff --git a/src/views/SettingsView/index.ts b/src/views/SettingsView/index.ts new file mode 100644 index 0000000..eb34623 --- /dev/null +++ b/src/views/SettingsView/index.ts @@ -0,0 +1 @@ +export * from "./SettingsView"; -- 2.30.2