An open API service indexing awesome lists of open source software.

https://github.com/chucho-kun/client-uptask-node-typescript-

CLIENT - UpTask in React - Typescript - TailwindCSS
https://github.com/chucho-kun/client-uptask-node-typescript-

jsonwebtoken login-system mongodb-atlas platform-engineering react server task-manager typescript

Last synced: 9 months ago
JSON representation

CLIENT - UpTask in React - Typescript - TailwindCSS

Awesome Lists containing this project

README

          

# FRONT MERN - REST API REACT/TypeScript
React Web Platform connected to an API hosted on a MongoDB + Express + React + Node ( MERN )
## 🚀 Tech Stack MERN
![MongoDB](https://img.shields.io/badge/MongoDB-47A248?style=for-the-badge&logo=mongodb&logoColor=white)
![Express](https://img.shields.io/badge/Express.js-000000?style=for-the-badge&logo=express&logoColor=white)
![React](https://img.shields.io/badge/React-61DAFB?style=for-the-badge&logo=react&logoColor=black)
![Node.js](https://img.shields.io/badge/Node.js-339933?style=for-the-badge&logo=node.js&logoColor=white)

![Gameplay A](src/assets/shotA.png)
![Gameplay B](src/assets/shotB.png)
![Gameplay C](src/assets/shotC.png)
![Gameplay 1](src/assets/shot1.png)
![Gameplay 2](src/assets/shot2.png)
![Gameplay 3](src/assets/shot3.png)

## Technologies
React + Typescript + TailwindCSS + Axios + Zod + React Router + React Query
## Developer Notes
## Deploy on Vercel
Website hosted on vercel.com server
https://client-uptask-node-typescript.vercel.app/
### Managed with Axios
#### src/lib/axios.ts
```
import axios from "axios"

const api = axios.create({
baseURL: import.meta.env.VITE_API_URL
});

api.interceptors.request.use( config => {
const token = localStorage.getItem('AUTH_TOKEN')
if(token){
config.headers.Authorization = `Bearer ${token}`
}
return config
})
export default api
```
#### src/api/ProjectAPI.ts
```
import api from "@/lib/axios";
import { dashboardProjectSchema, editProjectSchema, projectSchema, type Project, type ProjectFormData } from "../types";
import { isAxiosError } from "axios";

export async function createProject( formData : ProjectFormData ) {

try {
const { data } = await api.post( '/projects' , formData )
return data
} catch (error) {
if( isAxiosError(error) && error.response ){
throw new Error(error.response.data.error)
}

}

}

export async function getProjects() {

try {
const { data } = await api('/projects')
const response = dashboardProjectSchema.safeParse(data)

if(response.success) return response.data
//return []; // O retorna un array vacío para evitar undefined
} catch (error) {
if( isAxiosError(error) && error.response){
throw new Error( error.response.data.error )
}
return [];
}
}

export async function getProjectsById( id : Project['_id'] ) {
try {
const { data } = await api(`/projects/${ id }`)
const response = editProjectSchema.safeParse(data)
if(response.success){
return response.data
}
} catch (error) {
if( isAxiosError(error) && error.response){
throw new Error( error.response.data.error )
}
}
}

export async function getFullProject( id : Project['_id'] ) {
try {
const { data } = await api(`/projects/${ id }`)
const response = projectSchema.safeParse(data)
if(response.success){
return response.data
}
} catch (error) {
if( isAxiosError(error) && error.response){
throw new Error( error.response.data.error )
}
}
}

type ProjectAPIType = {
formData: ProjectFormData
projectId: Project['_id']
}

export async function updateProject({ formData , projectId } : ProjectAPIType) {
try {
const { data } = await api.put(`/projects/${ projectId }` , formData)
return data
} catch (error) {
if( isAxiosError(error) && error.response){
throw new Error( error.response.data.error )
}
}
}

export async function deleteProject( id : Project['_id'] ) {
try {
const { data } = await api.delete(`/projects/${ id }`)
return data
} catch (error) {
if( isAxiosError(error) && error.response){
throw new Error( error.response.data.error )
}
}
}
```
#### src/types/index.ts
```
import { z } from "zod"

/** Auth & Users */

const authSchema = z.object({
name: z.string(),
email: z.email(),
current_password: z.string(),
password: z.string(),
password_confirmation: z.string(),
token: z.string()
})

type Auth = z.infer
export type UserLoginForm = Pick
export type UserRegistrationForm = Pick
export type RequestConfirmationCodeForm = Pick
export type ForgottenPasswordForm = Pick
export type NewPasswordForm = Pick
export type UpdateCurrentPasswordForm = Pick
export type ConfirmToken = Pick
export type CheckPasswordForm = Pick

/** User Authentication */
export const userSchema = authSchema.pick({
name:true,
email:true
}).extend({
_id: z.string()
})
export type User = z.infer
export type UserProfileForm = Pick

/** Notes */
const noteSchema = z.object({
_id: z.string(),
content: z.string(),
createdBy: userSchema,
task: z.string(),
createdAt: z.string()
})
export type Note = z.infer
export type NoteFormData = Pick

/** Tasks */
export const taskStatusSchema = z.enum(["pending", "onHold" , "inProgress" , "underReview" , "completed"])
export type TaskStatus = z.infer

export const taskSchema = z.object({
_id: z.string(),
name: z.string(),
description: z.string(),
project: z.string(),
status: taskStatusSchema,
completedBy: z.array(z.object({
_id: z.string(),
user: userSchema,
status: taskStatusSchema
})),
notes: z.array(noteSchema.extend({
createdBy: userSchema
})),
createdAt: z.string(),
updatedAt: z.string()
})

export const taskProjectSchema = taskSchema.pick({
_id: true,
name: true,
description: true,
status: true
})

export type Task = z.infer
export type TaskFormData = Pick
export type TaskProject = z.infer

/** Projects **/
export const projectSchema = z.object({
_id: z.string(),
projectName: z.string(),
clientName: z.string(),
description: z.string(),
manager: z.string(),
tasks: z.array( taskProjectSchema ),
team: z.array( z.string() )
})

export const dashboardProjectSchema = z.array(
projectSchema.pick({
_id: true,
projectName: true,
clientName: true,
description: true,
manager: true,
tasks: true,
team: true
})
)

export const editProjectSchema = projectSchema.pick({
projectName: true,
clientName: true,
description: true
})

export type Project = z.infer
export type ProjectFormData = Pick & { tasks?:string[] }

/** Team */
const teamMemberSchema = userSchema.pick({
name: true,
email: true,
_id:true
})

export const teamMembersSchema = z.array(teamMemberSchema)
export type TeamMember = z.infer
export type TeamMemberForm = Pick
```
#### src/env.local
```
VITE_API_URL=https://server-uptask-node-typescript.onrender.com/api
```