diff --git a/.env.example b/.env.example index c61cc7529..854aae654 100644 --- a/.env.example +++ b/.env.example @@ -5,3 +5,5 @@ VITE_APP_INCLUDE_DEMOS= VITE_APP_ROUTER_MODE_HISTORY= VITE_APP_BUILD_VERSION= + +VITE_API_BASE_URL= diff --git a/.gitignore b/.gitignore index c3bb0dbc3..f9d0c5bb8 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ node_modules dist dist-ssr *.local +.env # Editor directories and files .vscode/* @@ -25,3 +26,4 @@ dist-ssr # Local Netlify folder .netlify + diff --git a/package.json b/package.json index 82226f019..e5c57494f 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "register-service-worker": "^1.7.1", "sass": "^1.69.5", "serve": "^14.2.1", + "uuid": "^11.0.3", "vue": "3.5.8", "vue-chartjs": "^5.3.0", "vue-i18n": "^9.6.2", diff --git a/src/data/pages/projects.ts b/src/data/pages/projects.ts index 87f1b98f2..8d75390d6 100644 --- a/src/data/pages/projects.ts +++ b/src/data/pages/projects.ts @@ -1,8 +1,6 @@ -import { sleep } from '../../services/utils' -import projectsDb from './projects-db.json' -import usersDb from './users-db.json' +import api from '../../services/api' +import { Project } from '../../pages/projects/types' -// Simulate API calls export type Pagination = { page: number perPage: number @@ -10,93 +8,36 @@ export type Pagination = { } export type Sorting = { - sortBy: keyof (typeof projectsDb)[number] | undefined + sortBy: 'project_owner' | 'team' | 'created_at' sortingOrder: 'asc' | 'desc' | null } -const getSortItem = (obj: any, sortBy: keyof (typeof projectsDb)[number]) => { - if (sortBy === 'project_owner') { - return obj.project_owner.fullname - } - - if (sortBy === 'team') { - return obj.team.map((user: any) => user.fullname).join(', ') - } - - if (sortBy === 'creation_date') { - return new Date(obj[sortBy]) - } - - return obj[sortBy] -} - -export const getProjects = async (options: Sorting & Pagination) => { - await sleep(1000) - - const projects = projectsDb.map((project) => ({ - ...project, - project_owner: usersDb.find((user) => user.id === project.project_owner)! as (typeof usersDb)[number], - team: usersDb.filter((user) => project.team.includes(user.id)) as (typeof usersDb)[number][], - })) - - if (options.sortBy && options.sortingOrder) { - projects.sort((a, b) => { - a = getSortItem(a, options.sortBy!) - b = getSortItem(b, options.sortBy!) - if (a < b) { - return options.sortingOrder === 'asc' ? -1 : 1 - } - if (a > b) { - return options.sortingOrder === 'asc' ? 1 : -1 - } - return 0 - }) - } - - const normalizedProjects = projects.slice((options.page - 1) * options.perPage, options.page * options.perPage) +export const getProjects = async (options: Partial & Pagination) => { + const projects: Project[] = await fetch(api.allProjects()).then((r) => r.json()) return { - data: normalizedProjects, + data: projects, pagination: { page: options.page, perPage: options.perPage, - total: projectsDb.length, + total: projects.length, }, } } -export const addProject = async (project: Omit<(typeof projectsDb)[number], 'id' | 'creation_date'>) => { - await sleep(1000) - - const newProject = { - ...project, - id: projectsDb.length + 1, - creation_date: new Date().toLocaleDateString('gb', { day: 'numeric', month: 'short', year: 'numeric' }), - } +export const addProject = async (project: Omit) => { + const headers = new Headers() + headers.append('Content-Type', 'application/json') - projectsDb.push(newProject) - - return { - ...newProject, - project_owner: usersDb.find((user) => user.id === project.project_owner)! as (typeof usersDb)[number], - team: usersDb.filter((user) => project.team.includes(user.id)) as (typeof usersDb)[number][], - } + return fetch(api.allProjects(), { method: 'POST', body: JSON.stringify(project), headers }).then((r) => r.json()) } -export const updateProject = async (project: (typeof projectsDb)[number]) => { - await sleep(1000) - - const index = projectsDb.findIndex((p) => p.id === project.id) - projectsDb[index] = project - - return project +export const updateProject = async (project: Omit) => { + const headers = new Headers() + headers.append('Content-Type', 'application/json') + return fetch(api.project(project.id), { method: 'PUT', body: JSON.stringify(project), headers }).then((r) => r.json()) } -export const removeProject = async (project: (typeof projectsDb)[number]) => { - await sleep(1000) - - const index = projectsDb.findIndex((p) => p.id === project.id) - projectsDb.splice(index, 1) - - return project +export const removeProject = async (project: Project) => { + return fetch(api.project(project.id), { method: 'DELETE' }) } diff --git a/src/data/pages/users.ts b/src/data/pages/users.ts index 80285863f..0ef6b701c 100644 --- a/src/data/pages/users.ts +++ b/src/data/pages/users.ts @@ -1,23 +1,5 @@ -import { sleep } from '../../services/utils' -import { User } from './../../pages/users/types' -import usersDb from './users-db.json' -import projectsDb from './projects-db.json' -import { Project } from '../../pages/projects/types' - -export const users = usersDb as User[] - -const getUserProjects = (userId: number | string) => { - return projectsDb - .filter((project) => project.team.includes(Number(userId))) - .map((project) => ({ - ...project, - project_owner: users.find((user) => user.id === project.project_owner)!, - team: project.team.map((userId) => users.find((user) => user.id === userId)!), - status: project.status as Project['status'], - })) -} - -// Simulate API calls +import { User } from '../../pages/users/types' +import api from '../../services/api' export type Pagination = { page: number @@ -35,18 +17,9 @@ export type Filters = { search: string } -const getSortItem = (obj: any, sortBy: string) => { - if (sortBy === 'projects') { - return obj.projects.map((project: any) => project.project_name).join(', ') - } - - return obj[sortBy] -} - export const getUsers = async (filters: Partial) => { - await sleep(1000) - const { isActive, search, sortBy, sortingOrder } = filters - let filteredUsers = users + const { isActive, search } = filters + let filteredUsers: User[] = await fetch(api.allUsers()).then((r) => r.json()) filteredUsers = filteredUsers.filter((user) => user.active === isActive) @@ -54,25 +27,9 @@ export const getUsers = async (filters: Partial) filteredUsers = filteredUsers.filter((user) => user.fullname.toLowerCase().includes(search.toLowerCase())) } - filteredUsers = filteredUsers.map((user) => ({ ...user, projects: getUserProjects(user.id) })) - - if (sortBy && sortingOrder) { - filteredUsers = filteredUsers.sort((a, b) => { - const first = getSortItem(a, sortBy) - const second = getSortItem(b, sortBy) - if (first > second) { - return sortingOrder === 'asc' ? 1 : -1 - } - if (first < second) { - return sortingOrder === 'asc' ? -1 : 1 - } - return 0 - }) - } - const { page = 1, perPage = 10 } = filters || {} return { - data: filteredUsers.slice((page - 1) * perPage, page * perPage), + data: filteredUsers, pagination: { page, perPage, @@ -82,20 +39,39 @@ export const getUsers = async (filters: Partial) } export const addUser = async (user: User) => { - await sleep(1000) - users.unshift(user) + const headers = new Headers() + headers.append('Content-Type', 'application/json') + + const result = await fetch(api.allUsers(), { method: 'POST', body: JSON.stringify(user), headers }).then((r) => + r.json(), + ) + + if (!result.error) { + return result + } + + throw new Error(result.error) } export const updateUser = async (user: User) => { - await sleep(1000) - const index = users.findIndex((u) => u.id === user.id) - users[index] = user + const headers = new Headers() + headers.append('Content-Type', 'application/json') + + const result = await fetch(api.user(user.id), { method: 'PUT', body: JSON.stringify(user), headers }).then((r) => + r.json(), + ) + + if (!result.error) { + return result + } + + throw new Error(result.error) } export const removeUser = async (user: User) => { - await sleep(1000) - users.splice( - users.findIndex((u) => u.id === user.id), - 1, - ) + return fetch(api.user(user.id), { method: 'DELETE' }) +} + +export const uploadAvatar = async (body: FormData) => { + return fetch(api.avatars(), { method: 'POST', body, redirect: 'follow' }).then((r) => r.json()) } diff --git a/src/pages/admin/dashboard/cards/ProjectTable.vue b/src/pages/admin/dashboard/cards/ProjectTable.vue index b29f2a137..5296b4fa5 100644 --- a/src/pages/admin/dashboard/cards/ProjectTable.vue +++ b/src/pages/admin/dashboard/cards/ProjectTable.vue @@ -1,11 +1,11 @@