{"id":29867184,"url":"https://github.com/chucho-kun/client-uptask-node-typescript-","last_synced_at":"2025-10-13T17:06:51.852Z","repository":{"id":304253586,"uuid":"1018236968","full_name":"Chucho-Kun/client-uptask-node-typescript-","owner":"Chucho-Kun","description":"CLIENT - UpTask in React - Typescript - TailwindCSS","archived":false,"fork":false,"pushed_at":"2025-07-30T20:28:40.000Z","size":675,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-30T22:55:42.602Z","etag":null,"topics":["jsonwebtoken","login-system","mongodb-atlas","platform-engineering","react","server","task-manager","typescript"],"latest_commit_sha":null,"homepage":"https://client-uptask-node-typescript.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Chucho-Kun.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-11T21:14:46.000Z","updated_at":"2025-07-30T20:28:43.000Z","dependencies_parsed_at":"2025-07-12T00:23:02.055Z","dependency_job_id":"7a5dab1f-70e5-4df8-98d4-ec4aff15ffc8","html_url":"https://github.com/Chucho-Kun/client-uptask-node-typescript-","commit_stats":null,"previous_names":["chucho-kun/client-uptask-node-typescript-"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/Chucho-Kun/client-uptask-node-typescript-","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Chucho-Kun%2Fclient-uptask-node-typescript-","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Chucho-Kun%2Fclient-uptask-node-typescript-/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Chucho-Kun%2Fclient-uptask-node-typescript-/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Chucho-Kun%2Fclient-uptask-node-typescript-/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Chucho-Kun","download_url":"https://codeload.github.com/Chucho-Kun/client-uptask-node-typescript-/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Chucho-Kun%2Fclient-uptask-node-typescript-/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279016281,"owners_count":26085827,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jsonwebtoken","login-system","mongodb-atlas","platform-engineering","react","server","task-manager","typescript"],"created_at":"2025-07-30T13:22:33.665Z","updated_at":"2025-10-13T17:06:51.846Z","avatar_url":"https://github.com/Chucho-Kun.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FRONT MERN - REST API REACT/TypeScript\nReact Web Platform connected to an API hosted on a MongoDB + Express + React + Node ( MERN )\n## 🚀 Tech Stack MERN\n![MongoDB](https://img.shields.io/badge/MongoDB-47A248?style=for-the-badge\u0026logo=mongodb\u0026logoColor=white)\n![Express](https://img.shields.io/badge/Express.js-000000?style=for-the-badge\u0026logo=express\u0026logoColor=white)\n![React](https://img.shields.io/badge/React-61DAFB?style=for-the-badge\u0026logo=react\u0026logoColor=black)\n![Node.js](https://img.shields.io/badge/Node.js-339933?style=for-the-badge\u0026logo=node.js\u0026logoColor=white)\n\n![Gameplay A](src/assets/shotA.png)\n![Gameplay B](src/assets/shotB.png)\n![Gameplay C](src/assets/shotC.png)\n![Gameplay 1](src/assets/shot1.png)\n![Gameplay 2](src/assets/shot2.png)\n![Gameplay 3](src/assets/shot3.png)\n\n## Technologies\nReact + Typescript + TailwindCSS + Axios + Zod + React Router + React Query\n## Developer Notes\n## Deploy on Vercel\nWebsite hosted on vercel.com server\nhttps://client-uptask-node-typescript.vercel.app/\n### Managed with Axios\n#### src/lib/axios.ts\n```\nimport axios from \"axios\"\n\nconst api = axios.create({\n    baseURL: import.meta.env.VITE_API_URL\n});\n\napi.interceptors.request.use( config =\u003e {\n  const token = localStorage.getItem('AUTH_TOKEN')\n  if(token){\n    config.headers.Authorization = `Bearer ${token}`\n  }\n  return config\n})\nexport default api\n```\n#### src/api/ProjectAPI.ts\n```\nimport api from \"@/lib/axios\";\nimport { dashboardProjectSchema, editProjectSchema, projectSchema, type Project, type ProjectFormData } from \"../types\";\nimport { isAxiosError } from \"axios\";\n\nexport async function createProject( formData : ProjectFormData ) {\n    \n    try {\n        const { data } = await api.post( '/projects' , formData )\n        return data        \n    } catch (error) {\n        if( isAxiosError(error) \u0026\u0026 error.response ){\n            throw new Error(error.response.data.error)\n        }\n        \n    }\n    \n}\n\nexport async function getProjects() {\n    \n    try {\n        const { data } = await api('/projects')  \n        const response = dashboardProjectSchema.safeParse(data)\n        \n        if(response.success) return response.data\n        //return []; // O retorna un array vacío para evitar undefined\n    } catch (error) {\n        if( isAxiosError(error) \u0026\u0026 error.response){\n            throw new Error( error.response.data.error )\n        }\n        return [];\n    }\n}\n\nexport async function getProjectsById( id : Project['_id'] ) {\n    try {\n        const { data } = await api(`/projects/${ id }`)\n        const response = editProjectSchema.safeParse(data)\n        if(response.success){\n            return response.data\n        }\n    } catch (error) {\n        if( isAxiosError(error) \u0026\u0026 error.response){\n            throw new Error( error.response.data.error )\n        }\n    }\n}\n\nexport async function getFullProject( id : Project['_id'] ) {\n    try {\n        const { data } = await api(`/projects/${ id }`)\n        const response = projectSchema.safeParse(data)\n        if(response.success){\n            return response.data\n        }\n    } catch (error) {\n        if( isAxiosError(error) \u0026\u0026 error.response){\n            throw new Error( error.response.data.error )\n        }\n    }\n}\n\ntype ProjectAPIType = {\n    formData: ProjectFormData\n    projectId: Project['_id']\n}\n\nexport async function updateProject({ formData , projectId } : ProjectAPIType) {\n    try {\n        const { data } = await api.put\u003cstring\u003e(`/projects/${ projectId }` , formData)\n            return data            \n    } catch (error) {\n        if( isAxiosError(error) \u0026\u0026 error.response){\n            throw new Error( error.response.data.error )\n        }\n    }\n}\n\nexport async function deleteProject( id : Project['_id'] ) {\n    try {\n        const { data } = await api.delete\u003cstring\u003e(`/projects/${ id }`)\n            return data            \n    } catch (error) {\n        if( isAxiosError(error) \u0026\u0026 error.response){\n            throw new Error( error.response.data.error )\n        }\n    }\n}\n```\n#### src/types/index.ts\n```\nimport { z } from \"zod\"\n\n/** Auth \u0026 Users */\n\nconst authSchema = z.object({\n    name: z.string(),\n    email: z.email(),\n    current_password: z.string(),\n    password: z.string(),\n    password_confirmation: z.string(),\n    token: z.string()\n})\n\ntype Auth = z.infer\u003ctypeof authSchema\u003e\nexport type UserLoginForm = Pick\u003cAuth, 'email' | 'password'\u003e\nexport type UserRegistrationForm = Pick\u003cAuth, 'name' | 'email' | 'password' | 'password_confirmation'\u003e\nexport type RequestConfirmationCodeForm = Pick\u003cAuth, 'email' \u003e\nexport type ForgottenPasswordForm = Pick\u003cAuth, 'email' \u003e\nexport type NewPasswordForm = Pick\u003cAuth, 'password' | 'password_confirmation' \u003e\nexport type UpdateCurrentPasswordForm = Pick\u003cAuth, 'password' | 'password_confirmation' | 'current_password'\u003e\nexport type ConfirmToken = Pick\u003cAuth, 'token'\u003e\nexport type CheckPasswordForm = Pick\u003cAuth, 'password'\u003e\n\n/** User Authentication */\nexport const userSchema = authSchema.pick({\n    name:true,\n    email:true\n}).extend({\n    _id: z.string()\n})\nexport type User = z.infer\u003ctypeof userSchema\u003e\nexport type UserProfileForm = Pick\u003cUser, 'name' | 'email'\u003e\n\n/** Notes */\nconst noteSchema = z.object({\n    _id: z.string(),\n    content: z.string(),\n    createdBy: userSchema,\n    task: z.string(),\n    createdAt: z.string()\n})\nexport type Note = z.infer\u003ctypeof noteSchema\u003e\nexport type NoteFormData = Pick\u003cNote, 'content'\u003e\n\n/** Tasks */\nexport const taskStatusSchema = z.enum([\"pending\", \"onHold\" , \"inProgress\" , \"underReview\" , \"completed\"])\nexport type TaskStatus = z.infer\u003ctypeof taskStatusSchema\u003e\n\nexport const taskSchema = z.object({\n    _id: z.string(),\n    name: z.string(),\n    description: z.string(),\n    project: z.string(),\n    status: taskStatusSchema,\n    completedBy: z.array(z.object({\n        _id: z.string(),\n        user: userSchema,\n        status: taskStatusSchema\n    })),\n    notes: z.array(noteSchema.extend({\n        createdBy: userSchema\n    })),\n    createdAt: z.string(),\n    updatedAt: z.string()\n})\n\nexport const taskProjectSchema = taskSchema.pick({\n    _id: true,\n    name: true,\n    description: true,\n    status: true\n})\n\nexport type Task = z.infer\u003ctypeof taskSchema\u003e\nexport type TaskFormData = Pick\u003cTask, 'name' | 'description'\u003e\nexport type TaskProject = z.infer\u003ctypeof taskProjectSchema\u003e\n\n/** Projects **/\nexport const projectSchema = z.object({\n    _id: z.string(),\n    projectName: z.string(),\n    clientName: z.string(),\n    description: z.string(),\n    manager: z.string(),\n    tasks: z.array( taskProjectSchema ),\n    team: z.array( z.string() )\n})\n\nexport const dashboardProjectSchema = z.array(\n   projectSchema.pick({\n        _id: true,\n        projectName: true,\n        clientName: true,\n        description: true,\n        manager: true,\n        tasks: true,\n        team: true\n   })\n)\n\nexport const editProjectSchema = projectSchema.pick({\n    projectName: true,\n    clientName: true,\n    description: true\n})\n\nexport type Project = z.infer\u003ctypeof projectSchema\u003e\nexport type ProjectFormData = Pick\u003cProject , 'clientName' | 'projectName' | 'description' \u003e \u0026 { tasks?:string[] }\n\n\n/** Team */\nconst teamMemberSchema = userSchema.pick({\n    name: true,\n    email: true,\n    _id:true\n})\n\nexport const teamMembersSchema = z.array(teamMemberSchema)\nexport type TeamMember = z.infer\u003ctypeof teamMemberSchema\u003e\nexport type TeamMemberForm = Pick\u003cTeamMember , 'email'\u003e\n```\n#### src/env.local\n```\nVITE_API_URL=https://server-uptask-node-typescript.onrender.com/api\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchucho-kun%2Fclient-uptask-node-typescript-","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchucho-kun%2Fclient-uptask-node-typescript-","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchucho-kun%2Fclient-uptask-node-typescript-/lists"}