Skip to content

Commit 0083e62

Browse files
authored
develop -> main
기본 구조 UI 테스트 배포
2 parents 078e7a3 + ee80b4f commit 0083e62

File tree

6 files changed

+445
-6
lines changed

6 files changed

+445
-6
lines changed

src/pages/town/EditTownModal.jsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { useState } from "react";
2+
import * as S from "./EditTownModal.styled";
3+
4+
const EditTownModal = ({ onClose }) => {
5+
const [type] = useState("town");
6+
7+
return (
8+
<S.Overlay>
9+
<S.Modal>
10+
<S.Header>
11+
<span>동네 수정</span>
12+
<button onClick={onClose}></button>
13+
</S.Header>
14+
15+
{type === "area" && (
16+
<S.Field>
17+
<label>지역 이름 *</label>
18+
<input defaultValue="서울" />
19+
</S.Field>
20+
)}
21+
22+
{type === "town" && (
23+
<>
24+
<S.Field>
25+
<label>동네 이름 *</label>
26+
<input defaultValue="망원" />
27+
</S.Field>
28+
29+
<S.Field>
30+
<label>지역 *</label>
31+
<select defaultValue="서울">
32+
<option>서울</option>
33+
</select>
34+
</S.Field>
35+
</>
36+
)}
37+
38+
<S.Footer>
39+
<S.Cancel onClick={onClose}>취소</S.Cancel>
40+
<S.Delete>삭제</S.Delete>
41+
<S.Save>저장</S.Save>
42+
</S.Footer>
43+
</S.Modal>
44+
</S.Overlay>
45+
);
46+
};
47+
48+
export default EditTownModal;
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import styled from "styled-components";
2+
3+
export const Overlay = styled.div`
4+
position: fixed;
5+
inset: 0;
6+
background: rgba(0, 0, 0, 0.7);
7+
display: flex;
8+
justify-content: center;
9+
align-items: center;
10+
z-index: 1000;
11+
`;
12+
13+
export const Modal = styled.div`
14+
width: 420px;
15+
background: #fff;
16+
border-radius: 8px;
17+
padding: 20px;
18+
`;
19+
20+
export const Header = styled.div`
21+
display: flex;
22+
justify-content: space-between;
23+
align-items: center;
24+
font-weight: 600;
25+
margin-bottom: 20px;
26+
27+
button {
28+
background: none;
29+
border: none;
30+
cursor: pointer;
31+
}
32+
`;
33+
34+
export const Field = styled.div`
35+
display: flex;
36+
flex-direction: column;
37+
gap: 6px;
38+
margin-bottom: 16px;
39+
40+
label {
41+
font-size: 14px;
42+
font-weight: 500;
43+
}
44+
45+
input,
46+
select {
47+
height: 36px;
48+
padding: 0 10px;
49+
border: 1px solid #d1d5db;
50+
border-radius: 4px;
51+
}
52+
`;
53+
54+
export const RadioGroup = styled.div`
55+
display: flex;
56+
align-items: center;
57+
gap: 16px;
58+
`;
59+
60+
export const Radio = styled.div`
61+
display: flex;
62+
align-items: center;
63+
justify-content: center;
64+
gap: 5px;
65+
`
66+
67+
export const Footer = styled.div`
68+
display: flex;
69+
justify-content: flex-end;
70+
gap: 10px;
71+
margin-top: 20px;
72+
`;
73+
74+
export const Cancel = styled.button`
75+
padding: 8px 14px;
76+
background: #fff;
77+
border: 1px solid #d1d5db;
78+
border-radius: 4px;
79+
cursor: pointer;
80+
`;
81+
82+
export const Save = styled.button`
83+
padding: 8px 14px;
84+
background: #111827;
85+
color: #fff;
86+
border-radius: 4px;
87+
border: none;
88+
cursor: pointer;
89+
`;
90+
91+
export const Delete = styled.button`
92+
padding: 8px 14px;
93+
background: #ef4444;
94+
color: #fff;
95+
border-radius: 4px;
96+
border: none;
97+
cursor: pointer;
98+
`;

src/pages/town/Town.jsx

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,51 @@
1+
import { useState } from "react";
12
import * as S from "./Town.styled";
3+
import TownModal from "./TownModal";
4+
import EditTownModal from "./EditTownModal";
25

36
const Town = () => {
7+
const [isOpen, setIsOpen] = useState(false);
8+
const [isEditOpen, setIsEditOpen] = useState(false);
9+
410
return (
5-
<S.Wrapper>
6-
<h2>동네 관리</h2>
7-
<button>+ 동네 추가</button>
8-
<div>테이블 영역</div>
9-
</S.Wrapper>
11+
<>
12+
<S.Wrapper>
13+
<S.Title>동네 관리</S.Title>
14+
<S.Container>
15+
<S.Header>
16+
<S.AddBtn onClick={() => setIsOpen(true)}>
17+
<span>+</span>
18+
동네 추가
19+
</S.AddBtn>
20+
</S.Header>
21+
<S.Table>
22+
<S.TableHeader>
23+
<span>번호</span>
24+
<span>동네 이름</span>
25+
<span>지역</span>
26+
<span>활성화</span>
27+
<span>수정</span>
28+
</S.TableHeader>
29+
<S.TableRow>
30+
<span>1</span>
31+
<span>서울</span>
32+
<span>-</span>
33+
<S.Toggle />
34+
<S.EditBtn onClick={() => setIsEditOpen(true)}></S.EditBtn>
35+
</S.TableRow>
36+
<S.TableRow>
37+
<span>2</span>
38+
<span>망원</span>
39+
<span>서울</span>
40+
<S.Toggle />
41+
<S.EditBtn onClick={() => setIsEditOpen(true)}></S.EditBtn>
42+
</S.TableRow>
43+
</S.Table>
44+
</S.Container>
45+
</S.Wrapper>
46+
{isOpen && <TownModal onClose={() => setIsOpen(false)} />}
47+
{isEditOpen && <EditTownModal onClose={() => setIsEditOpen(false)} />}
48+
</>
1049
);
1150
};
1251

src/pages/town/Town.styled.js

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,108 @@ import styled from "styled-components";
33
export const Wrapper = styled.div`
44
display: flex;
55
flex-direction: column;
6-
align-items: center;
6+
justify-content: flex-start;
77
width: 100vw;
8+
height: 95vh;
9+
margin-top: 5vh;
810
background-color: ${({ theme}) => theme.colors.white};
11+
`;
12+
13+
export const Title = styled.span`
14+
font-size: 30px;
15+
font-weight: 500;
16+
margin-bottom: 3%;
17+
`;
18+
19+
export const Container = styled.div`
20+
display: flex;
21+
flex-direction: column;
22+
gap: 16px;
23+
width: 80%;
24+
padding: 2%;
25+
border: 3px solid gray;
26+
border-radius: 10px;
27+
`;
28+
29+
export const Header = styled.div`
30+
display: flex;
31+
justify-content: flex-start;
32+
`;
33+
34+
export const AddBtn = styled.button`
35+
display: flex;
36+
align-items: center;
37+
gap: 6px;
38+
39+
padding: 10px 20px;
40+
font-size: 20px;
41+
font-weight: 500;
42+
color: #fff;
43+
44+
background-color: ${({ theme }) => theme.colors.black};
45+
border-radius: 6px;
46+
border: none;
47+
cursor: pointer;
48+
`;
49+
50+
export const Table = styled.div`
51+
width: 100%;
52+
border: 1px solid #e5e7eb;
53+
border-radius: 8px;
54+
overflow: hidden;
55+
`;
56+
57+
export const TableHeader = styled.div`
58+
display: grid;
59+
align-items: center;
60+
justify-items: center;
61+
grid-template-columns: 10% 30% 30% 15% 15%;
62+
padding: 12px;
63+
font-weight: 600;
64+
background-color: #f9fafb;
65+
border-bottom: 1px solid #e5e7eb;
66+
`;
67+
68+
export const TableRow = styled.div`
69+
display: grid;
70+
align-items: center;
71+
justify-items: center;
72+
grid-template-columns: 10% 30% 30% 15% 15%;
73+
74+
padding: 12px;
75+
align-items: center;
76+
border-bottom: 1px solid #e5e7eb;
77+
78+
&:last-child {
79+
border-bottom: none;
80+
}
81+
`;
82+
83+
export const Toggle = styled.div`
84+
width: 36px;
85+
height: 20px;
86+
border-radius: 10px;
87+
background-color: #111827;
88+
position: relative;
89+
cursor: pointer;
90+
91+
&::after {
92+
content: "";
93+
position: absolute;
94+
top: 2px;
95+
left: 18px;
96+
width: 16px;
97+
height: 16px;
98+
background-color: white;
99+
border-radius: 50%;
100+
}
101+
`;
102+
103+
export const EditBtn = styled.button`
104+
display: flex;
105+
justify-content: left;
106+
background: none;
107+
border: none;
108+
cursor: pointer;
109+
font-size: 20px;
9110
`;

src/pages/town/TownModal.jsx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { useState } from "react";
2+
import * as S from "./TownModal.styled";
3+
4+
const TownModal = ({ onClose }) => {
5+
const [type, setType] = useState("area");
6+
7+
return (
8+
<S.Overlay>
9+
<S.Modal>
10+
<S.Header>
11+
<span>동네 추가</span>
12+
<button onClick={onClose}></button>
13+
</S.Header>
14+
15+
<S.Field>
16+
<label>동네 유형 *</label>
17+
<S.RadioGroup>
18+
<S.Radio>
19+
<input
20+
type="radio"
21+
name="type"
22+
value="area"
23+
checked={type === "area"}
24+
onChange={() => setType("area")}
25+
/>
26+
<span>지역</span>
27+
</S.Radio>
28+
<S.Radio>
29+
<input
30+
type="radio"
31+
name="type"
32+
value="town"
33+
checked={type === "town"}
34+
onChange={() => setType("town")}
35+
/>
36+
<span>동네</span>
37+
</S.Radio>
38+
</S.RadioGroup>
39+
</S.Field>
40+
41+
<S.Field>
42+
<label>지역 *</label>
43+
<select>
44+
<option>지역 선택</option>
45+
</select>
46+
</S.Field>
47+
48+
{type === "town" && (
49+
<S.Field>
50+
<label>동네 이름 *</label>
51+
<input placeholder="망원" />
52+
</S.Field>
53+
)}
54+
55+
<S.Footer>
56+
<S.Cancel onClick={onClose}>취소</S.Cancel>
57+
<S.Save>저장</S.Save>
58+
</S.Footer>
59+
</S.Modal>
60+
</S.Overlay>
61+
);
62+
};
63+
64+
export default TownModal;

0 commit comments

Comments
 (0)