Skip to content

Commit

Permalink
Merge pull request #205 from cabcookie:include-bible-reading
Browse files Browse the repository at this point in the history
Bibellesen integrieren
  • Loading branch information
cabcookie authored Oct 1, 2024
2 parents b03d27b + 063ca47 commit 6772247
Show file tree
Hide file tree
Showing 31 changed files with 10,821 additions and 3,394 deletions.
33 changes: 33 additions & 0 deletions amplify/data/bible-schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { a } from "@aws-amplify/backend";

const bibleSchema = {
Section: a.enum(["OLD", "NEW"]),
BookOfBible: a
.model({
notionId: a.integer(),
book: a.string().required(),
chapters: a
.hasMany("NotesBibleChapter", "bookId")
.authorization((allow) => [allow.owner()]),
alias: a.string().required(),
section: a.ref("Section").required(),
noOfChapters: a.integer(),
})
.authorization((allow) => [allow.authenticated().to(["read"])]),
NotesBibleChapter: a
.model({
owner: a
.string()
.authorization((allow) => [allow.owner().to(["read", "delete"])]),
notionId: a.integer(),
bookId: a.id().required(),
chapter: a.integer().required(),
book: a.belongsTo("BookOfBible", "bookId"),
note: a.string(),
formatVersion: a.integer().default(1),
noteJson: a.json(),
})
.authorization((allow) => [allow.owner()]),
};

export default bibleSchema;
2 changes: 2 additions & 0 deletions amplify/data/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { a, defineData, type ClientSchema } from "@aws-amplify/backend";
import { postConfirmation } from "../auth/post-confirmation/resource";
import accountSchema from "./account-schema";
import activitySchema from "./activity-schema";
import bibleSchema from "./bible-schema";
import contextSchema from "./context-schema";
import personSchmema from "./person-schema";
import planningSchema from "./planning-schema";
Expand All @@ -17,6 +18,7 @@ const schema = a
...projectSchema,
...prayerSchema,
...planningSchema,
...bibleSchema,
Inbox: a
.model({
owner: a
Expand Down
116 changes: 116 additions & 0 deletions api/useBible.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { type Schema } from "@/amplify/data/resource";
import {
checkReadingDue,
getLastReadChapterNo,
getSortVal,
} from "@/helpers/bible/bible";
import { transformNotesVersion } from "@/helpers/bible/transformers";
import { JSONContent } from "@tiptap/core";
import { generateClient, SelectionSet } from "aws-amplify/data";
import { flow, map, sortBy } from "lodash/fp";
import useSWR from "swr";
import { handleApiErrors } from "./globals";
const client = generateClient<Schema>();

export type BibleBookChapter = {
id: string;
chapter: number;
notes: JSONContent;
createdAt: Date;
updatedAt: Date;
};

export type BibleBook = {
id: string;
book: string;
section: BibleSection;
alias: string;
noOfChapters?: number;
chapters: BibleBookChapter[];
lastReadChapter?: number;
readingDue: boolean;
};

export const selectionSet = [
"id",
"book",
"section",
"alias",
"noOfChapters",
"chapters.id",
"chapters.chapter",
"chapters.note",
"chapters.noteJson",
"chapters.formatVersion",
"chapters.createdAt",
"chapters.updatedAt",
] as const;

export type BibleBookData = SelectionSet<
Schema["BookOfBible"]["type"],
typeof selectionSet
>;

export type BibleSection = BibleBookData["section"];

export const mapBibleChapter = ({
id,
chapter,
note,
noteJson,
formatVersion,
createdAt,
updatedAt,
}: BibleBookData["chapters"][number]): BibleBookChapter => ({
id,
chapter,
notes: transformNotesVersion({ note, noteJson, formatVersion }),
createdAt: new Date(createdAt),
updatedAt: new Date(updatedAt),
});

export const mapBible = ({
id,
book,
alias,
noOfChapters,
chapters,
section,
}: BibleBookData): BibleBook => {
const lastReadChapter = getLastReadChapterNo(chapters, section);

return {
id,
book,
section,
alias,
noOfChapters: noOfChapters ?? undefined,
chapters: flow(
map(mapBibleChapter),
sortBy(({ createdAt }) => -createdAt.getTime())
)(chapters),
lastReadChapter,
readingDue: checkReadingDue(chapters, noOfChapters, section),
};
};

const fetchBible = async (): Promise<BibleBook[] | undefined> => {
const { data, errors } = await client.models.BookOfBible.list({
limit: 100,
selectionSet,
});
if (errors) {
handleApiErrors(errors, "Error loading books of the bible");
throw errors;
}
if (!data) throw new Error("fetchBible didn't return data");
return flow(map(mapBible), sortBy(getSortVal))(data);
};

const useBible = () => {
const { data: bible, isLoading, error } = useSWR("/api/bible", fetchBible);

return { bible, isLoading, error };
};

export default useBible;
71 changes: 71 additions & 0 deletions api/useBibleBook.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { type Schema } from "@/amplify/data/resource";
import { emptyDocument } from "@/components/ui-elements/editors/helpers/document";
import { generateClient } from "aws-amplify/data";
import { flow } from "lodash/fp";
import useSWR from "swr";
import { handleApiErrors } from "./globals";
import { BibleBook, mapBible, selectionSet } from "./useBible";
const client = generateClient<Schema>();

const fetchBibleBook =
(bookId: string | undefined) => async (): Promise<BibleBook | undefined> => {
if (!bookId) return;
const { data, errors } = await client.models.BookOfBible.get(
{ id: bookId },
{ selectionSet }
);
if (errors) {
handleApiErrors(errors, "Error loading book of the bible");
throw errors;
}
if (!data) throw new Error("fetchBibleBook didn't return data");
return flow(mapBible)(data);
};

const useBibleBook = (bookId: string | undefined) => {
const {
data: book,
isLoading,
error,
mutate,
} = useSWR(`/api/bible/${bookId}`, fetchBibleBook(bookId));

const addChapter = async (bookId: string | undefined, chapterNo: number) => {
if (!bookId) return;
if (!book) return;
if (book.noOfChapters && chapterNo > book.noOfChapters) return;

const updated: BibleBook | undefined = !book
? undefined
: {
...book,
chapters: [
...book.chapters,
{
id: crypto.randomUUID(),
chapter: chapterNo,
notes: emptyDocument,
createdAt: new Date(),
updatedAt: new Date(),
},
],
};
if (updated) mutate(updated, false);
const { data, errors } = await client.models.NotesBibleChapter.create({
bookId,
chapter: chapterNo,
});
if (errors) handleApiErrors(errors, "Creating chapter failed");
if (updated) mutate(updated);
return data?.id;
};

return {
book,
isLoading,
error,
addChapter,
};
};

export default useBibleBook;
94 changes: 94 additions & 0 deletions api/useBibleBookChapter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { type Schema } from "@/amplify/data/resource";
import { JSONContent } from "@tiptap/core";
import { generateClient, SelectionSet } from "aws-amplify/data";
import { first, flow, get, identity } from "lodash/fp";
import useSWR from "swr";
import { handleApiErrors } from "./globals";
import { BibleBook, BibleBookData, mapBible } from "./useBible";
const client = generateClient<Schema>();

const selectionSet = [
"id",
"chapter",
"note",
"noteJson",
"formatVersion",
"createdAt",
"updatedAt",
"book.id",
"book.book",
"book.section",
"book.alias",
"book.noOfChapters",
] as const;

export type BibleBookChapterData = SelectionSet<
Schema["NotesBibleChapter"]["type"],
typeof selectionSet
>;

const mapRawChapter: (chapter: BibleBookChapterData) => BibleBookData = (
chapter
) => ({
...chapter.book,
chapters: [chapter],
});

const fetchBibleBookChapter =
(chapterId: string | undefined) =>
async (): Promise<BibleBook | undefined> => {
if (!chapterId) return;
const { data, errors } = await client.models.NotesBibleChapter.get(
{ id: chapterId },
{ selectionSet }
);
if (errors) {
handleApiErrors(errors, "Error loading chapter of book of the bible");
throw errors;
}
if (!data) throw new Error("fetchBibleBookChapter didn't return data");
return flow(mapRawChapter, mapBible)(data);
};

const useBibleBookChapter = (chapterId: string | undefined) => {
const {
data: book,
isLoading,
error,
mutate,
} = useSWR(`/api/chapter/${chapterId}`, fetchBibleBookChapter(chapterId));

const updateNotes = async (notes: JSONContent) => {
if (!book) return;
const theChapter = flow(identity<BibleBook>, get("chapters"), first)(book);
if (!theChapter) return;
const updated: BibleBook = {
...book,
chapters: [
{
...theChapter,
notes,
},
],
};
mutate(updated, false);
const { data, errors } = await client.models.NotesBibleChapter.update({
id: theChapter.id,
note: null,
noteJson: JSON.stringify(notes),
formatVersion: 2,
});
if (errors) handleApiErrors(errors, "Updating chapter notes failed");
mutate(updated);
return data?.id;
};

return {
book,
isLoading,
error,
updateNotes,
};
};

export default useBibleBookChapter;
33 changes: 0 additions & 33 deletions components/activities/activity-meta-data.tsx

This file was deleted.

3 changes: 0 additions & 3 deletions components/activities/activity-notes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import DefaultAccordionItem from "../ui-elements/accordion/DefaultAccordionItem"
import { getTextFromJsonContent } from "../ui-elements/editors/helpers/text-generation";
import NotesEditor from "../ui-elements/editors/notes-editor/NotesEditor";
import ActivityFormatBadge from "./activity-format-badge";
import ActivityMetaData from "./activity-meta-data";

type ActivityNotesProps = {
activity?: Activity;
Expand All @@ -27,8 +26,6 @@ const ActivityNotes: FC<ActivityNotesProps> = ({ activity, readOnly }) => {
readonly={readOnly}
key={activity.id}
/>

<ActivityMetaData activity={activity} />
</DefaultAccordionItem>
);
};
Expand Down
Loading

0 comments on commit 6772247

Please sign in to comment.