still rainbow vommit
This commit is contained in:
parent
f857ae3e2d
commit
8032f415dc
@ -1,9 +1,9 @@
|
|||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
|
import jwt from 'jsonwebtoken';
|
||||||
import { getRepository } from 'typeorm';
|
import { getRepository } from 'typeorm';
|
||||||
import { Project } from './entities/Project';
|
import { Project } from './entities/Project';
|
||||||
import { ProjectMember } from './entities/ProjectMember'
|
import { ProjectMember } from './entities/ProjectMember';
|
||||||
import { Task } from './entities/Task';
|
import { Task } from './entities/Task';
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
import { User } from './entities/User';
|
import { User } from './entities/User';
|
||||||
|
|
||||||
const SECRET_KEY = process.env.JWT_SECRET || 'your_secret_key';
|
const SECRET_KEY = process.env.JWT_SECRET || 'your_secret_key';
|
||||||
|
|||||||
@ -6,12 +6,15 @@ import {
|
|||||||
useGetTasksForGroupQuery,
|
useGetTasksForGroupQuery,
|
||||||
} from '../../services/mainApi';
|
} from '../../services/mainApi';
|
||||||
import TaskCard from '../TaskCard/TaskCard';
|
import TaskCard from '../TaskCard/TaskCard';
|
||||||
import CreateTaskDialog from './CreateTaskDialog/CreateTaskDialog';
|
import AddUserToProjectDialog from '../dialogs/AddUserToProjectDialog/AddUserToProjectDialog';
|
||||||
import DeleteProjectDialog from './DeleteProjectDialog/CreateTaskDialog';
|
import CreateTaskDialog from '../dialogs/CreateTaskDialog/CreateTaskDialog';
|
||||||
|
import DeleteProjectDialog from '../dialogs/DeleteProjectDialog/CreateTaskDialog';
|
||||||
|
|
||||||
|
import { PlusIcon } from '@radix-ui/react-icons';
|
||||||
|
|
||||||
type TCardGroup = {
|
type TCardGroup = {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function CardGroup(props: TCardGroup) {
|
export default function CardGroup(props: TCardGroup) {
|
||||||
@ -56,14 +59,19 @@ export default function CardGroup(props: TCardGroup) {
|
|||||||
</Box>
|
</Box>
|
||||||
<Flex gap={'2'} className="mx-auto w-full mt-2">
|
<Flex gap={'2'} className="mx-auto w-full mt-2">
|
||||||
<CreateTaskDialog onClose={createTask}>
|
<CreateTaskDialog onClose={createTask}>
|
||||||
<Button>Add Task</Button>
|
<Button className='!grow-1'>Add Task</Button>
|
||||||
</CreateTaskDialog>
|
</CreateTaskDialog>
|
||||||
<DeleteProjectDialog onClose={deleteGroup}>
|
<DeleteProjectDialog onClose={deleteGroup}>
|
||||||
<Button color="red" onClick={deleteGroup}>
|
<Button className='!grow-1' color="red">Delete Project</Button>
|
||||||
Delete Project
|
|
||||||
</Button>
|
|
||||||
</DeleteProjectDialog>
|
</DeleteProjectDialog>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
|
<AddUserToProjectDialog projectId={+props.id}>
|
||||||
|
<Button className='!mt-2'>
|
||||||
|
<PlusIcon />
|
||||||
|
Add user
|
||||||
|
</Button>
|
||||||
|
</AddUserToProjectDialog>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</Droppable>
|
</Droppable>
|
||||||
|
|||||||
@ -2,41 +2,24 @@ import { DragDropContext } from '@hello-pangea/dnd';
|
|||||||
import { Button, Flex, ScrollArea } from '@radix-ui/themes';
|
import { Button, Flex, ScrollArea } from '@radix-ui/themes';
|
||||||
import {
|
import {
|
||||||
useCreateProjectMutation,
|
useCreateProjectMutation,
|
||||||
useCreateTaskMutation,
|
useGetProjectsQuery
|
||||||
useGetProjectsQuery,
|
|
||||||
} from '../../services/mainApi';
|
} from '../../services/mainApi';
|
||||||
import CardGroup from '../CardGroup/CardGroup';
|
import CardGroup from '../CardGroup/CardGroup';
|
||||||
|
import CreateProjectDialog from '../dialogs/CreateProjectDialog/CreateProjectDialog';
|
||||||
|
|
||||||
export default function MainBoard() {
|
export default function MainBoard() {
|
||||||
const dragEndHandle = (result: TDragResult) => {
|
const dragEndHandle = (result: TDragResult) => {
|
||||||
result;
|
result;
|
||||||
};
|
};
|
||||||
|
|
||||||
const [create] = useCreateTaskMutation();
|
|
||||||
const [createProject] = useCreateProjectMutation();
|
const [createProject] = useCreateProjectMutation();
|
||||||
const { data: cringe, isLoading } = useGetProjectsQuery({});
|
const { data: cringe, isLoading } = useGetProjectsQuery({});
|
||||||
|
|
||||||
const onClick = () => {
|
|
||||||
create({
|
|
||||||
title: 'My Task 123',
|
|
||||||
projectId: 4,
|
|
||||||
assignedUserId: 1,
|
|
||||||
deadline: '2025-03-01T12:00:00Z',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onClick1 = () => {
|
|
||||||
createProject({
|
|
||||||
title: 'My project test 12',
|
|
||||||
description: 'Test desc 123 123 123',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DragDropContext onDragEnd={dragEndHandle}>
|
<DragDropContext onDragEnd={dragEndHandle}>
|
||||||
<ScrollArea scrollbars='horizontal' className='pb-3'>
|
<ScrollArea scrollbars="horizontal" className="pb-3">
|
||||||
<Flex gap={'2'} className='min-w-fit'>
|
<Flex gap={'2'} className="min-w-fit">
|
||||||
{!isLoading &&
|
{!isLoading &&
|
||||||
(cringe as any[]).map((item: any) => (
|
(cringe as any[]).map((item: any) => (
|
||||||
<CardGroup id={item.id} title={item.title} />
|
<CardGroup id={item.id} title={item.title} />
|
||||||
@ -44,7 +27,10 @@ export default function MainBoard() {
|
|||||||
</Flex>
|
</Flex>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</DragDropContext>
|
</DragDropContext>
|
||||||
<Button onClick={onClick1}>Create project</Button>
|
|
||||||
|
<CreateProjectDialog onCreate={createProject}>
|
||||||
|
<Button>Create project</Button>
|
||||||
|
</CreateProjectDialog>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,92 @@
|
|||||||
|
import { Button, Dialog, Flex, Select } from '@radix-ui/themes';
|
||||||
|
import { PropsWithChildren, useState } from 'react';
|
||||||
|
import {
|
||||||
|
useAddProjectMemberMutation,
|
||||||
|
useGetAllUsersQuery,
|
||||||
|
} from '../../../services/mainApi';
|
||||||
|
|
||||||
|
type TAddUserToProjectDialog = {
|
||||||
|
projectId: number;
|
||||||
|
} & PropsWithChildren;
|
||||||
|
|
||||||
|
export default function AddUserToProjectDialog(props: TAddUserToProjectDialog) {
|
||||||
|
const { projectId, children } = props;
|
||||||
|
const { data: users, isLoading, error, refetch } = useGetAllUsersQuery({});
|
||||||
|
const [addProjectMember, { isLoading: isAdding }] =
|
||||||
|
useAddProjectMemberMutation();
|
||||||
|
const [selectedUserId, setSelectedUserId] = useState<number | null>(null);
|
||||||
|
|
||||||
|
const handleAddUser = async () => {
|
||||||
|
if (selectedUserId) {
|
||||||
|
try {
|
||||||
|
await addProjectMember({
|
||||||
|
projectId,
|
||||||
|
memberId: selectedUserId,
|
||||||
|
}).unwrap();
|
||||||
|
setSelectedUserId(null);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to add user:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog.Root onOpenChange={() => refetch()}>
|
||||||
|
<Dialog.Trigger>{children}</Dialog.Trigger>
|
||||||
|
|
||||||
|
<Dialog.Content maxWidth="450px">
|
||||||
|
<Dialog.Title>Add User to Project</Dialog.Title>
|
||||||
|
|
||||||
|
<Flex direction="column" gap="3" mt="4">
|
||||||
|
{isLoading ? (
|
||||||
|
<span>Loading users...</span>
|
||||||
|
) : error ? (
|
||||||
|
<span>Error loading users.</span>
|
||||||
|
) : (
|
||||||
|
<Select.Root
|
||||||
|
value={selectedUserId?.toString() || ''}
|
||||||
|
onValueChange={(value) =>
|
||||||
|
setSelectedUserId(Number(value))
|
||||||
|
}
|
||||||
|
required
|
||||||
|
>
|
||||||
|
<Select.Trigger aria-label="User">
|
||||||
|
{selectedUserId
|
||||||
|
? users?.find(
|
||||||
|
(user: any) =>
|
||||||
|
user.id === selectedUserId,
|
||||||
|
)?.username
|
||||||
|
: 'Select a user'}
|
||||||
|
</Select.Trigger>
|
||||||
|
<Select.Content>
|
||||||
|
{users?.map((user: any) => (
|
||||||
|
<Select.Item key={user.id} value={user.id}>
|
||||||
|
{user.username}
|
||||||
|
</Select.Item>
|
||||||
|
))}
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex gap="3" mt="4" justify="end">
|
||||||
|
<Dialog.Close>
|
||||||
|
<Button variant="soft" color="gray">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</Dialog.Close>
|
||||||
|
<Dialog.Close>
|
||||||
|
<Button
|
||||||
|
color="green"
|
||||||
|
onClick={handleAddUser}
|
||||||
|
disabled={!selectedUserId || isAdding}
|
||||||
|
>
|
||||||
|
{isAdding ? 'Adding...' : 'Add'}
|
||||||
|
</Button>
|
||||||
|
</Dialog.Close>
|
||||||
|
</Flex>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog.Root>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
import { Button, Dialog, Flex, TextArea, TextField } from '@radix-ui/themes';
|
||||||
|
import { PropsWithChildren, useState } from 'react';
|
||||||
|
|
||||||
|
type TCreateProjectDialog = {
|
||||||
|
onCreate: (f: any) => void;
|
||||||
|
} & PropsWithChildren;
|
||||||
|
|
||||||
|
export default function CreateProjectDialog(props: TCreateProjectDialog) {
|
||||||
|
const [title, setTitle] = useState('');
|
||||||
|
const [description, setDescription] = useState('');
|
||||||
|
|
||||||
|
const handleCreate = () => {
|
||||||
|
props.onCreate({title, description});
|
||||||
|
setTitle('');
|
||||||
|
setDescription('');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog.Root>
|
||||||
|
<Dialog.Trigger>
|
||||||
|
{props.children}
|
||||||
|
</Dialog.Trigger>
|
||||||
|
|
||||||
|
<Dialog.Content maxWidth="450px">
|
||||||
|
<Dialog.Title>Create a New Project</Dialog.Title>
|
||||||
|
|
||||||
|
<Flex direction="column" gap="3" mt="4">
|
||||||
|
<TextField.Root
|
||||||
|
value={title}
|
||||||
|
onChange={(e) => setTitle(e.target.value)}
|
||||||
|
required
|
||||||
|
></TextField.Root>
|
||||||
|
<TextArea
|
||||||
|
value={description}
|
||||||
|
onChange={(e) => setDescription(e.target.value)}
|
||||||
|
placeholder="Optional description"
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex gap="3" mt="4" justify="end">
|
||||||
|
<Dialog.Close>
|
||||||
|
<Button variant="soft" color="gray">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</Dialog.Close>
|
||||||
|
<Dialog.Close>
|
||||||
|
<Button
|
||||||
|
color="green"
|
||||||
|
onClick={handleCreate}
|
||||||
|
disabled={!title}
|
||||||
|
>
|
||||||
|
Create
|
||||||
|
</Button>
|
||||||
|
</Dialog.Close>
|
||||||
|
</Flex>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog.Root>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -8,8 +8,33 @@ import {
|
|||||||
TextField,
|
TextField,
|
||||||
} from '@radix-ui/themes';
|
} from '@radix-ui/themes';
|
||||||
import { Form } from 'radix-ui';
|
import { Form } from 'radix-ui';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { useRegisterMutation } from '../../../services/mainApi';
|
||||||
|
|
||||||
export default function RegisterPage() {
|
export default function RegisterPage() {
|
||||||
|
const [register, { isLoading, error }] = useRegisterMutation();
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
username: '',
|
||||||
|
email: '',
|
||||||
|
password: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setFormData({
|
||||||
|
...formData,
|
||||||
|
[e.target.name]: e.target.value,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
try {
|
||||||
|
await register(formData).unwrap();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to register:', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-fit">
|
<Card className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-fit">
|
||||||
<Heading size="4" className="text-center !mb-2">
|
<Heading size="4" className="text-center !mb-2">
|
||||||
@ -17,8 +42,27 @@ export default function RegisterPage() {
|
|||||||
</Heading>
|
</Heading>
|
||||||
<Form.Root
|
<Form.Root
|
||||||
className="flex flex-col gap-4"
|
className="flex flex-col gap-4"
|
||||||
onSubmit={(e) => e.preventDefault()}
|
onSubmit={handleSubmit}
|
||||||
>
|
>
|
||||||
|
<Form.Field name="username">
|
||||||
|
<Form.Message match="valueMissing">
|
||||||
|
<Text>Username is required</Text>
|
||||||
|
</Form.Message>
|
||||||
|
|
||||||
|
<Form.Control asChild>
|
||||||
|
<TextField.Root
|
||||||
|
type="text"
|
||||||
|
name="username"
|
||||||
|
placeholder="Username"
|
||||||
|
required
|
||||||
|
value={formData.username}
|
||||||
|
onChange={handleChange}
|
||||||
|
>
|
||||||
|
<TextField.Slot />
|
||||||
|
</TextField.Root>
|
||||||
|
</Form.Control>
|
||||||
|
</Form.Field>
|
||||||
|
|
||||||
<Form.Field name="email">
|
<Form.Field name="email">
|
||||||
<Form.Message match="valueMissing">
|
<Form.Message match="valueMissing">
|
||||||
<Text>Email is required</Text>
|
<Text>Email is required</Text>
|
||||||
@ -31,8 +75,11 @@ export default function RegisterPage() {
|
|||||||
<Form.Control asChild>
|
<Form.Control asChild>
|
||||||
<TextField.Root
|
<TextField.Root
|
||||||
type="email"
|
type="email"
|
||||||
|
name="email"
|
||||||
placeholder="Email"
|
placeholder="Email"
|
||||||
required
|
required
|
||||||
|
value={formData.email}
|
||||||
|
onChange={handleChange}
|
||||||
>
|
>
|
||||||
<TextField.Slot />
|
<TextField.Slot />
|
||||||
</TextField.Root>
|
</TextField.Root>
|
||||||
@ -49,16 +96,24 @@ export default function RegisterPage() {
|
|||||||
type="password"
|
type="password"
|
||||||
placeholder="Password"
|
placeholder="Password"
|
||||||
required
|
required
|
||||||
|
value={formData.password}
|
||||||
|
onChange={handleChange}
|
||||||
>
|
>
|
||||||
<TextField.Slot />
|
<TextField.Slot />
|
||||||
</TextField.Root>
|
</TextField.Root>
|
||||||
</Form.Control>
|
</Form.Control>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
|
|
||||||
<Button onClick={(e) => e.preventDefault()} className="mt-4">
|
<Button type="submit" disabled={isLoading} className="mt-4">
|
||||||
Register
|
Register
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{error && (
|
||||||
|
<Box className="text-red-500">
|
||||||
|
<Text>Error registering user.</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
<Box className="w-full !flex justify-center">
|
<Box className="w-full !flex justify-center">
|
||||||
<Link href="/login">
|
<Link href="/login">
|
||||||
<Text>Login</Text>
|
<Text>Login</Text>
|
||||||
@ -67,4 +122,4 @@ export default function RegisterPage() {
|
|||||||
</Form.Root>
|
</Form.Root>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -3,7 +3,7 @@ import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
|
|||||||
export const mainApi = createApi({
|
export const mainApi = createApi({
|
||||||
reducerPath: 'api',
|
reducerPath: 'api',
|
||||||
baseQuery: fetchBaseQuery({
|
baseQuery: fetchBaseQuery({
|
||||||
baseUrl: 'http://109.107.166.17:3000/api/',
|
baseUrl: 'http://109.107.166.17:5000/api/',
|
||||||
prepareHeaders: (headers) => {
|
prepareHeaders: (headers) => {
|
||||||
headers.set(
|
headers.set(
|
||||||
'Authorization',
|
'Authorization',
|
||||||
@ -12,7 +12,7 @@ export const mainApi = createApi({
|
|||||||
return headers;
|
return headers;
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
tagTypes: ['Task', 'Project'],
|
tagTypes: ['Task', 'Project', 'ProjectMembers'],
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
getTasks: builder.query<string[], void>({
|
getTasks: builder.query<string[], void>({
|
||||||
query: () => ({
|
query: () => ({
|
||||||
@ -57,7 +57,7 @@ export const mainApi = createApi({
|
|||||||
query: (task) => ({
|
query: (task) => ({
|
||||||
url: `tasks/${task.id}`,
|
url: `tasks/${task.id}`,
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
body: {status: task.status},
|
body: { status: task.status },
|
||||||
}),
|
}),
|
||||||
invalidatesTags: (result, error, id) => [{ type: 'Task', id }],
|
invalidatesTags: (result, error, id) => [{ type: 'Task', id }],
|
||||||
}),
|
}),
|
||||||
@ -88,7 +88,7 @@ export const mainApi = createApi({
|
|||||||
}),
|
}),
|
||||||
getProjects: builder.query({
|
getProjects: builder.query({
|
||||||
query: () => ({
|
query: () => ({
|
||||||
url: 'projects',
|
url: 'projects/my',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
}),
|
}),
|
||||||
providesTags: (result, error, id) => [
|
providesTags: (result, error, id) => [
|
||||||
@ -115,7 +115,40 @@ export const mainApi = createApi({
|
|||||||
url: `projects/${id}`,
|
url: `projects/${id}`,
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
}),
|
}),
|
||||||
invalidatesTags: (result, error, id) => [{ type: 'Project', id }],
|
invalidatesTags: (result, error, id) => [
|
||||||
|
{ type: 'Project', id: 'LIST' },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
|
||||||
|
// PROJECT MEMBERS
|
||||||
|
addProjectMember: builder.mutation({
|
||||||
|
query: ({ projectId, memberId }) => ({
|
||||||
|
url: `projects/${projectId}/members/add`,
|
||||||
|
method: 'POST',
|
||||||
|
body: { userId: memberId, role: '' },
|
||||||
|
}),
|
||||||
|
invalidatesTags: (result, error, args) => [
|
||||||
|
{ type: 'ProjectMembers', id: 'LIST' },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
getProjectMembers: builder.query({
|
||||||
|
query: (id) => ({
|
||||||
|
url: `projects/${id}/members`,
|
||||||
|
method: 'GET',
|
||||||
|
}),
|
||||||
|
providesTags: (result, error, args) => [
|
||||||
|
{ type: 'ProjectMembers', id: 'LIST' },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
removeProjectMember: builder.mutation({
|
||||||
|
query: ({ projectId, memberId }) => ({
|
||||||
|
url: `projects/${projectId}/members/remove`,
|
||||||
|
method: 'DELETE',
|
||||||
|
body: { userId: memberId },
|
||||||
|
}),
|
||||||
|
invalidatesTags: (result, error, id) => [
|
||||||
|
{ type: 'ProjectMembers', id: 'LIST' },
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
@ -123,39 +156,76 @@ export const mainApi = createApi({
|
|||||||
export const authApi = createApi({
|
export const authApi = createApi({
|
||||||
reducerPath: 'authApi',
|
reducerPath: 'authApi',
|
||||||
baseQuery: fetchBaseQuery({
|
baseQuery: fetchBaseQuery({
|
||||||
baseUrl: 'http://109.107.166.17:3000/api/auth/',
|
baseUrl: 'http://109.107.166.17:4000/api/',
|
||||||
|
|
||||||
}),
|
}),
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
login: builder.mutation({
|
login: builder.mutation({
|
||||||
query: (credentials) => ({
|
query: (credentials) => ({
|
||||||
url: 'login',
|
url: '/auth/login',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: credentials,
|
body: credentials,
|
||||||
}),
|
}),
|
||||||
async onQueryStarted(arg, { queryFulfilled }) {
|
async onQueryStarted(arg, { queryFulfilled }) {
|
||||||
try {
|
try {
|
||||||
const response = await queryFulfilled;
|
const response = await queryFulfilled;
|
||||||
if (response.data) {
|
if (response.data.access_token) {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'token',
|
'token',
|
||||||
response.data.access_token,
|
response.data.access_token,
|
||||||
);
|
);
|
||||||
window.location.href = '/';
|
if (response.meta?.response?.status === 201)
|
||||||
|
window.location.href = '/';
|
||||||
}
|
}
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
register: builder.mutation({
|
register: builder.mutation({
|
||||||
query: (credentials) => ({
|
query: (credentials) => ({
|
||||||
url: 'register',
|
url: '/auth/register',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: credentials,
|
body: credentials,
|
||||||
}),
|
}),
|
||||||
}),
|
onQueryStarted: async (arg, { queryFulfilled }) => {
|
||||||
|
try {
|
||||||
|
const response = await queryFulfilled;
|
||||||
|
if (response.meta?.response?.status === 201)
|
||||||
|
window.location.href = '/login';
|
||||||
|
} catch (error) {}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
// USERS
|
||||||
|
getAllUsers: builder.query({
|
||||||
|
query: () => ({
|
||||||
|
url: '/users',
|
||||||
|
method: 'GET',
|
||||||
|
}),
|
||||||
|
keepUnusedDataFor: 0,
|
||||||
|
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { useLoginMutation, useRegisterMutation } = authApi;
|
export const { useLoginMutation, useRegisterMutation, useGetAllUsersQuery } =
|
||||||
export const { useGetTasksQuery, useCreateTaskMutation, useUpdateTaskMutation, useDeleteTaskMutation, useGetTasksForGroupQuery } = mainApi;
|
authApi;
|
||||||
export const { useGetProjectsQuery, useCreateProjectMutation, useUpdateProjectMutation, useDeleteProjectMutation } = mainApi;
|
|
||||||
|
export const {
|
||||||
|
useGetTasksQuery,
|
||||||
|
useCreateTaskMutation,
|
||||||
|
useUpdateTaskMutation,
|
||||||
|
useDeleteTaskMutation,
|
||||||
|
useGetTasksForGroupQuery,
|
||||||
|
} = mainApi;
|
||||||
|
|
||||||
|
export const {
|
||||||
|
useGetProjectsQuery,
|
||||||
|
useCreateProjectMutation,
|
||||||
|
useUpdateProjectMutation,
|
||||||
|
useDeleteProjectMutation,
|
||||||
|
} = mainApi;
|
||||||
|
|
||||||
|
export const {
|
||||||
|
useRemoveProjectMemberMutation,
|
||||||
|
useAddProjectMemberMutation,
|
||||||
|
useGetProjectMembersQuery,
|
||||||
|
} = mainApi;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user