Skip to content

Commit

Permalink
Merge pull request #13 from P-r4Tes/feat/asidebar
Browse files Browse the repository at this point in the history
Feat/asidbar Sidbar Component style
  • Loading branch information
entrolEC authored Mar 13, 2024
2 parents 2e4836a + b099b46 commit 5617503
Show file tree
Hide file tree
Showing 14 changed files with 4,479 additions and 6,439 deletions.
10,753 changes: 4,350 additions & 6,403 deletions .pnp.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function getAbsolutePath(value: string): any {
}
const config: StorybookConfig = {
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
staticDirs: ["../public"],
staticDirs: ["../src/assets"],
addons: [
getAbsolutePath("@storybook/addon-links"),
getAbsolutePath("@storybook/addon-essentials"),
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@yarnpkg/plugin-typescript": "^4.0.0",
"clsx": "^2.1.0",
"firebase": "^10.8.1",
"framer-motion": "^11.0.8",
"next": "14.1.0",
"prettier-plugin-tailwindcss": "^0.5.11",
"react": "^18",
Expand Down
12 changes: 6 additions & 6 deletions src/__test__/api/user.test.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as firebaseModule from "@/api/firebase";
import {
deleteUser,
getUser,
popUserGroup,
popUserPersonalSchedule,
postUser,
pushUserPersonalSchedule,
pushUserGroup,
popUserPersonalSchedule,
popUserGroup,
pushUserPersonalSchedule,
updateUserName,
getUser,
deleteUser,
} from "@/api/users";

jest.mock("@/api/firebase", () => ({
Expand Down Expand Up @@ -47,7 +47,7 @@ describe("User functions", () => {
const id = "TEST_USER_ID"; // id 추가
const body = { email: "[email protected]", name: "CSKIM", groups: ["g1"], personalSchedules: ["s1"] };
postUser(id, body);
expect(firebaseModule.postFirebase).toHaveBeenCalledWith("users", id, body);
expect(firebaseModule.postFirebase).toHaveBeenCalledWith("users", body, id);
});

test("전달인자가 유효하지 않다면 pushUserPersonalSchedule는 에러를 반환해야 한다", () => {
Expand Down
5 changes: 3 additions & 2 deletions src/api/firebase.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { db } from "@/lib/firebaseConfig";
import { arrayRemove, arrayUnion, collection, deleteDoc, doc, getDoc, updateDoc, addDoc } from "firebase/firestore";
import { addDoc, arrayRemove, arrayUnion, collection, deleteDoc, doc, getDoc, updateDoc } from "firebase/firestore";

// 조건부 파라미터를 추가하고 addDoc을 바꾸고 둘다 해야한다.
export const postFirebase = async <T extends TableTypes>(table: T, id: string, body: TalbeField<T>) => {
export const postFirebase = async <T extends TableTypes>(table: T, body: TalbeField<T>, id?: string) => {
try {
if (id === undefined) return await addDoc(collection(db, table), body);
await addDoc(collection(db, table), { ...body, id });
} catch (e) {
console.error("Invalid Data");
Expand Down
2 changes: 1 addition & 1 deletion src/api/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {

export const postUser = (id: string, body: user) => {
if (isEmpty(body.email)) throw new Error("Invalid email");
postFirebase<"users">("users", id, body);
postFirebase<"users">("users", body, id);
};

export const getUser = (id: string) => {
Expand Down
3 changes: 2 additions & 1 deletion src/components/MonthView/MonthBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { generateCalendar } from "@/lib/functions/calendar";
import { useRouter } from "next/navigation";
import React, { useState, useEffect } from "react";
import React, { useEffect, useState } from "react";
import { EmptyLayout } from "./EmptyLayout";
import { MONTH_BODY } from "@/constants/testId";
import { DataSpreader } from "./DateSpreader";
Expand Down Expand Up @@ -52,6 +52,7 @@ function MonthBody(props: MonthBodyProps) {

const newData = new Date(parseInt(year), parseInt(month) - 1, 1);
setDate(newData);
// eslint-disable-next-line
}, [month, year]);

useEffect(() => {
Expand Down
14 changes: 11 additions & 3 deletions src/components/Sidebar/AddGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import Link from "next/link";
import PlusIcon from "@/components/Sidebar/PlusIcon";
import { motion } from "framer-motion";

type GroupProps = {
href: string;
};
const AddGroup = ({ href }: GroupProps) => {
return (
<Link href={href} className="w-full h-auto rounded-full bg-slate-800 p-2">
<PlusIcon className="text-white" />
</Link>
<motion.div
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.95 }}
transition={{ type: "spring", stiffness: 400, damping: 17 }}
className="w-12 h-12 rounded-full bg-slate-800 p-2"
>
<Link href={href}>
<PlusIcon className="text-white" />
</Link>
</motion.div>
);
};

Expand Down
41 changes: 23 additions & 18 deletions src/components/Sidebar/Group.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
"use client";
import Image from "next/image";
import Link from "next/link";
import clsx from "clsx";
import { MouseEventHandler } from "react";
import { motion } from "framer-motion";
import clsx from "clsx";

// 임시 이미지
const tempSrc = "https://avatars.githubusercontent.com/u/161491870?s=200&v=4";
Expand All @@ -13,26 +15,29 @@ type GroupProps = Pick<group, "name"> & {
};
const Group = ({ name, href, selected, onSelect }: GroupProps) => {
return (
<Link
href={href}
<motion.div
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.95 }}
transition={{ type: "spring", stiffness: 400, damping: 17 }}
className={clsx("", {
"border-2 border-slate-100": selected,
"border-2 border-slate-300 rounded-full": selected,
})}
onClick={onSelect}
>
<Image
className="rounded-full"
src={tempSrc}
alt={`그룹 ${name}`}
sizes="100vw"
style={{
width: "100%",
height: "auto",
}}
width={360}
height={360}
/>
</Link>
<Link href={href} onClick={onSelect}>
<Image
className="rounded-full"
src={tempSrc}
alt={`그룹 ${name}`}
sizes="100vw"
style={{
width: "100%",
height: "auto",
}}
width={360}
height={360}
/>
</Link>
</motion.div>
);
};

Expand Down
16 changes: 16 additions & 0 deletions src/components/Sidebar/Pointer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client";
import { motion } from "framer-motion";
import { CSSProperties } from "react";

const Pointer = ({ top, style }: { top: number; style?: CSSProperties }) => {
return (
<motion.div
className={"absolute left-1 w-2 h-2 rounded-full bg-white"}
style={{ ...style, top: top }}
layout
transition={{ type: "spring", stiffness: 700, damping: 30 }}
/>
);
};

export default Pointer;
12 changes: 12 additions & 0 deletions src/components/Sidebar/Sidebar.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ export const Default: Story = {
users: ["user1"],
schedules: ["schedules"],
},
{
id: "test2",
name: "샘플2",
users: ["user2"],
schedules: ["schedules"],
},
{
id: "test3",
name: "샘플3",
users: ["user3"],
schedules: ["schedules"],
},
],
},
};
16 changes: 13 additions & 3 deletions src/components/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,27 @@
import React, { MouseEventHandler, useState } from "react";
import Group from "@/components/Sidebar/Group";
import AddGroup from "@/components/Sidebar/AddGroup";
import Pointer from "@/components/Sidebar/Pointer";

type SidebarProps = {
groups: (group & id)[];
};

const ASIDE_WIDTH = 80;
const ASIDE_PADDING = 16;
const GROUP_HEIGHT = ASIDE_WIDTH - ASIDE_PADDING * 2; // 48
const GROUP_REDIUS = GROUP_HEIGHT / 2; // 24
const POINTER_REDIUS = 4;

const Sidebar = ({ groups }: SidebarProps) => {
const [selectedIdx, setSelectedIdx] = useState(0);
const height = groups.length * 80 + 80;
const height = groups.length * (GROUP_HEIGHT + ASIDE_PADDING) + 80;
const pointerY = selectedIdx * (GROUP_HEIGHT + ASIDE_PADDING) + GROUP_REDIUS - POINTER_REDIUS;

return (
<div className="flex h-screen">
<aside className={"flex items-center w-20 bg-[#383A57] rounded-l-3xl"} style={{ height: height }}>
<div className="flex flex-col items-center space-y-4 p-4">
<aside className="flex items-center bg-[#383A57] rounded-l-3xl" style={{ height: height, width: ASIDE_WIDTH }}>
<div className="relative flex flex-col items-center space-y-4" style={{ padding: ASIDE_PADDING }}>
{groups.map((group, idx) => {
const onSelect: MouseEventHandler<HTMLAnchorElement> = () => {
setSelectedIdx(idx);
Expand All @@ -29,6 +38,7 @@ const Sidebar = ({ groups }: SidebarProps) => {
);
})}
<AddGroup href="." />
<Pointer top={pointerY} style={{ width: POINTER_REDIUS * 2, height: POINTER_REDIUS * 2 }} />
</div>
</aside>
</div>
Expand Down
3 changes: 2 additions & 1 deletion src/components/UserProfile/UserProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import defaultAvatar from "@/assets/defaultAvatar.png";
import styles from "./UserProfile.module.css";
import Image from "next/image";

type UserProfileProps = {
userImage?: string;
Expand All @@ -12,7 +13,7 @@ export const UserProfile = ({ userImage, userName }: UserProfileProps) => {
<div className="flex w-[212px] h-[60px] px-2 bg-[#393D5E] rounded-lg items-center">
<div className="h-11 justify-start items-center gap-2 inline-flex">
<div className={styles.hexagon}>
<img src={imageUrl} alt="userImage" />
<Image src={imageUrl} alt="userImage" />
</div>
<div className="text-white text-md font-normal leading-[7px]">{userName}</div>
</div>
Expand Down
38 changes: 38 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1905,6 +1905,22 @@ __metadata:
languageName: node
linkType: hard

"@emotion/is-prop-valid@npm:^0.8.2":
version: 0.8.8
resolution: "@emotion/is-prop-valid@npm:0.8.8"
dependencies:
"@emotion/memoize": "npm:0.7.4"
checksum: 10c0/f6be625f067c7fa56a12a4edaf090715616dc4fc7803c87212831f38c969350107b9709b1be54100e53153b18d9fa068eb4bf4f9ac66a37a8edf1bac9b64e279
languageName: node
linkType: hard

"@emotion/memoize@npm:0.7.4":
version: 0.7.4
resolution: "@emotion/memoize@npm:0.7.4"
checksum: 10c0/b2376548fc147b43afd1ff005a80a1a025bd7eb4fb759fdb23e96e5ff290ee8ba16628a332848d600fb91c3cdc319eee5395fa33d8875e5d5a8c4ce18cddc18e
languageName: node
linkType: hard

"@emotion/use-insertion-effect-with-fallbacks@npm:^1.0.0":
version: 1.0.1
resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.0.1"
Expand Down Expand Up @@ -7401,6 +7417,7 @@ __metadata:
eslint-plugin-react-hooks: "npm:^4.6.0"
eslint-plugin-storybook: "npm:^0.8.0"
firebase: "npm:^10.8.1"
framer-motion: "npm:^11.0.8"
husky: "npm:^9.0.11"
jest: "npm:^29.7.0"
jest-environment-jsdom: "npm:^29.7.0"
Expand Down Expand Up @@ -10156,6 +10173,27 @@ __metadata:
languageName: node
linkType: hard

"framer-motion@npm:^11.0.8":
version: 11.0.8
resolution: "framer-motion@npm:11.0.8"
dependencies:
"@emotion/is-prop-valid": "npm:^0.8.2"
tslib: "npm:^2.4.0"
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
dependenciesMeta:
"@emotion/is-prop-valid":
optional: true
peerDependenciesMeta:
react:
optional: true
react-dom:
optional: true
checksum: 10c0/098776e277b1707116c511f62261ed421381071258a6174c51bf1cdbb7ed436b5789fa114144426253d1719e6426d51e3f1812a9cbc1ca773361b63aacda8056
languageName: node
linkType: hard

"fresh@npm:0.5.2":
version: 0.5.2
resolution: "fresh@npm:0.5.2"
Expand Down

0 comments on commit 5617503

Please sign in to comment.