1
1
import React , { useRef , useCallback } from 'react' ;
2
- import styled , { css } from 'styled-components' ;
2
+ import styled from 'styled-components' ;
3
+ import { SearchIcon2 } from '../../static/svg' ;
3
4
import RoundButton from '../common/RoundButton' ;
4
- import { CurrentUser } from '../../lib/graphql/user' ;
5
+ import MainResponsive from '../main/MainResponsive' ;
6
+ import useHeader from './hooks/useHeader' ;
5
7
import HeaderUserIcon from './HeaderUserIcon' ;
6
8
import useToggle from '../../lib/hooks/useToggle' ;
7
9
import HeaderUserMenu from './HeaderUserMenu' ;
8
- import { logout } from '../../lib/api/auth' ;
9
- import storage from '../../lib/storage' ;
10
- import { UserLogo } from '../../modules/header' ;
11
- import HeaderLogo from './HeaderLogo' ;
12
- import media from '../../lib/styles/media' ;
13
- import { SearchIcon2 } from '../../static/svg' ;
14
10
import { Link } from 'react-router-dom' ;
15
- import MainResponsive from '../main/MainResponsive' ;
16
-
17
- const HeaderBlock = styled . div < { floating : boolean } > `
18
- width: 100%;
19
- .wrapper {
20
- /* width: 1200px; */
21
- width: 100%;
22
- height: 4rem;
23
- /* padding-left: 1rem;
24
- padding-right: 1rem; */
25
- display: flex;
26
- justify-content: space-between;
27
- align-items: center;
28
-
29
- .search {
30
- display: none;
31
- margin-right: 1rem;
32
- }
33
-
34
- .right {
35
- display: flex;
36
- align-items: center;
37
- }
38
-
39
- ${ media . large } {
40
- /* width: 1024px; */
41
- }
42
- ${ media . medium } {
43
- /* width: 100%; */
44
- .write-button {
45
- display: none;
46
- }
47
- .search {
48
- display: block;
49
- }
50
- }
51
- ${ media . small } {
52
- height: 3.5rem;
53
-
54
- .login-button {
55
- font-size: 0.875rem;
56
- padding-left: 0.75rem;
57
- padding-right: 0.75rem;
58
- }
59
- }
60
-
61
- .logged-in {
62
- position: relative;
63
- display: flex;
64
- align-items: center;
65
- }
66
- }
67
-
68
- ${ props =>
69
- props . floating &&
70
- css `
71
- z-index: 10;
72
- position: fixed;
73
- top: 0;
74
- background: rgba(255, 255, 255, 1);
75
- box-shadow: 0px 0 8px rgba(0, 0, 0, 0.08);
76
- ` }
77
- ` ;
78
-
79
- const Placeholder = styled . div `
80
- width: 100%;
81
- height: 5rem;
82
- ${ media . small } {
83
- height: 3.5rem;
84
- }
85
- ` ;
11
+ import media from '../../lib/styles/media' ;
12
+ import HeaderLogo from './HeaderLogo' ;
86
13
87
- interface HeaderProps {
88
- floating : boolean ;
89
- floatingMargin : number ;
90
- onLoginClick : ( ) => void ;
91
- user : CurrentUser | null ;
92
- custom : boolean ;
93
- userLogo : UserLogo | null ;
94
- velogUsername : string | null ;
95
- isSearch : boolean ;
96
- }
14
+ export type MainHeaderProps = { } ;
97
15
98
- const Header : React . FC < HeaderProps > = ( {
99
- floating,
100
- floatingMargin,
101
- onLoginClick,
102
- user,
103
- custom,
104
- userLogo,
105
- velogUsername,
106
- isSearch,
107
- } ) => {
16
+ function Header ( props : MainHeaderProps ) {
17
+ const { user, onLoginClick, onLogout, customHeader } = useHeader ( ) ;
108
18
const [ userMenu , toggleUserMenu ] = useToggle ( false ) ;
109
19
const ref = useRef < HTMLDivElement > ( null ) ;
110
20
111
- const onLogout = useCallback ( async ( ) => {
112
- try {
113
- await logout ( ) ;
114
- } catch { }
115
- storage . removeItem ( 'CURRENT_USER' ) ;
116
- window . location . href = '/' ;
117
- } , [ ] ) ;
118
-
119
21
const onOutsideClick = useCallback (
120
22
( e : React . MouseEvent ) => {
121
23
if ( ! ref . current ) return ;
@@ -125,78 +27,105 @@ const Header: React.FC<HeaderProps> = ({
125
27
[ toggleUserMenu ] ,
126
28
) ;
127
29
30
+ const urlForSearch = customHeader . custom
31
+ ? `/search?username=${ customHeader . username } `
32
+ : '/search' ;
33
+
128
34
return (
129
- < >
130
- < HeaderBlock
131
- floating = { floating }
132
- style = { { marginTop : floating ? floatingMargin : 0 } }
133
- data-testid = "Header"
134
- >
135
- < MainResponsive >
136
- < div className = "wrapper" >
137
- < div className = "brand" >
138
- < HeaderLogo
139
- custom = { custom }
140
- userLogo = { userLogo }
141
- velogUsername = { velogUsername }
142
- />
143
- </ div >
144
- < div className = "right" >
145
- { /* {velogUsername ? (
146
- <SearchIcon2 className="search" />
147
- ) : (
148
- <Link to="/search">
149
- <SearchIcon2 className="search" />
150
- </Link>
151
- )} */ }
152
- { ! isSearch && (
153
- < Link
154
- to = {
155
- velogUsername
156
- ? `/search?username=${ velogUsername } `
157
- : '/search'
158
- }
159
- >
160
- < SearchIcon2 className = "search" />
161
- </ Link >
162
- ) }
163
- { user ? (
164
- < div className = "logged-in" >
165
- < RoundButton
166
- border
167
- color = "darkGray"
168
- style = { { marginRight : '1.25rem' } }
169
- to = "/write"
170
- className = "write-button"
171
- >
172
- 새 글 작성
173
- </ RoundButton >
174
- < div ref = { ref } >
175
- < HeaderUserIcon user = { user } onClick = { toggleUserMenu } />
176
- </ div >
177
- < HeaderUserMenu
178
- onClose = { onOutsideClick }
179
- username = { user . username }
180
- onLogout = { onLogout }
181
- visible = { userMenu }
182
- />
183
- </ div >
184
- ) : (
185
- < RoundButton
186
- color = "darkGray"
187
- onClick = { onLoginClick }
188
- className = "login-button"
189
- >
190
- 로그인
191
- </ RoundButton >
192
- ) }
35
+ < Block >
36
+ < Inner >
37
+ < HeaderLogo
38
+ custom = { customHeader . custom }
39
+ userLogo = { customHeader . userLogo }
40
+ username = { customHeader . username }
41
+ />
42
+
43
+ { user ? (
44
+ < Right >
45
+ < SearchButton to = { urlForSearch } >
46
+ < SearchIcon2 />
47
+ </ SearchButton >
48
+ < RoundButton
49
+ border
50
+ color = "darkGray"
51
+ style = { { marginRight : '1.25rem' } }
52
+ to = "/write"
53
+ className = "write-button"
54
+ >
55
+ 새 글 작성
56
+ </ RoundButton >
57
+
58
+ < div ref = { ref } >
59
+ < HeaderUserIcon user = { user } onClick = { toggleUserMenu } />
193
60
</ div >
194
- </ div >
195
- </ MainResponsive >
196
- </ HeaderBlock >
197
- { floating && < Placeholder /> }
198
- </ >
61
+ < HeaderUserMenu
62
+ onClose = { onOutsideClick }
63
+ onLogout = { onLogout }
64
+ username = { user . username }
65
+ visible = { userMenu }
66
+ />
67
+ </ Right >
68
+ ) : (
69
+ < Right >
70
+ < SearchButton to = { urlForSearch } >
71
+ < SearchIcon2 />
72
+ </ SearchButton >
73
+ < RoundButton color = "darkGray" onClick = { onLoginClick } >
74
+ 로그인
75
+ </ RoundButton >
76
+ </ Right >
77
+ ) }
78
+ </ Inner >
79
+ </ Block >
199
80
) ;
200
- } ;
81
+ }
82
+
83
+ const Block = styled . div `
84
+ height: 4rem;
85
+ ` ;
86
+
87
+ const StyledLink = styled ( Link ) `
88
+ display: flex;
89
+ align-items: center;
90
+ ` ;
91
+
92
+ const SearchButton = styled ( Link ) `
93
+ display: flex;
94
+ align-items: center;
95
+ justify-content: center;
96
+ background: transparent;
97
+ border: none;
98
+ width: 2.5rem;
99
+ height: 2.5rem;
100
+ outline: none;
101
+ border-radius: 50%;
102
+ cursor: pointer;
103
+ &:hover {
104
+ background: rgba(0, 0, 0, 0.045);
105
+ }
106
+ svg {
107
+ width: 1.125rem;
108
+ height: 1.125rem;
109
+ }
110
+ margin-right: 0.75rem;
111
+ ` ;
112
+
113
+ const Inner = styled ( MainResponsive ) `
114
+ height: 100%;
115
+ display: flex;
116
+ align-items: center;
117
+ justify-content: space-between;
118
+ ` ;
119
+
120
+ const Right = styled . div `
121
+ display: flex;
122
+ align-items: center;
123
+ position: relative;
124
+ .write-button {
125
+ ${ media . medium } {
126
+ display: none;
127
+ }
128
+ }
129
+ ` ;
201
130
202
131
export default Header ;
0 commit comments