generated from alphane/template
Adding in flashcard's and decks
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import http from "@/api/http-client"
|
||||
import { type FiltersOptions, type ModelOrder, type Policy, type WhereOptions } from "@/api/base-api"
|
||||
|
||||
export type FlashcardDeck = {
|
||||
id: number
|
||||
parentDeckId: number | null
|
||||
creatorId: number
|
||||
name: string
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
export type FlashcardDeckWhereOptions = WhereOptions<FlashcardDeck, "creatorId" | "parentDeckId">
|
||||
|
||||
export type FlashcardDeckFiltersOptions = FiltersOptions<{
|
||||
search: string | string[]
|
||||
}>
|
||||
|
||||
export type FlashcardDeckQueryOptions = {
|
||||
where?: FlashcardDeckWhereOptions
|
||||
filters?: FlashcardDeckFiltersOptions
|
||||
order?: ModelOrder[]
|
||||
page?: number
|
||||
perPage?: number
|
||||
}
|
||||
|
||||
export const flashcardDecksApi = {
|
||||
async list(params: FlashcardDeckQueryOptions = {}): Promise<{
|
||||
flashcardDecks: FlashcardDeck[]
|
||||
totalCount: number
|
||||
}> {
|
||||
const { data } = await http.get("/api/flashcard-decks", { params })
|
||||
return data
|
||||
},
|
||||
async get(flashcardDeckId: number): Promise<{
|
||||
flashcardDeck: FlashcardDeck
|
||||
policy: Policy
|
||||
}> {
|
||||
const { data } = await http.get(`/api/flashcard-decks/${flashcardDeckId}`)
|
||||
return data
|
||||
},
|
||||
async create(attributes: Partial<FlashcardDeck>): Promise<{
|
||||
flashcardDeck: FlashcardDeck
|
||||
}> {
|
||||
const { data } = await http.post("/api/flashcard-decks", attributes)
|
||||
return data
|
||||
},
|
||||
async update(
|
||||
flashcardDeckId: number,
|
||||
attributes: Partial<FlashcardDeck>
|
||||
): Promise<{
|
||||
flashcardDeck: FlashcardDeck
|
||||
}> {
|
||||
const { data } = await http.patch(`/api/flashcard-decks/${flashcardDeckId}`, attributes)
|
||||
return data
|
||||
},
|
||||
async delete(flashcardDeckId: number): Promise<void> {
|
||||
const { data } = await http.delete(`/api/flashcard-decks/${flashcardDeckId}`)
|
||||
return data
|
||||
},
|
||||
}
|
||||
|
||||
export default flashcardDecksApi
|
||||
@@ -0,0 +1,65 @@
|
||||
import http from "@/api/http-client"
|
||||
import { type FiltersOptions, type ModelOrder, type Policy, type WhereOptions } from "@/api/base-api"
|
||||
|
||||
export type Flashcard = {
|
||||
id: number
|
||||
flashcardDeckId: number
|
||||
creatorId: number
|
||||
cardType: string
|
||||
front: string
|
||||
back: string | null
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
export type FlashcardWhereOptions = WhereOptions<Flashcard, "flashcardDeckId" | "creatorId" | "cardType">
|
||||
|
||||
export type FlashcardFiltersOptions = FiltersOptions<{
|
||||
search: string | string[]
|
||||
}>
|
||||
|
||||
export type FlashcardQueryOptions = {
|
||||
where?: FlashcardWhereOptions
|
||||
filters?: FlashcardFiltersOptions
|
||||
order?: ModelOrder[]
|
||||
page?: number
|
||||
perPage?: number
|
||||
}
|
||||
|
||||
export const flashcardsApi = {
|
||||
async list(params: FlashcardQueryOptions = {}): Promise<{
|
||||
flashcards: Flashcard[]
|
||||
totalCount: number
|
||||
}> {
|
||||
const { data } = await http.get("/api/flashcards", { params })
|
||||
return data
|
||||
},
|
||||
async get(flashcardId: number): Promise<{
|
||||
flashcard: Flashcard
|
||||
policy: Policy
|
||||
}> {
|
||||
const { data } = await http.get(`/api/flashcards/${flashcardId}`)
|
||||
return data
|
||||
},
|
||||
async create(attributes: Partial<Flashcard>): Promise<{
|
||||
flashcard: Flashcard
|
||||
}> {
|
||||
const { data } = await http.post("/api/flashcards", attributes)
|
||||
return data
|
||||
},
|
||||
async update(
|
||||
flashcardId: number,
|
||||
attributes: Partial<Flashcard>
|
||||
): Promise<{
|
||||
flashcard: Flashcard
|
||||
}> {
|
||||
const { data } = await http.patch(`/api/flashcards/${flashcardId}`, attributes)
|
||||
return data
|
||||
},
|
||||
async delete(flashcardId: number): Promise<void> {
|
||||
const { data } = await http.delete(`/api/flashcards/${flashcardId}`)
|
||||
return data
|
||||
},
|
||||
}
|
||||
|
||||
export default flashcardsApi
|
||||
@@ -0,0 +1,87 @@
|
||||
import { type Ref, reactive, toRefs, unref, watch } from "vue"
|
||||
import { isNil } from "lodash"
|
||||
|
||||
import { type Policy } from "@/api/base-api"
|
||||
import flashcardDecksApi, { type FlashcardDeck } from "@/api/flashcard-decks-api"
|
||||
|
||||
export { type FlashcardDeck }
|
||||
|
||||
export function useFlashcardDeck(id: Ref<number | null | undefined>) {
|
||||
const state = reactive<{
|
||||
flashcardDeck: FlashcardDeck | null
|
||||
policy: Policy | null
|
||||
isLoading: boolean
|
||||
isErrored: boolean
|
||||
}>({
|
||||
flashcardDeck: null,
|
||||
policy: null,
|
||||
isLoading: false,
|
||||
isErrored: false,
|
||||
})
|
||||
|
||||
async function fetch(): Promise<FlashcardDeck> {
|
||||
const staticId = unref(id)
|
||||
if (isNil(staticId)) {
|
||||
throw new Error("id is required")
|
||||
}
|
||||
|
||||
state.isLoading = true
|
||||
try {
|
||||
const { flashcardDeck, policy } = await flashcardDecksApi.get(staticId)
|
||||
state.isErrored = false
|
||||
state.flashcardDeck = flashcardDeck
|
||||
state.policy = policy
|
||||
return flashcardDeck
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch flashcard deck:", error)
|
||||
state.isErrored = true
|
||||
throw error
|
||||
} finally {
|
||||
state.isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
async function save(): Promise<FlashcardDeck> {
|
||||
const staticId = unref(id)
|
||||
if (isNil(staticId)) {
|
||||
throw new Error("id is required")
|
||||
}
|
||||
|
||||
if (isNil(state.flashcardDeck)) {
|
||||
throw new Error("No flashcard deck to save")
|
||||
}
|
||||
|
||||
state.isLoading = true
|
||||
try {
|
||||
const { flashcardDeck } = await flashcardDecksApi.update(staticId, state.flashcardDeck)
|
||||
state.isErrored = false
|
||||
state.flashcardDeck = flashcardDeck
|
||||
return flashcardDeck
|
||||
} catch (error) {
|
||||
console.error("Failed to save flashcard deck:", error)
|
||||
state.isErrored = true
|
||||
throw error
|
||||
} finally {
|
||||
state.isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => unref(id),
|
||||
async (newId) => {
|
||||
if (isNil(newId)) return
|
||||
|
||||
await fetch()
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
fetch,
|
||||
refresh: fetch,
|
||||
save,
|
||||
}
|
||||
}
|
||||
|
||||
export default useFlashcardDeck
|
||||
@@ -0,0 +1,67 @@
|
||||
import { type Ref, reactive, toRefs, ref, unref, watch } from "vue"
|
||||
|
||||
import flashcardDecksApi, {
|
||||
type FlashcardDeck,
|
||||
type FlashcardDeckWhereOptions,
|
||||
type FlashcardDeckFiltersOptions,
|
||||
type FlashcardDeckQueryOptions,
|
||||
} from "@/api/flashcard-decks-api"
|
||||
|
||||
export {
|
||||
type FlashcardDeck,
|
||||
type FlashcardDeckWhereOptions,
|
||||
type FlashcardDeckFiltersOptions,
|
||||
type FlashcardDeckQueryOptions,
|
||||
}
|
||||
|
||||
export function useFlashcardDecks(
|
||||
queryOptions: Ref<FlashcardDeckQueryOptions> = ref({}),
|
||||
{ skipWatchIf = () => false }: { skipWatchIf?: () => boolean } = {}
|
||||
) {
|
||||
const state = reactive<{
|
||||
flashcardDecks: FlashcardDeck[]
|
||||
totalCount: number
|
||||
isLoading: boolean
|
||||
isErrored: boolean
|
||||
}>({
|
||||
flashcardDecks: [],
|
||||
totalCount: 0,
|
||||
isLoading: false,
|
||||
isErrored: false,
|
||||
})
|
||||
|
||||
async function fetch(): Promise<FlashcardDeck[]> {
|
||||
state.isLoading = true
|
||||
try {
|
||||
const { flashcardDecks, totalCount } = await flashcardDecksApi.list(unref(queryOptions))
|
||||
state.isErrored = false
|
||||
state.flashcardDecks = flashcardDecks
|
||||
state.totalCount = totalCount
|
||||
return flashcardDecks
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch flashcard decks:", error)
|
||||
state.isErrored = true
|
||||
throw error
|
||||
} finally {
|
||||
state.isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [skipWatchIf(), unref(queryOptions)],
|
||||
async ([skip]) => {
|
||||
if (skip) return
|
||||
|
||||
await fetch()
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
fetch,
|
||||
refresh: fetch,
|
||||
}
|
||||
}
|
||||
|
||||
export default useFlashcardDecks
|
||||
@@ -0,0 +1,87 @@
|
||||
import { type Ref, reactive, toRefs, unref, watch } from "vue"
|
||||
import { isNil } from "lodash"
|
||||
|
||||
import { type Policy } from "@/api/base-api"
|
||||
import flashcardsApi, { type Flashcard } from "@/api/flashcards-api"
|
||||
|
||||
export { type Flashcard }
|
||||
|
||||
export function useFlashcard(id: Ref<number | null | undefined>) {
|
||||
const state = reactive<{
|
||||
flashcard: Flashcard | null
|
||||
policy: Policy | null
|
||||
isLoading: boolean
|
||||
isErrored: boolean
|
||||
}>({
|
||||
flashcard: null,
|
||||
policy: null,
|
||||
isLoading: false,
|
||||
isErrored: false,
|
||||
})
|
||||
|
||||
async function fetch(): Promise<Flashcard> {
|
||||
const staticId = unref(id)
|
||||
if (isNil(staticId)) {
|
||||
throw new Error("id is required")
|
||||
}
|
||||
|
||||
state.isLoading = true
|
||||
try {
|
||||
const { flashcard, policy } = await flashcardsApi.get(staticId)
|
||||
state.isErrored = false
|
||||
state.flashcard = flashcard
|
||||
state.policy = policy
|
||||
return flashcard
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch flashcard:", error)
|
||||
state.isErrored = true
|
||||
throw error
|
||||
} finally {
|
||||
state.isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
async function save(): Promise<Flashcard> {
|
||||
const staticId = unref(id)
|
||||
if (isNil(staticId)) {
|
||||
throw new Error("id is required")
|
||||
}
|
||||
|
||||
if (isNil(state.flashcard)) {
|
||||
throw new Error("No flashcard to save")
|
||||
}
|
||||
|
||||
state.isLoading = true
|
||||
try {
|
||||
const { flashcard } = await flashcardsApi.update(staticId, state.flashcard)
|
||||
state.isErrored = false
|
||||
state.flashcard = flashcard
|
||||
return flashcard
|
||||
} catch (error) {
|
||||
console.error("Failed to save flashcard:", error)
|
||||
state.isErrored = true
|
||||
throw error
|
||||
} finally {
|
||||
state.isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => unref(id),
|
||||
async (newId) => {
|
||||
if (isNil(newId)) return
|
||||
|
||||
await fetch()
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
fetch,
|
||||
refresh: fetch,
|
||||
save,
|
||||
}
|
||||
}
|
||||
|
||||
export default useFlashcard
|
||||
@@ -0,0 +1,67 @@
|
||||
import { type Ref, reactive, toRefs, ref, unref, watch } from "vue"
|
||||
|
||||
import flashcardsApi, {
|
||||
type Flashcard,
|
||||
type FlashcardWhereOptions,
|
||||
type FlashcardFiltersOptions,
|
||||
type FlashcardQueryOptions,
|
||||
} from "@/api/flashcards-api"
|
||||
|
||||
export {
|
||||
type Flashcard,
|
||||
type FlashcardWhereOptions,
|
||||
type FlashcardFiltersOptions,
|
||||
type FlashcardQueryOptions,
|
||||
}
|
||||
|
||||
export function useFlashcards(
|
||||
queryOptions: Ref<FlashcardQueryOptions> = ref({}),
|
||||
{ skipWatchIf = () => false }: { skipWatchIf?: () => boolean } = {}
|
||||
) {
|
||||
const state = reactive<{
|
||||
flashcards: Flashcard[]
|
||||
totalCount: number
|
||||
isLoading: boolean
|
||||
isErrored: boolean
|
||||
}>({
|
||||
flashcards: [],
|
||||
totalCount: 0,
|
||||
isLoading: false,
|
||||
isErrored: false,
|
||||
})
|
||||
|
||||
async function fetch(): Promise<Flashcard[]> {
|
||||
state.isLoading = true
|
||||
try {
|
||||
const { flashcards, totalCount } = await flashcardsApi.list(unref(queryOptions))
|
||||
state.isErrored = false
|
||||
state.flashcards = flashcards
|
||||
state.totalCount = totalCount
|
||||
return flashcards
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch flashcards:", error)
|
||||
state.isErrored = true
|
||||
throw error
|
||||
} finally {
|
||||
state.isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [skipWatchIf(), unref(queryOptions)],
|
||||
async ([skip]) => {
|
||||
if (skip) return
|
||||
|
||||
await fetch()
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
fetch,
|
||||
refresh: fetch,
|
||||
}
|
||||
}
|
||||
|
||||
export default useFlashcards
|
||||
Reference in New Issue
Block a user