feat: added user auth

This commit is contained in:
Aaryan Khandelwal 2023-01-27 12:55:20 +05:30
parent 9075f9441c
commit cedc884d92
26 changed files with 356 additions and 299 deletions

View file

@ -4,6 +4,8 @@ import { useRouter } from "next/router";
import useSWR, { mutate } from "swr";
// lib
import { requiredAdmin, requiredAuth } from "lib/auth";
// layouts
import AppLayout from "layouts/app-layout";
// contexts
@ -32,7 +34,8 @@ import { CustomMenu, EmptySpace, EmptySpaceItem, Spinner } from "components/ui";
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
// icons
// types
import { CycleIssueResponse, IIssue, SelectIssue } from "types";
import { CycleIssueResponse, IIssue, SelectIssue, UserAuth } from "types";
import { NextPageContext } from "next";
// fetch-keys
import {
CYCLE_ISSUES,
@ -42,7 +45,7 @@ import {
PROJECT_DETAILS,
} from "constants/fetch-keys";
const SingleCycle: React.FC = () => {
const SingleCycle: React.FC<UserAuth> = (props) => {
const [isIssueModalOpen, setIsIssueModalOpen] = useState(false);
const [selectedIssues, setSelectedIssues] = useState<SelectIssue>();
const [cycleIssuesListModal, setCycleIssuesListModal] = useState(false);
@ -109,18 +112,6 @@ const SingleCycle: React.FC = () => {
}
);
const partialUpdateIssue = (formData: Partial<IIssue>, issueId: string) => {
if (!workspaceSlug || !projectId) return;
issuesServices
.patchIssue(workspaceSlug as string, projectId as string, issueId, formData)
.then(() => {
mutate(CYCLE_ISSUES(cycleId as string));
})
.catch((error) => {
console.log(error);
});
};
const openCreateIssueModal = (
issue?: IIssue,
actionType: "create" | "edit" | "delete" = "create"
@ -256,16 +247,16 @@ const SingleCycle: React.FC = () => {
openIssuesListModal={openIssuesListModal}
removeIssueFromCycle={removeIssueFromCycle}
setPreloadedData={setPreloadedData}
userAuth={props}
/>
<CyclesBoardView
issues={cycleIssuesArray ?? []}
removeIssueFromCycle={removeIssueFromCycle}
members={members}
openCreateIssueModal={openCreateIssueModal}
openIssuesListModal={openIssuesListModal}
handleDeleteIssue={setDeleteIssue}
partialUpdateIssue={partialUpdateIssue}
setPreloadedData={setPreloadedData}
userAuth={props}
/>
</div>
) : (
@ -309,4 +300,32 @@ const SingleCycle: React.FC = () => {
);
};
export const getServerSideProps = async (ctx: NextPageContext) => {
const user = await requiredAuth(ctx.req?.headers.cookie);
const redirectAfterSignIn = ctx.req?.url;
if (!user) {
return {
redirect: {
destination: `/signin?next=${redirectAfterSignIn}`,
permanent: false,
},
};
}
const projectId = ctx.query.projectId as string;
const workspaceSlug = ctx.query.workspaceSlug as string;
const memberDetail = await requiredAdmin(workspaceSlug, projectId, ctx.req?.headers.cookie);
return {
props: {
isOwner: memberDetail?.role === 20,
isMember: memberDetail?.role === 15,
isViewer: memberDetail?.role === 10,
isGuest: memberDetail?.role === 5,
},
};
};
export default SingleCycle;

View file

@ -4,7 +4,7 @@ import useSWR, { mutate } from "swr";
import { RectangleStackIcon } from "@heroicons/react/24/outline";
import { PlusIcon } from "@heroicons/react/20/solid";
// lib
import { requiredAuth } from "lib/auth";
import { requiredAdmin, requiredAuth } from "lib/auth";
// services
import issuesServices from "services/issues.service";
import projectService from "services/project.service";
@ -22,12 +22,12 @@ import View from "components/core/view";
import { Spinner, EmptySpace, EmptySpaceItem, HeaderButton } from "components/ui";
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
// types
import type { IIssue, IssueResponse } from "types";
import type { IIssue, IssueResponse, UserAuth } from "types";
import type { NextPage, NextPageContext } from "next";
// fetch-keys
import { PROJECT_DETAILS, PROJECT_ISSUES_LIST } from "constants/fetch-keys";
const ProjectIssues: NextPage = () => {
const ProjectIssues: NextPage<UserAuth> = (props) => {
const [isOpen, setIsOpen] = useState(false);
const [selectedIssue, setSelectedIssue] = useState<
(IIssue & { actionType: "edit" | "delete" }) | undefined
@ -63,26 +63,6 @@ const ProjectIssues: NextPage = () => {
}
}, [isOpen]);
const partialUpdateIssue = (formData: Partial<IIssue>, issueId: string) => {
if (!workspaceSlug || !projectId) return;
issuesServices
.patchIssue(workspaceSlug as string, projectId as string, issueId, formData)
.then((response) => {
mutate<IssueResponse>(
PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string),
(prevData) => ({
...(prevData as IssueResponse),
results:
prevData?.results.map((issue) => (issue.id === response.id ? response : issue)) ?? [],
}),
false
);
})
.catch((error) => {
console.log(error);
});
};
const handleEditIssue = (issue: IIssue) => {
setIsOpen(true);
setSelectedIssue({ ...issue, actionType: "edit" });
@ -134,12 +114,12 @@ const ProjectIssues: NextPage = () => {
<ListView
issues={projectIssues?.results.filter((p) => p.parent === null) ?? []}
handleEditIssue={handleEditIssue}
partialUpdateIssue={partialUpdateIssue}
userAuth={props}
/>
<BoardView
issues={projectIssues?.results.filter((p) => p.parent === null) ?? []}
handleDeleteIssue={setDeleteIssue}
partialUpdateIssue={partialUpdateIssue}
userAuth={props}
/>
</>
) : (
@ -170,7 +150,6 @@ const ProjectIssues: NextPage = () => {
export const getServerSideProps = async (ctx: NextPageContext) => {
const user = await requiredAuth(ctx.req?.headers.cookie);
const redirectAfterSignIn = ctx.req?.url;
if (!user) {
@ -182,9 +161,17 @@ export const getServerSideProps = async (ctx: NextPageContext) => {
};
}
const projectId = ctx.query.projectId as string;
const workspaceSlug = ctx.query.workspaceSlug as string;
const memberDetail = await requiredAdmin(workspaceSlug, projectId, ctx.req?.headers.cookie);
return {
props: {
user,
isOwner: memberDetail?.role === 20,
isMember: memberDetail?.role === 15,
isViewer: memberDetail?.role === 10,
isGuest: memberDetail?.role === 5,
},
};
};

View file

@ -3,6 +3,9 @@ import React, { useState } from "react";
import { useRouter } from "next/router";
import useSWR, { mutate } from "swr";
// lib
import { requiredAdmin, requiredAuth } from "lib/auth";
// services
import modulesService from "services/modules.service";
import projectService from "services/project.service";
@ -32,7 +35,15 @@ import {
RectangleStackIcon,
} from "@heroicons/react/24/outline";
// types
import { IIssue, IModule, ModuleIssueResponse, SelectIssue, SelectModuleType } from "types";
import {
IIssue,
IModule,
ModuleIssueResponse,
SelectIssue,
SelectModuleType,
UserAuth,
} from "types";
import { NextPageContext } from "next";
// fetch-keys
import {
MODULE_DETAIL,
@ -42,7 +53,7 @@ import {
PROJECT_MEMBERS,
} from "constants/fetch-keys";
const SingleModule = () => {
const SingleModule: React.FC<UserAuth> = (props) => {
const [moduleSidebar, setModuleSidebar] = useState(true);
const [moduleDeleteModal, setModuleDeleteModal] = useState(false);
const [selectedIssues, setSelectedIssues] = useState<SelectIssue>(null);
@ -128,18 +139,6 @@ const SingleModule = () => {
}
};
const partialUpdateIssue = (formData: Partial<IIssue>, issueId: string) => {
if (!workspaceSlug || !projectId) return;
issuesService
.patchIssue(workspaceSlug as string, projectId as string, issueId, formData)
.then(() => {
mutate(MODULE_ISSUES(moduleId as string));
})
.catch((error) => {
console.log(error);
});
};
const openCreateIssueModal = (
issue?: IIssue,
actionType: "create" | "edit" | "delete" = "create"
@ -279,16 +278,16 @@ const SingleModule = () => {
openIssuesListModal={openIssuesListModal}
removeIssueFromModule={removeIssueFromModule}
setPreloadedData={setPreloadedData}
userAuth={props}
/>
<ModulesBoardView
issues={moduleIssuesArray ?? []}
removeIssueFromModule={removeIssueFromModule}
members={members}
openCreateIssueModal={openCreateIssueModal}
openIssuesListModal={openIssuesListModal}
handleDeleteIssue={setDeleteIssue}
partialUpdateIssue={partialUpdateIssue}
setPreloadedData={setPreloadedData}
userAuth={props}
/>
</div>
) : (
@ -333,4 +332,32 @@ const SingleModule = () => {
);
};
export const getServerSideProps = async (ctx: NextPageContext) => {
const user = await requiredAuth(ctx.req?.headers.cookie);
const redirectAfterSignIn = ctx.req?.url;
if (!user) {
return {
redirect: {
destination: `/signin?next=${redirectAfterSignIn}`,
permanent: false,
},
};
}
const projectId = ctx.query.projectId as string;
const workspaceSlug = ctx.query.workspaceSlug as string;
const memberDetail = await requiredAdmin(workspaceSlug, projectId, ctx.req?.headers.cookie);
return {
props: {
isOwner: memberDetail?.role === 20,
isMember: memberDetail?.role === 15,
isViewer: memberDetail?.role === 10,
isGuest: memberDetail?.role === 5,
},
};
};
export default SingleModule;

View file

@ -6,7 +6,6 @@ import Image from "next/image";
import useSWR, { mutate } from "swr";
import { Controller, useForm } from "react-hook-form";
import type { NextPageContext, NextPage } from "next";
// lib
import { requiredAdmin } from "lib/auth";
// layouts
@ -21,6 +20,7 @@ import { Button, CustomSelect, Loader } from "components/ui";
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
// types
import { IProject, IWorkspace } from "types";
import type { NextPageContext, NextPage } from "next";
// fetch-keys
import { PROJECTS_LIST, PROJECT_DETAILS, WORKSPACE_MEMBERS } from "constants/fetch-keys";
@ -88,24 +88,9 @@ const ControlSettings: NextPage<TControlSettingsProps> = (props) => {
await projectService
.updateProject(workspaceSlug as string, projectId as string, payload)
.then((res) => {
mutate<IProject>(
PROJECT_DETAILS(projectId as string),
(prevData) => ({ ...prevData, ...res }),
false
);
mutate<IProject[]>(
PROJECTS_LIST(workspaceSlug as string),
(prevData) => {
const newData = prevData?.map((item) => {
if (item.id === res.id) {
return res;
}
return item;
});
return newData;
},
false
);
mutate(PROJECT_DETAILS(projectId as string));
mutate(PROJECTS_LIST(workspaceSlug as string));
setToastAlert({
title: "Success",
type: "success",