This commit is contained in:
2024-09-02 16:58:23 +02:00
parent c77503ed45
commit 1b0dc0f27d
52 changed files with 817 additions and 1379 deletions

View File

@@ -4,42 +4,49 @@ export async function useCategories() {
const { data: categories, refresh }
= await useAsyncData<CategoryType[]>(async () => await useRequestFetch()('/api/categories'))
async function getCategory(id: number): CategoryType {
return categories.data.value.find(category => category.id === id)
}
async function createCategory(category: CreateCategorySchema) {
await $fetch('/api/categories', {
method: 'POST',
body: JSON.stringify(category),
})
.catch(error => useErrorToast('Category creation failed!', `Error: ${error}`))
await refresh()
await useSuccessToast('Category successfully created!')
try {
await useRequestFetch()('/api/categories', {
method: 'POST',
body: JSON.stringify(category),
})
await refresh()
await useSuccessToast('Category successfully created!', category.color)
}
catch (error) {
useErrorToast('Category creation failed!', error as string)
}
}
async function updateCategory(category: UpdateCategorySchema & { id: number }) {
await $fetch(`/api/categories/${category.id}`, {
method: 'PUT',
body: JSON.stringify(category),
})
.catch(error => useErrorToast('Category update failed!', `Error: ${error}`))
await refresh()
await useSuccessToast('Category successfully updated!')
try {
await $fetch(`/api/categories/${category.id}`, {
method: 'PUT',
body: JSON.stringify(category),
})
await refresh()
await useSuccessToast('Category successfully updated!')
}
catch (error) {
useErrorToast('Category update failed!', error as string)
}
}
async function deleteCategory(id: number) {
await $fetch(`/api/categories/${id}`, {
method: 'DELETE',
})
.catch(error => useErrorToast('Category deletion failed!', `Error: ${error}`))
await refresh()
await useSuccessToast('Category successfully deleted!')
try {
await $fetch(`/api/categories/${id}`, {
method: 'DELETE',
})
await refresh()
await useSuccessToast('Category successfully deleted!')
}
catch (error) {
useErrorToast('Category deletion failed!', error as string)
}
}
return {
categories,
getCategory,
createCategory,
updateCategory,
deleteCategory,

View File

@@ -9,51 +9,61 @@ export async function useTabs() {
}
async function createTab(tab: CreateTabSchema) {
await $fetch('/api/tabs', {
method: 'POST',
body: JSON.stringify(tab),
})
.then(async () => {
await refresh()
useSuccessToast('Tab successfully created!')
try {
await $fetch('/api/tabs', {
method: 'POST',
body: JSON.stringify(tab),
})
.catch(error => useErrorToast('Tab creation failed!', `Error: ${error}`))
await refresh()
useSuccessToast('Tab successfully created!', tab.color)
}
catch (error) {
useErrorToast('Tab creation failed!', error as string)
}
}
async function updateTab(tab: UpdateTabSchema) {
await $fetch(`/api/tabs/${tab.id}`, {
method: 'PUT',
body: JSON.stringify(tab),
})
.then(async () => {
await refresh()
useSuccessToast('Tab successfully updated!')
try {
await $fetch(`/api/tabs/${tab.id}`, {
method: 'PUT',
body: JSON.stringify(tab),
})
.catch(error => useErrorToast('Tab update failed!', `Error: ${error}`))
await refresh()
useSuccessToast('Tab successfully updated!')
}
catch (error) {
useErrorToast('Tab update failed!', error as string)
}
}
async function setTabPrimary(tab, primary: boolean) {
await $fetch(`/api/tabs/${tab.id}`, {
method: 'PUT',
body: JSON.stringify({
primary,
categoryId: tab.categoryId,
}),
})
.then(async () => {
await refresh()
useSuccessToast('Tab favorite toggled with success!')
try {
await $fetch(`/api/tabs/${tab.id}`, {
method: 'PUT',
body: JSON.stringify({
primary,
categoryId: tab.categoryId,
}),
})
.catch(error => useErrorToast('Cannot toggle Tab favorite!', `Error: ${error}`))
await refresh()
useSuccessToast(`Tab ${tab.name} ${primary ? 'set as favorite' : 'unset as favorite'}!`, 'yellow')
}
catch (error) {
useErrorToast('Cannot toggle favorite state for tab!', error as string)
}
}
async function deleteTab(id: number) {
await $fetch(`/api/tabs/${id}`, {
method: 'DELETE',
})
.catch(error => useErrorToast('Tab deletion failed!', `Error: ${error}`))
await refresh()
useSuccessToast('Tab successfully deleted!')
try {
await $fetch(`/api/tabs/${id}`, {
method: 'DELETE',
})
await refresh()
useSuccessToast('Tab successfully deleted!')
}
catch (error) {
useErrorToast('Tab deletion failed!', error as string)
}
}
return {

View File

@@ -1,10 +1,10 @@
export function useSuccessToast(title: string, description?: string) {
export function useSuccessToast(title: string, color?: string, description?: string) {
const toast = useToast()
toast.add({
title,
description,
color: 'green',
color: color || 'green',
icon: 'i-ph:check-circle-duotone',
})
}

View File

@@ -1,26 +0,0 @@
export async function useUserLimit() {
const { user } = useUserSession()
const { categories } = await useCategories()
const { tabs } = await useTabs()
const hasPaidPlan = computed(() => user.value.subscription !== 'free')
function canCreateCategory() {
if (hasPaidPlan.value)
return true
return categories.value.length < 3
}
function canCreateTabInCategory(categoryId: number): boolean {
if (hasPaidPlan.value)
return true
return tabs.filter(tab => tab.categoryId === categoryId).length < 5
}
return {
hasPaidPlan,
userLimits,
canCreateCategory,
canCreateTabInCategory,
}
}

View File

@@ -0,0 +1,28 @@
const MAX_CATEGORIES = 3
const MAX_TABS_PER_CATEGORY = 6
export async function useUserLimits() {
const { user } = useUserSession()
const { data: userLimits, refresh: refreshUserLimits } = await useFetch('/api/users/limits')
const hasPaidPlan = computed(() => user.value.subscription !== 'free')
function canCreateCategory() {
if (hasPaidPlan.value)
return true
return userLimits.value.categories.length < MAX_CATEGORIES
}
function canCreateTabInCategory(categoryId: number): boolean {
if (hasPaidPlan.value)
return true
return userLimits.value.categories.find(category => category.id === categoryId).tabs.length < MAX_TABS_PER_CATEGORY
}
return {
hasPaidPlan,
canCreateCategory,
canCreateTabInCategory,
refreshUserLimits,
}
}

43
app/composables/users.ts Normal file
View File

@@ -0,0 +1,43 @@
export async function useUser() {
const { fetch } = useUserSession()
async function deleteAvatar() {
try {
await useRequestFetch()('/api/users/avatars', {
method: 'DELETE',
})
useSuccessToast('Avatar successfully deleted!')
await fetch()
}
catch (error) {
useErrorToast('An error occurred while deleting your avatar', error as string)
}
}
async function uploadAvatar(event: Event) {
const file = event[0] as File
if (!file)
return
const formData = new FormData()
formData.append('file', file)
try {
await useRequestFetch()('/api/users/avatars', {
method: 'POST',
body: formData,
})
await fetch()
useSuccessToast('Avatar successfully uploaded!')
}
catch (error) {
useErrorToast('An error occurred while uploading your avatar', error as string)
}
}
return {
deleteAvatar,
uploadAvatar,
}
}