File tree Expand file tree Collapse file tree 6 files changed +157
-11
lines changed
Expand file tree Collapse file tree 6 files changed +157
-11
lines changed Original file line number Diff line number Diff line change @@ -14,6 +14,7 @@ function UserProfile({
1414 nickname,
1515 profileImageUrl,
1616} : UserProfileProps ) {
17+ if ( ! nickname ) return null ;
1718 return (
1819 < >
1920 < div className = { `${ styles [ 'user-profile' ] } ${ styles [ type ] } ` } >
Original file line number Diff line number Diff line change 112112 gap : 8px ;
113113}
114114
115+ .skeleton {
116+ background-color : var (--gray-medium );
117+ border-radius : 8px ;
118+ animation : loading 1.5s infinite linear;
119+ }
120+
121+ @keyframes loading {
122+ 0% {
123+ opacity : 0.99 ;
124+ }
125+ 50% {
126+ opacity : 0.5 ;
127+ }
128+ 100% {
129+ opacity : 0.99 ;
130+ }
131+ }
132+
133+ .skeleton-card {
134+ width : 100% ;
135+ height : 70px ;
136+ border-radius : 8px ;
137+ }
138+
115139@media screen and (max-width : 1199px ) {
116140 .dashboard-container {
117141 margin-left : 200px ;
154178 .modal input ::placeholder {
155179 font-size : 14px ;
156180 }
181+
182+ .skeleton-card {
183+ max-width : 260px ;
184+ }
157185}
Original file line number Diff line number Diff line change @@ -45,13 +45,20 @@ export default function DashboardList() {
4545 } ;
4646
4747 const fetchDashboards = async ( ) => {
48- const response = await getDashboards ( {
49- page : currentPage ,
50- size : pageSize ,
51- navigationMethod : 'pagination' ,
52- } ) ;
53- setDashboards ( response . dashboards ) ;
54- setTotalPages ( Math . ceil ( response . totalCount / pageSize ) ) ;
48+ setIsLoading ( true ) ;
49+ try {
50+ const response = await getDashboards ( {
51+ page : currentPage ,
52+ size : pageSize ,
53+ navigationMethod : 'pagination' ,
54+ } ) ;
55+ setDashboards ( response . dashboards ) ;
56+ setTotalPages ( Math . ceil ( response . totalCount / pageSize ) ) ;
57+ } catch ( error ) {
58+ console . error ( 'Error fetching dashboards:' , error ) ;
59+ } finally {
60+ setIsLoading ( false ) ;
61+ }
5562 } ;
5663
5764 const handleNewDashboard = async ( ) => {
@@ -89,7 +96,16 @@ export default function DashboardList() {
8996 </ CDSButton >
9097 </ li >
9198
92- { Array . isArray ( dashboards ) && dashboards . length > 0 ? (
99+ { /* 스켈레톤 표시 */ }
100+ { ! isLoading ? (
101+ Array . from ( { length : pageSize } ) . map ( ( _ , index ) => (
102+ < li key = { `skeleton_${ index } ` } className = { styles . dashboard } >
103+ < div
104+ className = { `${ styles . skeleton } ${ styles [ 'skeleton-card' ] } ` }
105+ />
106+ </ li >
107+ ) )
108+ ) : Array . isArray ( dashboards ) && dashboards . length > 0 ? (
93109 dashboards . map ( ( item ) => (
94110 < li key = { `DashboardList_${ item . id } ` } className = { styles . dashboard } >
95111 < CDSButton
Original file line number Diff line number Diff line change 112112 color : var (--gray-dark );
113113}
114114
115+ .skeleton {
116+ background-color : var (--gray-medium );
117+ border-radius : 8px ;
118+ animation : loading 1.5s infinite linear;
119+ }
120+
121+ @keyframes loading {
122+ 0% {
123+ opacity : 0.99 ;
124+ }
125+ 50% {
126+ opacity : 0.5 ;
127+ }
128+ 100% {
129+ opacity : 0.99 ;
130+ }
131+ }
132+
133+ .skeleton-container {
134+ padding : 0 28px 0 28px ;
135+ }
136+
137+ .skeleton-title {
138+ padding : 0 100px 0 100px ;
139+ display : flex;
140+ justify-content : space-between;
141+ text-align : center;
142+ border-bottom : 1px solid var (--gray-bright );
143+ font-size : 16px ;
144+ font-weight : 400 ;
145+ color : var (--gray-dark );
146+ }
147+
148+ .skeleton-row {
149+ display : flex;
150+ gap : 100px ;
151+ align-items : center;
152+ height : 52px ;
153+ margin-bottom : 20px ;
154+ }
155+
156+ .skeleton-cell {
157+ flex : 1 ;
158+ height : 32px ;
159+ }
160+
115161@media screen and (max-width : 1199px ) {
116162 .invitation-container {
117163 max-width : 504px ;
137183 padding : 120px 130px ;
138184 gap : 24px ;
139185 }
186+
187+ .skeleton-title {
188+ padding : 0 30px 0 30px ;
189+ }
190+
191+ .skeleton-row {
192+ display : flex;
193+ gap : 40px ;
194+ align-items : center;
195+ height : 52px ;
196+ margin-bottom : 20px ;
197+ }
140198}
141199
142200@media screen and (max-width : 743px ) {
182240 .no-invitations-text {
183241 font-size : 12px ;
184242 }
243+
244+ .skeleton-title {
245+ padding : 0 ;
246+ }
247+
248+ .skeleton-row {
249+ display : flex;
250+ gap : 20px ;
251+ align-items : center;
252+ height : 52px ;
253+ margin-bottom : 20px ;
254+ }
185255}
186256
187257@media screen and (max-width : 743px ) {
Original file line number Diff line number Diff line change @@ -130,7 +130,29 @@ export default function InvitationList() {
130130 </ div >
131131 </ div >
132132
133- { invitations . length > 0 ? (
133+ { ! isLoading ? (
134+ < div className = { styles [ 'skeleton-container' ] } >
135+ < div className = { styles [ 'skeleton-title' ] } >
136+ < div > 이름</ div >
137+ < div > 초대자</ div >
138+ < div > 수락 여부</ div >
139+ </ div >
140+
141+ { Array . from ( { length : 10 } ) . map ( ( _ , index ) => (
142+ < div key = { `skeleton_${ index } ` } className = { styles [ 'skeleton-row' ] } >
143+ < div
144+ className = { `${ styles . skeleton } ${ styles [ 'skeleton-cell' ] } ` }
145+ />
146+ < div
147+ className = { `${ styles . skeleton } ${ styles [ 'skeleton-cell' ] } ` }
148+ />
149+ < div
150+ className = { `${ styles . skeleton } ${ styles [ 'skeleton-cell' ] } ` }
151+ />
152+ </ div >
153+ ) ) }
154+ </ div >
155+ ) : invitations . length > 0 ? (
134156 < table className = { styles . table } >
135157 < thead >
136158 < tr className = { styles [ 'table-head' ] } >
You can’t perform that action at this time.
0 commit comments