Skip to content

Commit

Permalink
feat(frontend): update space document title, space document list (#50)
Browse files Browse the repository at this point in the history
* Add Cover Photo for CoverPage

* Update Document Title, and Add Left Side Document List
  • Loading branch information
cptrodgers authored May 8, 2024
1 parent 2b7f327 commit 50ec1d0
Show file tree
Hide file tree
Showing 14 changed files with 830 additions and 63 deletions.
45 changes: 0 additions & 45 deletions apps/ikigai/components/DocumentV2/DocumentBody/CoverPage.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import styled from "styled-components";
import { Trans } from "@lingui/macro";
import React from "react";

import { Button } from "components/common/Button";
import { DraggerStyled } from "components/common/FileUpload";
import { PictureIcon } from "components/common/IconSvg";
import useDocumentStore from "context/DocumentV2Store";

const CoverHeader = () => {
const activeDocument = useDocumentStore((state) => state.activeDocument);

return (
<Container>
<DocumentPhotoCover>
{activeDocument.coverPhotoUrl && (
<img src={activeDocument.coverPhotoUrl} alt="photoCover" />
)}
<EditCoverButton size="large" icon={<PictureIcon />}>
<Trans>Edit Cover</Trans>
</EditCoverButton>
</DocumentPhotoCover>
</Container>
);
};

const Container = styled.div`
width: 100%;
min-height: 50px;
`;

const EditCoverButton = styled(Button)`
&&& {
box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px,
rgba(15, 15, 15, 0.1) 0px 2px 4px;
height: 34px;
position: absolute;
bottom: 16px;
right: 16px;
border: none;
opacity: 0;
font-size: 13px;
font-weight: 500;
transition: opacity 0.3s;
.ant-btn-icon {
margin-inline-end: 0px;
}
}
`;

const DocumentPhotoCover = styled.div`
display: grid;
width: 100%;
height: 30vh;
background-color: ${(props) => props.theme.colors.primary[5]};
position: relative;
cursor: pointer;
img {
display: block;
object-fit: cover;
border-radius: 0px;
width: 100%;
height: 30vh;
opacity: 1;
object-position: center 50%;
}
&&& {
span {
font-size: 13px;
font-weight: 500;
}
svg {
height: 16px;
margin-inline-end: 4px;
}
&:hover {
${EditCoverButton} {
opacity: 1;
}
}
${DraggerStyled} {
div {
border: none;
align-items: self-start;
}
}
}
`;

export default CoverHeader;
90 changes: 90 additions & 0 deletions apps/ikigai/components/DocumentV2/DocumentBody/CoverPage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { useEffect } from "react";
import { Divider, Input } from "antd";
import { t } from "@lingui/macro";
import styled from "styled-components";
import { useDebounce } from "ahooks";
import { useMutation } from "@apollo/client";

import { BreakPoints } from "styles/mediaQuery";
import useDocumentStore from "context/DocumentV2Store";
import CoverHeader from "./CoverHeader";
import { UPDATE_DOCUMENT } from "graphql/mutation/SpaceMutation";
import { handleError } from "graphql/ApolloClient";
import { UpdateDocumentData } from "graphql/types";

const CoverPage = () => {
const [updateDocumentServer] = useMutation(UPDATE_DOCUMENT, {
onError: handleError,
});
const activeDocumentId = useDocumentStore((state) => state.activeDocumentId);
const activeDocumentTitle = useDocumentStore(
(state) => state.activeDocument?.title,
);
const activeDocument = useDocumentStore((state) => state.activeDocument);
const updateActiveDocument = useDocumentStore(
(state) => state.updateActiveDocument,
);
const updateSpaceDocument = useDocumentStore(
(state) => state.updateSpaceDocument,
);
const debouncedTitle = useDebounce(activeDocumentTitle, { wait: 500 });

useEffect(() => {
const updateDocumentData: UpdateDocumentData = {
title: debouncedTitle || "",
coverPhotoId: activeDocument.coverPhotoId,
editorConfig: activeDocument.editorConfig,
body: activeDocument.body,
};
updateDocumentServer({
variables: {
documentId: activeDocumentId,
data: updateDocumentData,
},
});
}, [debouncedTitle]);

const changeTitle = (value: string) => {
updateActiveDocument({ title: value });
updateSpaceDocument(activeDocumentId, { title: value });
};

return (
<div>
<CoverHeader />
<div style={{ padding: 20 }}>
<DocumentTitle
autoSize
variant="borderless"
maxLength={255}
value={activeDocumentTitle}
onChange={(e) => changeTitle(e.currentTarget.value)}
placeholder={t`Untitled`}
/>
<Divider />
</div>
</div>
);
};

export const DocumentTitle = styled(Input.TextArea)`
&&& {
font-size: 40px;
font-weight: 700;
padding-left: 0;
overflow: hidden;
line-height: normal;
&:focus {
outline: none !important;
box-shadow: none !important;
border-color: transparent !important;
}
${BreakPoints.tablet} {
font-size: 32px;
}
}
`;

export default CoverPage;
13 changes: 10 additions & 3 deletions apps/ikigai/components/DocumentV2/DocumentBody/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ import { BreakPoints } from "styles/mediaQuery";

import CoverPage from "./CoverPage";
import { useState } from "react";
import { Skeleton } from "antd";

const DocumentBody = () => {
export type DocumentBodyProps = {
loading: boolean;
};

const DocumentBody = ({ loading }: DocumentBodyProps) => {
const [activePageId] = useState<string | undefined>();

return (
<Container>
<Body>{!activePageId && <CoverPage />}</Body>
<Body>
{loading && <Skeleton />}
{!loading && !activePageId && <CoverPage />}
</Body>
</Container>
);
};
Expand All @@ -34,7 +42,6 @@ const Body = styled.div<{
background: #ffff;
border: 1px solid var(--gray-4, #eaecef);
box-sizing: border-box;
padding: 20px;
${BreakPoints.tablet} {
margin: 0;
Expand Down
35 changes: 22 additions & 13 deletions apps/ikigai/components/DocumentV2/LeftSide/index.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
import React, { useState } from "react";
import shallow from "zustand/shallow";
import { Divider } from "antd";
import { t } from "@lingui/macro";
import styled from "styled-components";

import useDocumentStore from "context/ZustandDocumentStore";
import { GetDocuments_spaceGet_documents } from "graphql/types";
import useAuthUserStore from "context/ZustandAuthStore";
import EditProfileModal from "components/UserCredential/EditProfileModal";
import UserBasicInformation from "components/UserBasicInformation";
import { BreakPoints } from "styles/mediaQuery";
import LearningModuleDnd from "components/common/LearningModuleDnd";
import LessonItemDnd from "components/common/LearningModuleDnd/LessonItemDnd";
import useDocumentStore from "context/DocumentV2Store";

interface Props {
docs: GetDocuments_spaceGet_documents[];
}

const LeftSide: React.FC<Props> = () => {
const leftPanelHidden = useDocumentStore(
(state) => state.leftPanelHidden,
shallow,
);
const LeftSide = () => {
const me = useAuthUserStore((state) => state.currentUser?.userMe);
const spaceDocuments = useDocumentStore((state) => state.spaceDocuments);
const [openProfile, setOpenProfile] = useState(false);

const myName = me ? `${me.firstName} ${me.lastName}` : t`Unknown`;
return (
<Container $hide={leftPanelHidden}>
<Container $hide={false}>
<div style={{ width: "100%" }}>
<SpaceInfoContainer>
<UserBasicInformation
Expand All @@ -37,6 +30,14 @@ const LeftSide: React.FC<Props> = () => {
/>
</SpaceInfoContainer>
<NoMarginDivider $margin={0} />
<ListModule style={{ height: "80%", overflow: "auto" }}>
<LearningModuleDnd
docs={spaceDocuments}
keyword={""}
TreeItemComponent={LessonItemDnd}
defaultCollapsed={true}
/>
</ListModule>
</div>
{openProfile && (
<EditProfileModal
Expand Down Expand Up @@ -79,3 +80,11 @@ const Container = styled.div<{
height: auto;
}
`;

const ListModule = styled.div`
padding: 10px 20px;
overflow: auto;
display: flex;
flex-direction: column;
gap: 8px;
`;
11 changes: 9 additions & 2 deletions apps/ikigai/components/DocumentV2/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import React from "react";
import styled from "styled-components";
import { useRouter } from "next/router";

import { BreakPoints } from "styles/mediaQuery";
import LeftSide from "./LeftSide";
import DocumentBody from "./DocumentBody";
import RightSide from "./RightSide";
import { useLoadDocument } from "hook/UseLoadDocumentV2";

const Document = () => {
const router = useRouter();
const documentId = router.query.documentId as string;

const { loading } = useLoadDocument(documentId);

return (
<Container>
<DocumentHeaderWrapper>
Expand All @@ -16,8 +23,8 @@ const Document = () => {
</DocumentHeaderWrapper>
<DocumentBodyContainer>
<BodyWrapper>
<LeftSide docs={[]} />
<DocumentBody />
<LeftSide />
<DocumentBody loading={loading} />
<RightSide />
</BodyWrapper>
</DocumentBodyContainer>
Expand Down
Loading

0 comments on commit 50ec1d0

Please sign in to comment.