Skip to content

Commit

Permalink
feat: [LINKER-80] 일정 등록 기능 구현 (#68)
Browse files Browse the repository at this point in the history
  • Loading branch information
useonglee authored Feb 23, 2024
1 parent 7915a07 commit 3c9e536
Show file tree
Hide file tree
Showing 26 changed files with 751 additions and 36 deletions.
5 changes: 3 additions & 2 deletions packages/lds/src/Button/IconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import { Icon } from '../Icon';

interface Props extends HTMLAttributes<HTMLButtonElement> {
name: string;
size?: number;
className?: string;
}

const IconButton = ({ name, className, ...props }: Props) => {
const IconButton = ({ name, size = 32, className, ...props }: Props) => {
return (
<button type="button" className={className} {...props}>
<Icon name={name} />
<Icon name={name} size={size} />
</button>
);
};
Expand Down
16 changes: 8 additions & 8 deletions packages/lds/src/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';

import clsx from 'clsx';
import { HTMLAttributes } from 'react';
import { ReactNode } from 'react';
import { useState } from 'react';
Expand All @@ -10,21 +11,20 @@ import { DropdownProvider, useDropdownContext } from './context';

interface Props extends HTMLAttributes<HTMLButtonElement> {
open?: boolean;
onOpenChange?: () => void;
children?: ReactNode;
className?: string;
}

const Dropdown = ({ children, className, open }: Props) => {
const Dropdown = ({ children, className, open, onOpenChange }: Props) => {
const [isOpen, setIsOpen] = useState(false);

return (
<DropdownProvider
isOpen={open ?? isOpen}
onOpenChange={() => {
setIsOpen((prev) => !prev);
}}
onOpenChange={onOpenChange ?? (() => setIsOpen((prev) => !prev))}
>
<button className={className}>{children}</button>
<div className={className}>{children}</div>
</DropdownProvider>
);
};
Expand All @@ -35,11 +35,11 @@ export default Object.assign(Dropdown, {
Content: DropdownContent,
});

function DropdownTrigger({ children }: Props) {
function DropdownTrigger({ children, className }: Props) {
const { onOpenChange } = useDropdownContext('Dropdown-Trigger');

return (
<button type="button" onClick={onOpenChange} className={dropdownTrigger}>
<button type="button" onClick={onOpenChange} className={clsx(dropdownTrigger, className)}>
{children}
</button>
);
Expand All @@ -48,5 +48,5 @@ function DropdownTrigger({ children }: Props) {
function DropdownContent({ children, className }: Props) {
const { isOpen } = useDropdownContext('Dropdow-Trigger');

return <>{isOpen && <button className={className}> {children}</button>}</>;
return <>{isOpen && <ul className={className}> {children}</ul>}</>;
}
1 change: 0 additions & 1 deletion packages/lds/src/Layout/Layout.css.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { style } from '@vanilla-extract/css';

export const container = style({
position: 'relative',
maxWidth: '72rem',
minWidth: '36rem',
width: '100%',
Expand Down
4 changes: 1 addition & 3 deletions packages/lds/src/List/ListHeader.css.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { style } from '@vanilla-extract/css';

export const headerContainer = style({
position: 'relative',
});
export const headerContainer = style({});

export const headerTitle = style({
display: 'flex',
Expand Down
5 changes: 3 additions & 2 deletions packages/lds/src/TextArea/TextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import { Txt } from '../Txt';
interface Props extends InputHTMLAttributes<HTMLTextAreaElement> {
value?: string;
label?: string;
containerClassName?: string;
className?: string;
errorMessage?: string;
}

const Input = forwardRef<HTMLTextAreaElement, Props>(
({ label, className, errorMessage, value, ...props }, ref) => {
({ label, containerClassName, className, errorMessage, value, ...props }, ref) => {
return (
<div className={formContainer}>
<div className={clsx(formContainer, containerClassName)}>
{label != null && (
<label htmlFor={label} className={labelContainer}>
{label}
Expand Down
4 changes: 4 additions & 0 deletions packages/styles/src/nomalize.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ body {
-moz-user-select: none;
-ms-user-select: none;
user-select: none;

* {
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function ContactSearch({ contacts }: ContactDataRes) {

useEffect(() => {
setQueryAtom(query);
}, [query]);
}, [query, setQueryAtom]);

return (
<section className={container}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const keyframesExample = keyframes({
'0%': {
opacity: 0,
transform: 'scale(0.95)',
background: colors.gradationPurple,
},
'50%': {
opacity: 0.5,
Expand All @@ -13,14 +14,17 @@ const keyframesExample = keyframes({
'100%': {
opacity: 1,
transform: 'scale(1)',
background: colors.gradationPurple,
},
});

export const bannerContainer = style({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
background: colors.gradationPurple,
maxWidth: '72rem',
margin: '1.6rem auto',
background: `${colors.gradationPurple} !important`,
animation: `${keyframesExample} 0.4s linear`,
});

Expand Down
10 changes: 9 additions & 1 deletion services/web/src/app/my/feed/contact-banner/ContactBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import { useRouter } from 'next/navigation';

import { bannerContainer, contentWrapper, imageWrapper, text } from './ContactBanner.css';

function ContactBanner() {
interface Props {
isLoggedIn: boolean;
}

function ContactBanner({ isLoggedIn }: Props) {
const router = useRouter();

const handleLoginClick = () => {
Expand All @@ -19,6 +23,10 @@ function ContactBanner() {
router.replace(`${process.env.NEXT_PUBLIC_KAKAO_LOGIN_URL}`);
};

if (isLoggedIn) {
return;
}

return (
<motion.div
initial={{
Expand Down
2 changes: 1 addition & 1 deletion services/web/src/app/my/feed/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function FeedPage() {

return (
<article className={wrapper}>
{accessToken == null && <ContactBanner />}
<ContactBanner isLoggedIn={accessToken != null} />
<UpcomingSchedule />
<Recommendation />
<PreviousSchedule />
Expand Down
5 changes: 2 additions & 3 deletions services/web/src/app/my/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import { Layout } from '@linker/lds';
import { getTokens } from '@utils/token/server';

function MyLayout({ children }: { children: React.ReactNode }) {
const hasToken = getTokens().accessToken;
const { accessToken } = getTokens();

return (
<>
<MyHeader />
<Layout>
{children}

{hasToken && <FloatingButton />}
{accessToken != null && <FloatingButton />}
</Layout>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/* eslint-disable max-lines */
/* eslint-disable max-lines-per-function */
/* eslint-disable no-console */
import { Tag } from '@/types/contact';
import useAddContact from '@features/contact/hooks/useAddContact';
import useImageUpload from '@features/contact/hooks/useImageUpload';
import { isDisplaySelectTagAtom, selectedTagsAtom } from '@features/contact/store';
import { selectedTagsAtom } from '@features/contact/store';
import {
BottomSheet,
Chip,
Expand Down Expand Up @@ -46,8 +47,6 @@ export interface InputData {

const AddFriendBottomSheet = () => {
const imageUploadRef = useRef<HTMLInputElement>(null);
const [isDisplaySelectTag, setIsDisplaySelectTag] = useAtom(isDisplaySelectTagAtom);
const [selectedTags, setSelectedTags] = useAtom(selectedTagsAtom);

const {
register,
Expand All @@ -66,6 +65,8 @@ const AddFriendBottomSheet = () => {
const { mutate: addContact } = useAddContact();

const [imageUrl, setImageUrl] = useState<string | null>(null);
const [isDisplaySelectTag, setIsDisplaySelectTag] = useState(false);
const [selectedTags, setSelectedTags] = useAtom(selectedTagsAtom);

const 모든정보를_입력했는가 =
formState.every((value) => value !== '') && imageS3Url != null && isValid;
Expand All @@ -89,7 +90,7 @@ const AddFriendBottomSheet = () => {
const payload = {
name: data.name,
profileImgUrl: imageS3Url ?? '',
phoneNumber: formatPhoneNumber(data.phoneNumber),
phoneNumber: data.phoneNumber,
description: data.description,
interests: selectedTags,
};
Expand All @@ -101,7 +102,7 @@ const AddFriendBottomSheet = () => {
return (
<BottomSheet.Content>
{isDisplaySelectTag ? (
<SelectTag />
<SelectTag setIsDisplay={setIsDisplaySelectTag} />
) : (
<>
<BottomSheet.ButtonGroup>
Expand Down Expand Up @@ -170,9 +171,16 @@ const AddFriendBottomSheet = () => {
<Input
label="전화번호"
placeholder="전화번호를 입력해주세요"
type="text"
errorMessage={errors.phoneNumber?.message}
onKeyUp={(e) => {
const formatted = formatPhoneNumber(e.currentTarget.value);

e.currentTarget.value = formatted;
}}
{...register('phoneNumber', {
required: '숫자만 입력할 수 있어요.',
required: true,
maxLength: 11,
pattern: {
value: /^[0-9]+$/,
message: '숫자만 입력할 수 있어요.',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Tag } from '@/types/contact';
import { isDisplaySelectTagAtom, selectedTagsAtom } from '@features/contact/store';
import { selectedTagsAtom } from '@features/contact/store';
import { BottomSheet, Chip, TextButton, Txt } from '@linker/lds';
import { colors } from '@linker/styles';
import { useSetAtom } from 'jotai';
Expand All @@ -8,9 +8,12 @@ import { useState } from 'react';
import { container, interestTagWrapper } from './SelectTag.css';
import { INTEREST_TAGS } from './constants';

const SelectTagBottomSheet = () => {
interface Props {
setIsDisplay: (value: boolean) => void;
}

const SelectTagBottomSheet = ({ setIsDisplay }: Props) => {
const setSelectedTags = useSetAtom(selectedTagsAtom);
const setIsDisplay = useSetAtom(isDisplaySelectTagAtom);

const [tags, setTags] = useState<Tag[]>([]);

Expand Down
2 changes: 0 additions & 2 deletions services/web/src/features/contact/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,3 @@ import { Tag } from '@/types/contact';
import { atom } from 'jotai';

export const selectedTagsAtom = atom<Tag[]>([]);

export const isDisplaySelectTagAtom = atom(false);
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { AddFriendBottomSheet } from '@features/contact/components';
import { AddScheduleBottomSheet } from '@features/schedule/components';
import { BottomSheet, Button, IconButton } from '@linker/lds';
import type { FABType } from '@linker/lds/src/Button/FAB';
import { useEffect, useState } from 'react';
Expand Down Expand Up @@ -31,7 +32,7 @@ const FloatingButton = () => {
}, []);

const BottomSheetContext = {
calendar: <AddFriendBottomSheet />,
calendar: <AddScheduleBottomSheet />,
user: <AddFriendBottomSheet />,
};

Expand Down
Loading

0 comments on commit 3c9e536

Please sign in to comment.