@@ -246,6 +253,6 @@ export default function CreateFlashcard() {
Create Flashcard
-
+
)
}
diff --git a/src/routes/(app)/flashcards/edit/[id].tsx b/src/routes/(app)/flashcards/edit/[id].tsx
index 237443e..f378209 100644
--- a/src/routes/(app)/flashcards/edit/[id].tsx
+++ b/src/routes/(app)/flashcards/edit/[id].tsx
@@ -1,140 +1,145 @@
-import { requireUserEmail } from '~/session.server'
+import { requireUserEmail } from '~/server/session.server'
import { getFolderNamePath, isNonEmptyString, parseForm } from '~/utils.server'
import { Textarea } from '~/components/base/Textarea'
import { db } from '~/db/db.server'
import {
- createServerAction$,
- createServerData$,
+ useParams,
redirect,
-} from 'solid-start/server'
-import { RouteDataArgs, useParams, useRouteData } from 'solid-start'
+ action,
+ createAsync,
+ useSubmission,
+ cache,
+} from '@solidjs/router'
import { createMemo, For } from 'solid-js'
-import { supportedLocales } from '~/routes/(app)/flashcards/create'
import { z } from 'zod'
import { deleteFlashcard } from '~/flashcard.server'
-export const routeData = ({ params }: RouteDataArgs) =>
- createServerData$(
- async ([, flashcardId], { request }) => {
- const email = await requireUserEmail(request)
- const folders = await db.folder.findMany({
- where: { owner: { email } },
- })
- const tags = await db.tag.findMany({
- where: { owner: { email } },
- })
- const flashcard = await db.flashcard.findFirstOrThrow({
- where: { id: flashcardId, owner: { email } },
- include: { tags: true },
- })
+const supportedLocales = ['en-GB', 'en-US', 'ko-KR', 'es-ES'] as const
- if (!flashcard) {
- throw new Error('Not found')
+const routeData = cache(async (flashcardId: string) => {
+ 'use server'
+
+ const email = await requireUserEmail()
+ const folders = await db.folder.findMany({
+ where: { owner: { email } },
+ })
+ const tags = await db.tag.findMany({
+ where: { owner: { email } },
+ })
+ const flashcard = await db.flashcard.findFirstOrThrow({
+ where: { id: flashcardId, owner: { email } },
+ include: { tags: true },
+ })
+
+ if (!flashcard) {
+ throw new Error('Not found')
+ }
+
+ const foldersWithMappedName = folders
+ .map((folder) => {
+ return {
+ ...folder,
+ name: getFolderNamePath(folder.id, folders),
}
+ })
+ .sort((a, b) => a.name.localeCompare(b.name))
- const foldersWithMappedName = folders
- .map((folder) => {
- return {
- ...folder,
- name: getFolderNamePath(folder.id, folders),
- }
- })
- .sort((a, b) => a.name.localeCompare(b.name))
+ return { folders: foldersWithMappedName, tags, flashcard }
+}, 'flashcard-edit-id')
- return { folders: foldersWithMappedName, tags, flashcard }
- },
- { key: () => ['flashcard', params.id] }
- )
+const editFlashcard = action(async (form: FormData) => {
+ 'use server'
-export default function EditFlashcard() {
- const data = useRouteData
()
- const params = useParams()
+ const supportedLocales = ['en-GB', 'en-US', 'ko-KR', 'es-ES'] as const
+
+ const email = await requireUserEmail()
+ const action = form.get('action')
+ const id = form.get('id')
+ if (!isNonEmptyString(id)) throw new Error('Missing data')
- const [isEditing, { Form }] = createServerAction$(
- async (form: FormData, { request }) => {
- const email = await requireUserEmail(request)
- const action = form.get('action')
- const id = form.get('id')
- if (!isNonEmptyString(id)) throw new Error('Missing data')
+ await db.flashcard.findFirstOrThrow({
+ where: { id, owner: { email } },
+ })
- await db.flashcard.findFirstOrThrow({
- where: { id, owner: { email } },
+ if (action === 'update') {
+ const {
+ backDescription,
+ backLanguage,
+ frontDescription,
+ frontLanguage,
+ front,
+ back,
+ randomSideAllowed,
+ folderId,
+ tags: tagsOrTag,
+ } = z
+ .object({
+ front: z.string().nonempty(),
+ back: z.string().nonempty(),
+ frontLanguage: z.enum(supportedLocales),
+ backLanguage: z.enum(supportedLocales),
+ folderId: z.string().nonempty(),
+ tags: z
+ .array(z.string().nonempty())
+ .default([])
+ .or(z.string().nonempty()),
+ backDescription: z.string(),
+ frontDescription: z.string(),
+ randomSideAllowed: z.literal('on').optional(),
})
+ .parse(parseForm(form))
- if (action === 'update') {
- const {
- backDescription,
- backLanguage,
- frontDescription,
- frontLanguage,
- front,
- back,
- randomSideAllowed,
- folderId,
- tags: tagsOrTag,
- } = z
- .object({
- front: z.string().nonempty(),
- back: z.string().nonempty(),
- frontLanguage: z.enum(supportedLocales),
- backLanguage: z.enum(supportedLocales),
- folderId: z.string().nonempty(),
- tags: z
- .array(z.string().nonempty())
- .default([])
- .or(z.string().nonempty()),
- backDescription: z.string(),
- frontDescription: z.string(),
- randomSideAllowed: z.literal('on').optional(),
- })
- .parse(parseForm(form))
+ const tags = Array.isArray(tagsOrTag) ? tagsOrTag : [tagsOrTag]
- const tags = Array.isArray(tagsOrTag) ? tagsOrTag : [tagsOrTag]
+ await db.folder.findFirstOrThrow({
+ where: {
+ id: folderId,
+ owner: { email },
+ },
+ })
- await db.folder.findFirstOrThrow({
- where: {
- id: folderId,
- owner: { email },
- },
- })
+ const ownedTags = await db.tag.findMany({
+ where: {
+ id: {
+ in: tags,
+ },
+ owner: {
+ email,
+ },
+ },
+ })
+ if (ownedTags.length !== tags.length) {
+ throw new Error('You need to own all tags you try to assign')
+ }
- const ownedTags = await db.tag.findMany({
- where: {
- id: {
- in: tags,
- },
- owner: {
- email,
- },
- },
- })
- if (ownedTags.length !== tags.length) {
- throw new Error('You need to own all tags you try to assign')
- }
+ await db.flashcard.update({
+ where: {
+ id,
+ },
+ data: {
+ front,
+ back,
+ frontDescription,
+ backDescription,
+ frontLanguage,
+ backLanguage,
+ randomSideAllowed: randomSideAllowed === 'on',
+ folder: { connect: { id: folderId } },
+ tags: { set: tags.map((id) => ({ id })) },
+ },
+ })
+ return redirect(`/flashcards/folder/${folderId}`)
+ } else if (action === 'delete') {
+ const flashcard = await deleteFlashcard(id)
+ return redirect(`/flashcards/folder/${flashcard.folderId}`)
+ }
+}, 'edit-flashcard')
- await db.flashcard.update({
- where: {
- id,
- },
- data: {
- front,
- back,
- frontDescription,
- backDescription,
- frontLanguage,
- backLanguage,
- randomSideAllowed: randomSideAllowed === 'on',
- folder: { connect: { id: folderId } },
- tags: { set: tags.map((id) => ({ id })) },
- },
- })
- return redirect(`/flashcards/folder/${folderId}`)
- } else if (action === 'delete') {
- const flashcard = await deleteFlashcard(id)
- return redirect(`/flashcards/folder/${flashcard.folderId}`)
- }
- }
- )
+export default function EditFlashcard() {
+ const params = useParams()
+ const data = createAsync(() => routeData(params.id))
+
+ const isEditing = useSubmission(editFlashcard)
const tagIds = createMemo(() => data()?.flashcard.tags.map((tag) => tag.id))
const formatter = new Intl.DisplayNames('en-US', {
@@ -151,8 +156,8 @@ export default function EditFlashcard() {
return (
{isEditing.pending &&
Updating...
}
- {isEditing.error &&
{isEditing.error.message}
}
-
)
}
diff --git a/src/routes/(app)/flashcards/folder/edit/[id].tsx b/src/routes/(app)/flashcards/folder/edit/[id].tsx
index f280d31..9b98aab 100644
--- a/src/routes/(app)/flashcards/folder/edit/[id].tsx
+++ b/src/routes/(app)/flashcards/folder/edit/[id].tsx
@@ -1,146 +1,146 @@
-import { requireUserEmail } from '~/session.server'
+import { requireUserEmail } from '~/server/session.server'
import { getFolderNamePath, isNonEmptyString, parseForm } from '~/utils.server'
import { Input } from '~/components/base/Input'
+import { db } from '~/db/db.server'
import {
- createServerAction$,
- createServerData$,
+ useParams,
redirect,
-} from 'solid-start/server'
-import { db } from '~/db/db.server'
-import { FormError, RouteDataArgs, useParams, useRouteData } from 'solid-start'
+ cache,
+ createAsync,
+ action,
+ useSubmission,
+} from '@solidjs/router'
import { folderForm } from '~/schemas/folder'
-export const routeData = ({ params }: RouteDataArgs) =>
- createServerData$(
- async ([, id], { request }) => {
- const email = await requireUserEmail(request)
- const folders = await db.folder.findMany({ where: { owner: { email } } })
-
- const prohibitedFolders: string[] = []
- let currentProhibitedFolder: string | null | undefined = id
- while (currentProhibitedFolder) {
- prohibitedFolders.push(currentProhibitedFolder)
- currentProhibitedFolder = folders.find(
- (folder) => folder.parentFolderId === currentProhibitedFolder
- )?.id
- }
+const routeData = cache(async (prohibitedFolderId: string) => {
+ 'use server'
+
+ const email = await requireUserEmail()
+ const folders = await db.folder.findMany({ where: { owner: { email } } })
- const foldersWithMappedName = folders
- .filter((folder) => !prohibitedFolders.includes(folder.id))
- .map((folder) => {
- return {
- ...folder,
- name: getFolderNamePath(folder.id, folders),
- }
- })
- .sort((a, b) => a.name.localeCompare(b.name))
+ const prohibitedFolders: string[] = []
+ let currentProhibitedFolder: string | null | undefined = prohibitedFolderId
+ while (currentProhibitedFolder) {
+ prohibitedFolders.push(currentProhibitedFolder)
+ currentProhibitedFolder = folders.find(
+ (folder) => folder.parentFolderId === currentProhibitedFolder
+ )?.id
+ }
+ const foldersWithMappedName = folders
+ .filter((folder) => !prohibitedFolders.includes(folder.id))
+ .map((folder) => {
return {
- folders: foldersWithMappedName,
- editedFolder: folders.find((folder) => folder.id === id)!,
+ ...folder,
+ name: getFolderNamePath(folder.id, folders),
}
- },
- { key: () => ['folder', params.id] }
- )
+ })
+ .sort((a, b) => a.name.localeCompare(b.name))
-export default function EditFolder() {
- const data = useRouteData
()
- const params = useParams()
+ return {
+ folders: foldersWithMappedName,
+ editedFolder: folders.find((folder) => folder.id === prohibitedFolderId)!,
+ }
+}, 'flashcards-folder-edit-id')
- const [isEditing, { Form }] = createServerAction$(
- async (form: FormData, { request }) => {
- const email = await requireUserEmail(request)
- const id = form.get('id')
- if (!isNonEmptyString(id)) {
- return new FormError('Missing data')
- }
+const editFolder = action(async (form: FormData) => {
+ 'use server'
- const folders = await db.folder.findMany({ where: { owner: { email } } })
+ const email = await requireUserEmail()
+ const id = form.get('id')
+ if (!isNonEmptyString(id)) {
+ return new Error('Missing data')
+ }
- if (!folders.some((folder) => folder.id === id)) {
- throw new FormError(`Couldn't find folder with id ${id}`)
- }
+ const folders = await db.folder.findMany({ where: { owner: { email } } })
- const { parentFolderId, name, color } = folderForm.parse(parseForm(form))
+ if (!folders.some((folder) => folder.id === id)) {
+ throw new Error(`Couldn't find folder with id ${id}`)
+ }
- const parentFolderIds: string[] = []
- let currentParentFolderId: string | null | undefined = parentFolderId
- while (currentParentFolderId) {
- parentFolderIds.push(currentParentFolderId)
- currentParentFolderId = folders.find(
- (f) => f.id === currentParentFolderId
- )?.parentFolderId
- }
- const parentIndex = parentFolderIds.findIndex(
- (parentId) => parentId === id
- )
- if (parentIndex > -1) {
- throw new FormError(
- `Cannot set folder as its own parent folder - parent: ${parentFolderId} can't have child: ${id} because parent is already a child of ${id} (${
- parentIndex + 1
- } levels deep)`
- )
- }
+ const { parentFolderId, name, color } = folderForm.parse(parseForm(form))
+
+ const parentFolderIds: string[] = []
+ let currentParentFolderId: string | null | undefined = parentFolderId
+ while (currentParentFolderId) {
+ parentFolderIds.push(currentParentFolderId)
+ currentParentFolderId = folders.find(
+ (f) => f.id === currentParentFolderId
+ )?.parentFolderId
+ }
+ const parentIndex = parentFolderIds.findIndex((parentId) => parentId === id)
+ if (parentIndex > -1) {
+ throw new Error(
+ `Cannot set folder as its own parent folder - parent: ${parentFolderId} can't have child: ${id} because parent is already a child of ${id} (${
+ parentIndex + 1
+ } levels deep)`
+ )
+ }
- await db.folder.update({
- where: {
- id,
- },
- data: {
- name,
- color,
- parentFolder: parentFolderId
- ? { connect: { id: parentFolderId } }
- : { disconnect: true },
- },
- })
- return redirect(
- parentFolderId ? `/flashcards/folder/${parentFolderId}` : `/flashcards`
- )
- }
+ await db.folder.update({
+ where: {
+ id,
+ },
+ data: {
+ name,
+ color,
+ parentFolder: parentFolderId
+ ? { connect: { id: parentFolderId } }
+ : { disconnect: true },
+ },
+ })
+ return redirect(
+ parentFolderId ? `/flashcards/folder/${parentFolderId}` : `/flashcards`
)
+}, 'edit-folder')
- const [isDeleting, { Form: DeleteForm }] = createServerAction$(
- async (form: FormData, { request }) => {
- const email = await requireUserEmail(request)
- const id = form.get('id')
- if (!isNonEmptyString(id)) {
- return new FormError('Missing data')
- }
+const deleteFolder = action(async (form: FormData) => {
+ 'use server'
- await db.folder.findFirstOrThrow({
- where: {
- id,
- owner: { email },
- },
- })
-
- const folder = await db.folder.findFirst({
- where: {
- id,
- owner: { email },
- },
- include: {
- folders: true,
- flashcards: true,
- },
- })
- if (!folder) {
- throw new FormError('Folder not found')
- }
- if (folder.folders.length > 0 || folder.flashcards.length > 0) {
- throw new FormError('Folder not empty')
- }
- await db.folder.delete({ where: { id } })
- return redirect('/flashcards')
- }
- )
+ const email = await requireUserEmail()
+ const id = form.get('id')
+ if (!isNonEmptyString(id)) {
+ return new Error('Missing data')
+ }
+
+ await db.folder.findFirstOrThrow({
+ where: {
+ id,
+ owner: { email },
+ },
+ })
+
+ const folder = await db.folder.findFirst({
+ where: {
+ id,
+ owner: { email },
+ },
+ include: {
+ folders: true,
+ flashcards: true,
+ },
+ })
+ if (!folder) {
+ throw new Error('Folder not found')
+ }
+ if (folder.folders.length > 0 || folder.flashcards.length > 0) {
+ throw new Error('Folder not empty')
+ }
+ await db.folder.delete({ where: { id } })
+ return redirect('/flashcards')
+}, 'delete-folder')
+export default function EditFolder() {
+ const params = useParams()
+ const data = createAsync(() => routeData(params.id))
+
+ const isEditing = useSubmission(editFolder)
+ const isDeleting = useSubmission(deleteFolder)
return (
-
-
+
+
+
)
}
diff --git a/src/routes/(app)/flashcards/index.tsx b/src/routes/(app)/flashcards/index.tsx
index 7cd0ef0..9e695af 100644
--- a/src/routes/(app)/flashcards/index.tsx
+++ b/src/routes/(app)/flashcards/index.tsx
@@ -1,27 +1,27 @@
-import { requireUserEmail } from '~/session.server'
+import { requireUserEmail } from '~/server/session.server'
import { db } from '~/db/db.server'
-import { createServerData$, redirect } from 'solid-start/server'
-import { useRouteData } from 'solid-start'
+import { cache, createAsync, redirect } from '@solidjs/router'
-export const routeData = () =>
- createServerData$(async (_, { request }) => {
- const email = await requireUserEmail(request)
- const folder = await db.folder.findFirst({
- where: {
- owner: {
- email,
- },
- parentFolderId: null,
+const routeData = cache(async () => {
+ 'use server'
+
+ const email = await requireUserEmail()
+ const folder = await db.folder.findFirst({
+ where: {
+ owner: {
+ email,
},
- })
- if (!folder) {
- return redirect('/flashcards/folder/create')
- }
- return redirect(`/flashcards/folder/${folder.id}`)
+ parentFolderId: null,
+ },
})
+ if (!folder) {
+ throw redirect('/flashcards/folder/create')
+ }
+ throw redirect(`/flashcards/folder/${folder.id}`)
+}, 'flashcards-index')
export default function Index() {
- const data = useRouteData()
+ const data = createAsync(() => routeData())
data() // trigger routeData
return null
}
diff --git a/src/routes/(app)/index.tsx b/src/routes/(app)/index.tsx
index 897db39..1dcb41e 100644
--- a/src/routes/(app)/index.tsx
+++ b/src/routes/(app)/index.tsx
@@ -1,18 +1,21 @@
import { indexLoader } from '~/utils.server'
import { chunk, groupBy } from 'lodash-es'
import { clsx, daysFromNow } from '~/utils'
-import { A, useParams, useRouteData, useSearchParams } from 'solid-start'
import {
- createServerAction$,
- createServerData$,
+ useParams,
+ useSearchParams,
redirect,
-} from 'solid-start/server'
-import { requireUserEmail } from '~/session.server'
+ cache,
+ createAsync,
+ action,
+ useSubmission,
+} from '@solidjs/router'
+import { requireUserEmail } from '~/server/session.server'
+import { getNestedFlashcardsCount } from '~/server/getNestedFlashcardsCount'
import { createMemo, createSignal, Show } from 'solid-js'
import { Button } from '~/components/base/Button'
import { db } from '~/db/db.server'
import { createLearningSession } from '~/service/learningSession'
-import { getNestedFlashcardsCount } from '~/routes/(app)/flashcards/folder/[folderId]'
import { Prisma } from '@prisma/client'
import { HeadingSmall } from '~/components/base/Heading'
import { Sidebar } from '~/components/Sidebar'
@@ -29,80 +32,123 @@ type Folder = Prisma.FolderGetPayload<{}> & {
const MS_IN_DAY = 24 * 60 * 60 * 1000
-export const flashcardsServerData = () =>
- createServerData$(async (_, event) => {
- const email = await requireUserEmail(event.request)
- return await indexLoader(email)
- })
+const flashcardsServerData = async () => {
+ const email = await requireUserEmail()
+ return await indexLoader(email)
+}
-const activeLearningSession = () =>
- createServerData$(async (_, event) => {
- const email = await requireUserEmail(event.request)
- return await db.learningSession.findUnique({
- where: {
- ownerEmail: email,
- },
- include: {
- _count: {
- select: {
- completedFlashcards: true,
- uncompletedFlashcards: true,
- },
+const activeLearningSession = async () => {
+ const email = await requireUserEmail()
+ return await db.learningSession.findUnique({
+ where: {
+ ownerEmail: email,
+ },
+ include: {
+ _count: {
+ select: {
+ completedFlashcards: true,
+ uncompletedFlashcards: true,
},
},
- })
+ },
})
+}
-const folders = () =>
- createServerData$(async (_, { request }) => {
- const email = await requireUserEmail(request)
- const allFolders: Array = await Promise.all(
- (
- await db.folder.findMany({
- where: {
- owner: {
- email,
- },
+const folders = async () => {
+ const email = await requireUserEmail()
+ const allFolders: Array = await Promise.all(
+ (
+ await db.folder.findMany({
+ where: {
+ owner: {
+ email,
},
- })
- ).map(async (folder) => {
- return {
- ...folder,
- flashcardsCount: await getNestedFlashcardsCount(folder, email),
- subfolders: [],
- }
+ },
})
- )
- const foldersById = Object.fromEntries(
- allFolders.map((folder) => [folder.id, folder])
- )
- const folders: Array = []
- for (const folder of allFolders) {
- if (folder.parentFolderId === null) {
- folders.push(folder)
+ ).map(async (folder) => {
+ return {
+ ...folder,
+ flashcardsCount: await getNestedFlashcardsCount(folder, email),
+ subfolders: [],
+ }
+ })
+ )
+ const foldersById = Object.fromEntries(
+ allFolders.map((folder) => [folder.id, folder])
+ )
+ const folders: Array = []
+ for (const folder of allFolders) {
+ if (folder.parentFolderId === null) {
+ folders.push(folder)
+ } else {
+ const parent = foldersById[folder.parentFolderId]
+ if (parent) {
+ parent.subfolders.push(folder)
} else {
- const parent = foldersById[folder.parentFolderId]
- if (parent) {
- parent.subfolders.push(folder)
- } else {
- throw new Error(
- `Invalid folder structure, got ${JSON.stringify(
- folder
- )}, but folder with ${folder.parentFolderId} does not exist`
- )
- }
+ throw new Error(
+ `Invalid folder structure, got ${JSON.stringify(
+ folder
+ )}, but folder with ${folder.parentFolderId} does not exist`
+ )
}
}
- return folders
- })
+ }
+ return folders
+}
+
+const routeData = cache(async () => {
+ 'use server'
-export const routeData = () => {
return {
- data: flashcardsServerData(),
- learningSession: activeLearningSession(),
- folders: folders(),
+ data: await flashcardsServerData(),
+ learningSession: await activeLearningSession(),
+ folders: await folders(),
}
-}
+}, 'index')
+
+const splitEvenly = action(async () => {
+ 'use server'
+ const email = await requireUserEmail()
+ const flashcards = await db.flashcard.findMany({
+ where: { nextStudy: { lt: new Date(daysFromNow(0)) } },
+ })
+ await Promise.all(
+ chunk(flashcards, Math.ceil(flashcards.length / 30)).map(
+ (flashcard, index) => {
+ return db.flashcard.updateMany({
+ where: {
+ id: { in: flashcard.map((f) => f.id) },
+ ownerEmail: email,
+ },
+ data: { nextStudy: new Date(daysFromNow(index)) },
+ })
+ }
+ )
+ )
+}, 'splitEvenly')
+
+const createLearningSessionAction = action(async (formData: FormData) => {
+ 'use server'
+ console.log('request')
+ const email = await requireUserEmail()
+ console.log(email)
+ const schema = z.object({
+ day: z.string(),
+ folders: z.string(),
+ })
+ const { day, folders } = schema.parse(Object.fromEntries(formData.entries()))
+ console.log(day, folders)
+
+ const dayNumber = parseInt(day)
+ z.number().parse(dayNumber)
+ console.log(email, dayNumber, folders)
+ await createLearningSession(
+ email,
+ dayNumber,
+ folders === '' ? undefined : folders.split(',')
+ )
+ return redirect('/learning-session')
+}, 'createLearningSession')
const weekDayNames = [
'Monday',
@@ -121,11 +167,11 @@ const getAllSubfolders = (folder: Folder): Folder[] => {
)
}
export default function Calendar() {
- const data = useRouteData()
+ const data = createAsync(() => routeData(), { deferStream: true })
const [selectedFolders, setFolders] = useFolders()
const flashcards = createMemo(() => {
if (data === undefined) return []
- return data.data()?.flashcards.filter((flashcard) => {
+ return data()?.data.flashcards.filter((flashcard) => {
return selectedFolders().length > 0
? selectedFolders().includes(flashcard.folder.id)
: true
@@ -163,53 +209,12 @@ export default function Calendar() {
)
})
- const [splittingEvenly, { Form }] = createServerAction$(
- async (_: FormData, { request }) => {
- const email = await requireUserEmail(request)
- const flashcards = await db.flashcard.findMany({
- where: { nextStudy: { lt: new Date(daysFromNow(0)) } },
- })
- await Promise.all(
- chunk(flashcards, Math.ceil(flashcards.length / 30)).map(
- (flashcard, index) => {
- return db.flashcard.updateMany({
- where: {
- id: { in: flashcard.map((f) => f.id) },
- ownerEmail: email,
- },
- data: { nextStudy: new Date(daysFromNow(index)) },
- })
- }
- )
- )
- }
- )
-
- const [creatingLearningSession, { Form: CreateLearningSessionForm }] =
- createServerAction$(async (formData: FormData, { request }) => {
- const email = await requireUserEmail(request)
- const schema = z.object({
- day: z.string(),
- folders: z.string(),
- })
- const { day, folders } = schema.parse(
- Object.fromEntries(formData.entries())
- )
-
- const dayNumber = parseInt(day)
- z.number().parse(dayNumber)
- await createLearningSession(
- email,
- dayNumber,
- folders === '' ? undefined : folders.split(',')
- )
- return redirect('/learning-session')
- })
-
+ const splittingEvenly = useSubmission(splitEvenly)
+ const creatingLearningSession = useSubmission(createLearningSessionAction)
const handleSelect = createMemo(() => (id: string) => {
const flatFolders = [
- ...(data.folders() ?? []),
- ...(data.folders()?.flatMap((folder) => getAllSubfolders(folder)) ?? []),
+ ...(data()?.folders ?? []),
+ ...(data()?.folders?.flatMap((folder) => getAllSubfolders(folder)) ?? []),
]
const newSelectedFolder = flatFolders.find((folder) => folder.id === id)
const subfolders = newSelectedFolder
@@ -237,7 +242,7 @@ export default function Calendar() {
Folders
- {data.folders()?.map((folder) => {
+ {data()?.folders?.map((folder) => {
return (
{splittingEvenly.pending &&
Splitting evenly...
}
- {splittingEvenly.error &&
{splittingEvenly.error.message}
}
+ {/*{splittingEvenly.error &&
{splittingEvenly.error.message}
}*/}
{creatingLearningSession.pending && (
Creating learning session...
)}
- {creatingLearningSession.error && (
-
{creatingLearningSession.error.message}
- )}
-
+ {/*{creatingLearningSession.error && (*/}
+ {/* {creatingLearningSession.error.message}
*/}
+ {/*)}*/}
+
- {data.learningSession()?._count.completedFlashcards}/
- {(data.learningSession()?._count.completedFlashcards ?? 0) +
- (data.learningSession()?._count.uncompletedFlashcards ?? 0)}{' '}
- learned in last session
Continue
+ {data()?.learningSession?._count.completedFlashcards}/
+ {(data()?.learningSession?._count.completedFlashcards ?? 0) +
+ (data()?.learningSession?._count.uncompletedFlashcards ?? 0)}{' '}
+ learned in last session
Continue
-
-
+
-
+
{Array(27 - normalizedCurrentWeekDay)
.fill(undefined)
@@ -305,7 +310,7 @@ export default function Calendar() {
const todayFlashcards = flashcardsByNextStudy()[isoDate] ?? []
return (
-
+
-
+
)
})}
@@ -349,7 +354,7 @@ export default function Calendar() {
)
})}
-
+