Skip to content

Commit 9bb76ba

Browse files
authored
Merge pull request #87 from SWM-FIRE/FIRE-392-fe-방-생성하는-ui-제작
Fire 392 fe 방 생성하는 UI 제작
2 parents 9d6bb00 + fa87a3b commit 9bb76ba

File tree

12 files changed

+36525
-4
lines changed

12 files changed

+36525
-4
lines changed

src/App.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Room from './pages/Room';
77
import Ready from './pages/Ready';
88
import LandingPage from './pages/LandingPage';
99
import Main from './pages/Main';
10+
import Test from './pages/Test';
1011

1112
const queryClient = new QueryClient();
1213

@@ -27,6 +28,7 @@ function App() {
2728
<Route path="/ready">
2829
<Route path=":roomId" element={<Ready />} />
2930
</Route>
31+
<Route path="/test" element={<Test />} />
3032
</Routes>
3133
</BrowserRouter>
3234
</QueryClientProvider>

src/assets/img/theme/Fire.png

1.57 MB
Loading

src/assets/theme/camping.json

+33,384-1
Large diffs are not rendered by default.

src/assets/theme/cosmos.gif

1.17 MB
Loading

src/assets/theme/ocean.json

+2,824-1
Large diffs are not rendered by default.

src/components/main/CreateRoom.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import React from 'react';
22
import styled from 'styled-components';
3+
import modal from '../../stores/createRoomModalStore';
34

45
export default function CreateRoom() {
6+
const { openModal } = modal();
7+
58
return (
69
<Container>
710
<DetailContainer>
811
<Title>새로 방 생성</Title>
912
<Detail>우리모두 모여서 도란도란 코딩해요.</Detail>
1013
</DetailContainer>
11-
<Enter>방 만들기 →</Enter>
14+
<Enter onClick={openModal}>방 만들기 →</Enter>
1215
</Container>
1316
);
1417
}
+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import styled from 'styled-components';
2+
3+
export default function CreateRoomForm() {
4+
return (
5+
<Form>
6+
<Section>
7+
<Label htmlFor="name">방 이름*</Label>
8+
<Input id="name" type="text" placeholder="방 이름을 입력해주세요." />
9+
</Section>
10+
<Section>
11+
<Label htmlFor="description">설명*</Label>
12+
<Input
13+
id="description"
14+
type="text"
15+
placeholder="설명을 입력해주세요."
16+
/>
17+
</Section>
18+
<Section>
19+
<Label htmlFor="tag">태그*</Label>
20+
<Input
21+
id="tag"
22+
type="text"
23+
placeholder="태그 입력후 Enter를 눌러주세요."
24+
/>
25+
<Tags />
26+
</Section>
27+
<Section>
28+
<Label htmlFor="max">최대 인원 수*</Label>
29+
<Select id="max" placeholder="최대 인원 수를 선택해주세요.">
30+
<option value="1">1</option>
31+
<option value="2">2</option>
32+
<option value="3">3</option>
33+
<option value="4">4</option>
34+
</Select>
35+
</Section>
36+
<Section>
37+
<Label htmlFor="theme">테마*</Label>
38+
<Select id="theme" placeholder="테마를 선택해주세요.">
39+
<option value="theme1">모닥불</option>
40+
<option value="theme2">바다</option>
41+
<option value="theme3">캠핑</option>
42+
<option value="theme4">여행</option>
43+
<option value="theme5">우주인</option>
44+
</Select>
45+
</Section>
46+
<Submit>방 생성하기</Submit>
47+
</Form>
48+
);
49+
}
50+
51+
const Form = styled.form`
52+
display: flex;
53+
flex-direction: column;
54+
align-items: flex-start;
55+
width: 100%;
56+
margin-top: 1.5rem;
57+
color: #b0b8c1;
58+
font-size: 1.4rem;
59+
font-family: IBMPlexSansKRRegular, Arial;
60+
`;
61+
62+
const Section = styled.div`
63+
display: flex;
64+
flex-direction: column;
65+
align-items: center;
66+
margin-top: 1.5rem;
67+
width: 100%;
68+
`;
69+
70+
const Label = styled.label`
71+
width: 100%;
72+
`;
73+
74+
const Input = styled.input`
75+
height: 4.9rem;
76+
width: 100%;
77+
margin-top: 0.25rem;
78+
background: transparent;
79+
outline: none;
80+
color: #f9fafb;
81+
font-size: 1.5rem;
82+
background-color: #080909;
83+
border-radius: 0.6rem;
84+
padding: 0 1.6rem;
85+
`;
86+
87+
const Tags = styled.div``;
88+
89+
const Select = styled.select`
90+
width: 100%;
91+
height: 4.9rem;
92+
margin-top: 0.25rem;
93+
background: transparent;
94+
outline: none;
95+
border: none;
96+
color: #f9fafb;
97+
font-size: 1.5rem;
98+
background-color: #080909;
99+
border-radius: 0.6rem;
100+
padding: 0 1.6rem;
101+
`;
102+
103+
const Submit = styled.button`
104+
color: #111827;
105+
border-radius: 1rem;
106+
height: 5.5rem;
107+
width: 100%;
108+
font-size: 1.5rem;
109+
font-family: IBMPlexSansKRRegular, Arial;
110+
background-color: #f3f4f6;
111+
margin-top: 7.85rem;
112+
cursor: pointer;
113+
`;
+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import React from 'react';
2+
import styled from 'styled-components';
3+
import { ReactComponent as X } from '../../assets/svg/X.svg';
4+
import modal from '../../stores/createRoomModalStore';
5+
6+
export default function ScreenModal({ children }) {
7+
const { closeModal } = modal();
8+
return (
9+
<ModalBackground onClick={closeModal}>
10+
<ModalBox onClick={(e) => e.stopPropagation()}>
11+
<ModalController>
12+
<Title>방 생성하기</Title>
13+
<Close onClick={closeModal}>
14+
<X />
15+
</Close>
16+
</ModalController>
17+
{children}
18+
</ModalBox>
19+
</ModalBackground>
20+
);
21+
}
22+
23+
const ModalController = styled.div`
24+
svg {
25+
height: 100%;
26+
width: 3.2rem;
27+
}
28+
height: 3.2rem;
29+
width: 100%;
30+
display: flex;
31+
align-items: center;
32+
justify-content: space-between;
33+
`;
34+
35+
const Title = styled.h1`
36+
font-size: 2.4rem;
37+
font-family: IBMPlexMonoRegular;
38+
color: #f9fafb;
39+
`;
40+
41+
const Close = styled.div`
42+
cursor: pointer;
43+
svg {
44+
height: 100%;
45+
width: 3.2rem;
46+
}
47+
`;
48+
49+
const ModalBackground = styled.div`
50+
position: fixed;
51+
width: 100%;
52+
height: 100%;
53+
background-color: rgba(0, 0, 0, 0.7);
54+
justify-content: center;
55+
align-items: center;
56+
top: 0;
57+
display: flex;
58+
z-index: 999;
59+
`;
60+
61+
const ModalBox = styled.div`
62+
position: fixed;
63+
background-color: #23262f;
64+
border-radius: 2rem;
65+
display: flex;
66+
width: 60.8rem;
67+
flex-direction: column;
68+
justify-content: center;
69+
align-items: center;
70+
top: 16rem;
71+
padding: 3.2rem;
72+
`;

src/components/main/Header.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export default function Header({ modalHandler }: { modalHandler: () => void }) {
1010
const clickLogo = () => {
1111
navigate('/#/');
1212
};
13+
1314
return (
1415
<Container>
1516
<Logo onClick={clickLogo}>modoco</Logo>

src/pages/Main.tsx

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
1-
import { useState } from 'react';
1+
import { useState, useEffect } from 'react';
22
import styled from 'styled-components';
33
import RoomCards from '../components/main/RoomCards';
44
import Header from '../components/main/Header';
55
import MainTitle from '../components/main/MainTitle';
66
import Modal from '../components/layout/Modal';
77
import LoginModal from '../components/login/LoginModal';
88
import useSetSelf from '../hooks/useSetSelf';
9+
import UserStore from '../stores/userStore';
10+
import ModalStore from '../stores/createRoomModalStore';
11+
import CreateRoomModal from '../components/main/CreateRoomModal';
12+
import CreateRoomForm from '../components/main/CreateRoomForm';
913

1014
export default function Main() {
1115
const [isModal, setIsModal] = useState(false);
16+
const { setNickname, uid, setUid, setAvatar } = UserStore();
17+
const { isOpenCreateRoomModal } = ModalStore();
18+
19+
useEffect(() => {
20+
if (localStorage.getItem('uid')) {
21+
console.log('existing user', uid);
22+
setNickname(localStorage.getItem('nickname'));
23+
setUid(localStorage.getItem('uid'));
24+
setAvatar(localStorage.getItem('avatar'));
25+
}
26+
}, []);
1227

1328
useSetSelf();
1429
const closeModalHandler = () => {
@@ -30,6 +45,11 @@ export default function Main() {
3045
<LoginModal modalHandler={closeModalHandler} />
3146
</Modal>
3247
)}
48+
{isOpenCreateRoomModal && (
49+
<CreateRoomModal>
50+
<CreateRoomForm />
51+
</CreateRoomModal>
52+
)}
3353
</>
3454
);
3555
}

src/pages/Test.tsx

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import styled from 'styled-components';
2+
import { useEffect, useRef } from 'react';
3+
import Lottie from 'lottie-web';
4+
import FireJson from '../assets/theme/fire.json';
5+
import OceanJson from '../assets/theme/ocean.json';
6+
import CosmosJson from '../assets/theme/cosmos.json';
7+
import CampingJson from '../assets/theme/camping.json';
8+
9+
export default function Test() {
10+
const fireRef = useRef<HTMLDivElement>(null);
11+
const oceanRef = useRef<HTMLDivElement>(null);
12+
const cosmosRef = useRef<HTMLDivElement>(null);
13+
const campingRef = useRef<HTMLDivElement>(null);
14+
15+
useEffect(() => {
16+
Lottie.loadAnimation({
17+
container: fireRef.current,
18+
renderer: 'svg',
19+
loop: true,
20+
autoplay: true,
21+
animationData: FireJson,
22+
});
23+
Lottie.loadAnimation({
24+
container: oceanRef.current,
25+
renderer: 'svg',
26+
loop: true,
27+
autoplay: true,
28+
animationData: OceanJson,
29+
});
30+
Lottie.loadAnimation({
31+
container: cosmosRef.current,
32+
renderer: 'svg',
33+
loop: true,
34+
autoplay: true,
35+
animationData: CosmosJson,
36+
});
37+
Lottie.loadAnimation({
38+
container: campingRef.current,
39+
renderer: 'svg',
40+
loop: true,
41+
autoplay: true,
42+
animationData: CampingJson,
43+
});
44+
}, []);
45+
return (
46+
<Container>
47+
<Image>
48+
<File ref={oceanRef} />
49+
</Image>
50+
<Image>
51+
<Camp ref={campingRef} />
52+
</Image>
53+
<Image>
54+
<Cosmos ref={cosmosRef} />
55+
</Image>
56+
<Image>
57+
<File ref={fireRef} />
58+
</Image>
59+
</Container>
60+
);
61+
}
62+
63+
const Cosmos = styled.div`
64+
position: absolute;
65+
top: -10%;
66+
left: -45%;
67+
width: 200%;
68+
`;
69+
70+
const Camp = styled.div`
71+
position: absolute;
72+
top: -6%;
73+
left: -22%;
74+
width: 145%;
75+
`;
76+
77+
const File = styled.div`
78+
width: 100%;
79+
`;
80+
81+
const Image = styled.div`
82+
width: 20rem; // change image size
83+
background-color: gray;
84+
position: relative;
85+
`;
86+
87+
const Container = styled.div`
88+
display: flex;
89+
gap: 1rem;
90+
`;

src/stores/createRoomModalStore.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import create from 'zustand';
2+
3+
interface Modal {
4+
isOpenCreateRoomModal: boolean;
5+
closeModal: () => void;
6+
openModal: () => void;
7+
}
8+
const ModalStore = create<Modal>((set) => ({
9+
isOpenCreateRoomModal: false,
10+
closeModal: () => set(() => ({ isOpenCreateRoomModal: false })),
11+
openModal: () => set(() => ({ isOpenCreateRoomModal: true })),
12+
}));
13+
14+
export default ModalStore;

0 commit comments

Comments
 (0)