Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat/#219] 회의 생성 후 바텀 시트 모달 #223

Merged
merged 7 commits into from
Mar 23, 2024
11 changes: 9 additions & 2 deletions src/components/atomComponents/Button.tsx
Original file line number Diff line number Diff line change
@@ -51,12 +51,12 @@ const buttonCSS = {
${buttonDefaultCSS.basicCss};
background: ${({ theme }) => theme.colors.grey7};
width: 15.2rem;
color: ${({ theme }) => theme.colors.white};
color: ${({ theme }) => theme.colors.grey4};
`,
primaryDisabled: css`
${buttonDefaultCSS.basicCss};
background: ${({ theme }) => theme.colors.grey7};
color: ${({ theme }) => theme.colors.white};
color: ${({ theme }) => theme.colors.grey4};
`,
secondaryActive: css`
${buttonDefaultCSS.basicCss};
@@ -99,6 +99,11 @@ const buttonCSS = {
background-color: transparent;
color: ${({ theme }) => theme.colors.grey6};
`,
quaternaryDisabled: css`
${buttonDefaultCSS.basicCss};
background: ${({ theme }) => theme.colors.grey7};
color: ${({ theme }) => theme.colors.grey2};
`,
};

const ButtonWrapper = styled.button<{ $type: string }>`
@@ -126,6 +131,8 @@ const ButtonWrapper = styled.button<{ $type: string }>`
return buttonCSS.tertiaryDisabled;
case 'halfPrimaryDisabled':
return buttonCSS.halfPrimaryDisabled;
case 'quaternaryDisabled':
return buttonCSS.quaternaryDisabled;
default:
return '';
}
3 changes: 3 additions & 0 deletions src/components/atomComponents/PasswordInput.tsx
Original file line number Diff line number Diff line change
@@ -86,6 +86,9 @@ const StyledPasswordInput = styled.input<{ $iserror: boolean }>`

color: ${({ theme }) => theme.colors.white};
font-size: ${({ theme }) => theme.fonts.body3};
&::placeholder {
color: ${({ theme }) => theme.colors.grey4};
}

&:focus {
border: 2px solid ${({ $iserror, theme }) => ($iserror ? theme.colors.red : theme.colors.main1)};
3 changes: 3 additions & 0 deletions src/components/atomComponents/TextInput.tsx
Original file line number Diff line number Diff line change
@@ -84,6 +84,9 @@ const StyledTextInput = styled.input<{ $iserror: boolean }>`
font-size: ${({ theme }) => theme.fonts.body3};

caret-color: ${({ theme }) => theme.colors.main1};
&::placeholder{
color:${({theme})=>theme.colors.grey4}
}

&:focus {
outline: none;
2 changes: 1 addition & 1 deletion src/pages/LoginEntrance/components/HostComponent.tsx
Original file line number Diff line number Diff line change
@@ -110,7 +110,7 @@ function HostComponent({ hostInfo, setHostInfo }: HostProps) {
<StyledBtnSection>
<Button
typeState={
hostInfo.name && hostInfo.password.length >= 4 ? 'primaryActive' : 'secondaryDisabled'
hostInfo.name && hostInfo.password.length >= 4 ? 'primaryActive' : 'primaryDisabled'
}
onClick={hostInfo.name && hostInfo.password.length >= 4 ? loginHost : undefined}
>
79 changes: 66 additions & 13 deletions src/pages/SteppingStone/components/SteppingBtnSection.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { userNameAtom } from 'atoms/atom';
import { useEffect, useState } from 'react';

import Button from 'components/atomComponents/Button';
import Text from 'components/atomComponents/Text';
import CopyToClipboard from 'react-copy-to-clipboard';
import { useParams } from 'react-router';
import { Link, useLocation } from 'react-router-dom';
import { useRecoilValue } from 'recoil';
import styled from 'styled-components/macro';
import { theme } from 'styles/theme';
import { notify } from 'utils/toast/copyLink';
import ToastContainerBox from 'utils/toast/ToastContainer';

interface SteppingProps {
steppingType: string;
@@ -17,23 +17,37 @@ function SteppingBtnSection({ steppingType }: SteppingProps) {
const location = useLocation();
const meetInfo = { ...location.state };
const { meetingId } = useParams();
console.log(meetingId);
const [isModalOpen, setIsModalOpen] = useState(false);

useEffect(()=>{
setIsModalOpen(true);
},[])

return (
<>
{/* <ToastContainerBox /> */}
<StyledBtnSection>
{
{
meetComplete: (
<>
{/* 이후 도메인 시 연결 */}
<CopyToClipboard text={`${import.meta.env.VITE_WEB_IP}/meet/${meetInfo.meetingId}`}>
<Button typeState={'halfTertiaryActive'} onClick={notify}>
<Text font={'button2'}>링크 복사하기</Text>
</Button>
</CopyToClipboard>
<BottomSheetModal $isModalOpen={isModalOpen}>
<BottomSheetDescription>
<Text font={'head2'} color={'white'}>회의방 링크가 생성되었어요!</Text>
<Text font={'title2'} color={`${theme.colors.grey4}`}>링크를 복사하여 팀원에게 공유해주세요</Text>
</BottomSheetDescription>
<CopyToClipboard text={`${import.meta.env.VITE_WEB_IP}/meet/${meetInfo.meetingId}`}>
<Button typeState={'primaryActive'} onClick={()=>setIsModalOpen(false)}>
<Text font={'button2'}>링크 복사하기</Text>
</Button>
</CopyToClipboard>
<Button typeState={'quaternaryDisabled'} onClick={()=>setIsModalOpen(false)}>
<Text font={'button2'}>나중에 공유하기</Text>
</Button>
</BottomSheetModal>
<ModalOverlay $isModalOpen={isModalOpen} >
</ModalOverlay>
<Link to={`/host/schedule/${meetInfo.meetingId}`}>
<Button typeState={'halfPrimaryActive'}>
<Button typeState={'primaryActive'}>
<Text font={'button2'}>나의 가능시간 입력</Text>
</Button>
</Link>
@@ -48,7 +62,6 @@ function SteppingBtnSection({ steppingType }: SteppingProps) {
</Link>
<CopyToClipboard
text={`${import.meta.env.VITE_WEB_IP}/meet/${meetingId}`}
// onCopy={handleCopy}
>
<Button typeState={'halfPrimaryActive'} onClick={notify}>
<Text font={'button2'}>링크 복사하기</Text>
@@ -97,4 +110,44 @@ const StyledBtnSection = styled.section`
justify-content: center;
border-radius: 50%;
width: 100%;

`;

const BottomSheetModal = styled.div<{$isModalOpen:boolean;}>`
display:flex;
position:fixed;
bottom:${({$isModalOpen})=>$isModalOpen?0:-27.5}rem;
flex-direction:column;
gap:0.8rem;
transition: bottom 600ms cubic-bezier(0.86, 0, 0.07, 1);
z-index:1;
border-top-left-radius: 1.2rem;
border-top-right-radius: 1.2rem;
background-color: ${({ theme }) => theme.colors.grey8};

padding: 2.8rem 2rem 4rem;
width:100%;

& button {
width:100%;
}

`

const ModalOverlay = styled.div<{$isModalOpen:boolean;}>`
display:${({$isModalOpen})=>($isModalOpen?'block':'none')};
position:fixed;
top: 0;

background-color: rgba(0, 0, 0, 0.50);
width:100%;
height:100%;
`

const BottomSheetDescription = styled.div`
display:flex;
flex-direction:column;
gap:0.8rem;
margin-bottom:2.4rem;
padding-left:0.9rem;
`
8 changes: 4 additions & 4 deletions src/pages/createMeeting/components/useFunnel/SetDates.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// import { useState } from 'react';

import './SetDates.css';

import { methodStateAtom } from 'atoms/atom';
import Button from 'components/atomComponents/Button';
import Text from 'components/atomComponents/Text';
import { MeetingInfo, FunnelProps } from 'pages/createMeeting/types/useFunnelInterface';
import { FunnelProps, MeetingInfo } from 'pages/createMeeting/types/useFunnelInterface';
import { Calendar, DateObject, getAllDatesInRange } from 'react-multi-date-picker';
import { useRecoilState } from 'recoil';
import styled from 'styled-components/macro';

import './SetDates.css';

const months = [
'1월',
'2월',
@@ -125,7 +125,7 @@ function SetDates({ meetingInfo, setMeetingInfo, setStep }: FunnelProps) {
meetingInfo.availableDates.length > 0 &&
meetingInfo.availableDates.length < 8)
? 'primaryActive'
: 'secondaryDisabled'
: 'primaryDisabled'
}
onClick={
(meetingInfo.availableDates.length > 1 && meetingInfo.availableDates.length < 8) ||
8 changes: 3 additions & 5 deletions src/pages/createMeeting/components/useFunnel/SetDuration.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Button from 'components/atomComponents/Button';
import Text from 'components/atomComponents/Text';
import { durationType } from 'pages/createMeeting/data/meetingInfoData';
import { MeetingInfo, FunnelProps } from 'pages/createMeeting/types/useFunnelInterface';
import { FunnelProps, MeetingInfo } from 'pages/createMeeting/types/useFunnelInterface';
import styled from 'styled-components/macro';

function SetDuration({ meetingInfo, setMeetingInfo, setStep }: FunnelProps) {
@@ -13,9 +13,7 @@ function SetDuration({ meetingInfo, setMeetingInfo, setStep }: FunnelProps) {
<Button
key={i + duration.enum}
typeState={
meetingInfo.duration === duration.enum
? `halfPrimaryActive`
: `halfsecondaryDisabled`
meetingInfo.duration === duration.enum ? `halfPrimaryActive` : `halfPrimaryDisabled`
}
onClick={() => {
setMeetingInfo((prev: MeetingInfo) => {
@@ -30,7 +28,7 @@ function SetDuration({ meetingInfo, setMeetingInfo, setStep }: FunnelProps) {
</DurationWrapper>
<StyledBtnWrapper>
<Button
typeState={meetingInfo.duration ? 'primaryActive' : 'secondaryDisabled'}
typeState={meetingInfo.duration ? 'primaryActive' : 'primaryDisabled'}
onClick={
meetingInfo.duration
? () =>
4 changes: 2 additions & 2 deletions src/pages/createMeeting/components/useFunnel/SetHostInfo.tsx
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ import Button from 'components/atomComponents/Button';
import PasswordInput from 'components/atomComponents/PasswordInput';
import Text from 'components/atomComponents/Text';
import TextInput from 'components/atomComponents/TextInput';
import { MeetingInfo, FunnelProps } from 'pages/createMeeting/types/useFunnelInterface';
import { FunnelProps, MeetingInfo } from 'pages/createMeeting/types/useFunnelInterface';
import styled from 'styled-components/macro';
import { theme } from 'styles/theme';

@@ -75,7 +75,7 @@ function SetHostInfo({ meetingInfo, setMeetingInfo, setStep }: FunnelProps) {
typeState={
meetingInfo.name && meetingInfo.password.length >= 4
? 'primaryActive'
: 'secondaryDisabled'
: 'primaryDisabled'
}
onClick={
meetingInfo.name && meetingInfo.password.length >= 4
4 changes: 2 additions & 2 deletions src/pages/createMeeting/components/useFunnel/SetPlace.tsx
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ function SetPlace({ meetingInfo, setMeetingInfo, setStep }: FunnelProps) {
return (
<PlaceSection key={i + type}>
<Button
typeState={meetingInfo.place === type ? 'primaryActive' : 'secondaryDisabled'}
typeState={meetingInfo.place === type ? 'primaryActive' : 'primaryDisabled'}
onClick={() => setPlaceDetail(type)}
>
<Text font={'button2'}>
@@ -41,7 +41,7 @@ function SetPlace({ meetingInfo, setMeetingInfo, setStep }: FunnelProps) {
</PlaceInfoSection>
<StyledBtnSection>
<Button
typeState={meetingInfo.place ? 'primaryActive' : 'secondaryDisabled'}
typeState={meetingInfo.place ? 'primaryActive' : 'primaryDisabled'}
onClick={
meetingInfo.place
? () =>
14 changes: 10 additions & 4 deletions src/pages/createMeeting/components/useFunnel/SetTimes.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useState, useEffect } from 'react';
import { useEffect, useState } from 'react';

import Button from 'components/atomComponents/Button';
import Text from 'components/atomComponents/Text';
import { DropUpIc, DropDownIc, Wave } from 'components/Icon/icon';
import { preferTimeType, directInputButton } from 'pages/createMeeting/data/meetingInfoData';
import { DropDownIc, DropUpIc, Wave } from 'components/Icon/icon';
import { directInputButton, preferTimeType } from 'pages/createMeeting/data/meetingInfoData';
import { FunnelProps, PreferTimeInfo } from 'pages/createMeeting/types/useFunnelInterface';
import styled from 'styled-components/macro';

@@ -180,7 +180,13 @@ function SetTimes({ meetingInfo, setMeetingInfo, setStep }: FunnelProps) {

<StyledBtnSection>
<Button
typeState={buttonStateHandler() ? 'primaryActive' : 'secondaryDisabled'}
typeState={
meetingInfo.preferTimes.length >= 1 &&
meetingInfo.preferTimes[0].startTime &&
meetingInfo.preferTimes[0].endTime !== '00:00'
? 'primaryActive'
: 'primaryDisabled'
}
onClick={
buttonStateHandler()
? () => {
6 changes: 2 additions & 4 deletions src/pages/createMeeting/components/useFunnel/SetTitle.tsx
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ import React from 'react';
import Button from 'components/atomComponents/Button';
import Text from 'components/atomComponents/Text';
import TextInput from 'components/atomComponents/TextInput';
import { MeetingInfo, FunnelProps } from 'pages/createMeeting/types/useFunnelInterface';
import { FunnelProps, MeetingInfo } from 'pages/createMeeting/types/useFunnelInterface';
import styled from 'styled-components/macro';

function SetTitle({ meetingInfo, setMeetingInfo, setStep }: FunnelProps) {
@@ -29,9 +29,7 @@ function SetTitle({ meetingInfo, setMeetingInfo, setStep }: FunnelProps) {
<StyledBtnSection>
<Button
typeState={
meetingInfo.title && meetingInfo.title.length < 16
? 'primaryActive'
: 'secondaryDisabled'
meetingInfo.title && meetingInfo.title.length < 16 ? 'primaryActive' : 'primaryDisabled'
}
onClick={
meetingInfo.title && meetingInfo.title.length < 16
Loading