-
Notifications
You must be signed in to change notification settings - Fork 0
관리자 배너 페이지 구현( Feat/#347 ) #354
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
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| import type { ApiBannerList } from '../../models/admin/banner'; | ||
| import { httpClient } from '../http.api'; | ||
|
|
||
| export const getBannerList = async () => { | ||
| try { | ||
| const response = await httpClient.get<ApiBannerList>('/banner'); | ||
| console.log(response.data); | ||
| return response.data; | ||
| } catch (error) { | ||
| console.error(error); | ||
| throw error; | ||
| } | ||
| }; | ||
|
|
||
| export const postBanner = async (formData: FormData) => { | ||
| try { | ||
| const response = await httpClient.post('/banner', formData); | ||
| return response.data; | ||
| } catch (error) { | ||
| console.error(error); | ||
| throw error; | ||
| } | ||
| }; | ||
|
|
||
| export const patchBanner = async (formData: FormData, bannerId?: number) => { | ||
| try { | ||
| for (const [key, value] of formData.entries()) { | ||
| if (value instanceof File) { | ||
| console.log(`${key}:`, { | ||
| name: value.name, | ||
| size: value.size, | ||
| type: value.type, | ||
| lastModified: value.lastModified, | ||
| }); | ||
| } else { | ||
| console.log(`${key}:`, value); | ||
| } | ||
| } | ||
| const response = await httpClient.patch(`/banner/${bannerId}`, formData); | ||
| return response.data; | ||
| } catch (error) { | ||
| console.error(error); | ||
| throw error; | ||
| } | ||
| }; | ||
|
|
||
| export const deleteBanner = async (bannerId?: number) => { | ||
| try { | ||
| const response = await httpClient.delete(`/banner/${bannerId}`); | ||
| return response.data; | ||
| } catch (error) { | ||
| console.error(error); | ||
| throw error; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,247 @@ | ||||||||||
| import styled, { css } from 'styled-components'; | ||||||||||
| import Button from '../../common/Button/Button'; | ||||||||||
|
|
||||||||||
| export const AddButtonContainer = styled.div``; | ||||||||||
|
|
||||||||||
| export const AddButton = styled(Button)``; | ||||||||||
|
|
||||||||||
| export const Container = styled.table<{ $header?: boolean }>` | ||||||||||
| border-collapse: collapse; | ||||||||||
| table-layout: fixed; | ||||||||||
| border-radius: 8px; | ||||||||||
| overflow: hidden; | ||||||||||
| width: 100%; | ||||||||||
| margin-top: 10rem; | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| export const TableHeader = styled.thead` | ||||||||||
| color: #ffffff; | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| export const TableHeaderCell = styled.th` | ||||||||||
| padding: 16px; | ||||||||||
| font-size: 14px; | ||||||||||
| text-align: center; | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| export const ScrollBody = styled.tbody``; | ||||||||||
|
|
||||||||||
| export const TableRow = styled.tr``; | ||||||||||
|
|
||||||||||
| export const TableCell = styled.td` | ||||||||||
| padding: 14px; | ||||||||||
| font-size: 14px; | ||||||||||
| text-align: center; | ||||||||||
| color: #333; | ||||||||||
| vertical-align: middle; | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| export const ImageCell = styled(TableCell)` | ||||||||||
| position: relative; | ||||||||||
| height: 120px; | ||||||||||
| padding: 0; | ||||||||||
| width: 280px; | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| export const ImageUploadArea = styled.div` | ||||||||||
| position: relative; | ||||||||||
| width: 100%; | ||||||||||
| height: 120px; | ||||||||||
| cursor: pointer; | ||||||||||
| border-radius: 6px; | ||||||||||
| overflow: hidden; | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| export const Thumbnail = styled.img` | ||||||||||
| width: 100%; | ||||||||||
| height: 100%; | ||||||||||
| object-fit: cover; | ||||||||||
| border-radius: 6px; | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| export const ImageOverlay = styled.div` | ||||||||||
| position: absolute; | ||||||||||
| top: 0; | ||||||||||
| left: 0; | ||||||||||
| width: 100%; | ||||||||||
| height: 100%; | ||||||||||
| background-color: rgba(0, 0, 0, 0.5); | ||||||||||
| display: flex; | ||||||||||
| align-items: center; | ||||||||||
| justify-content: center; | ||||||||||
| border-radius: 6px; | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| export const EditIcon = styled.div` | ||||||||||
| display: flex; | ||||||||||
| align-items: center; | ||||||||||
| justify-content: center; | ||||||||||
| color: white; | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| export const ImageLabel = styled.div` | ||||||||||
| position: absolute; | ||||||||||
| top: 50%; | ||||||||||
| left: 50%; | ||||||||||
| transform: translate(-50%, -50%); | ||||||||||
| color: white; | ||||||||||
| font-weight: 600; | ||||||||||
| font-size: 15px; | ||||||||||
| text-shadow: 0 0 5px rgba(0, 0, 0, 0.6); | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| export const PlusButton = styled.div` | ||||||||||
| width: 100%; | ||||||||||
| height: 120px; | ||||||||||
| border: 2px dashed #ccc; | ||||||||||
| font-size: 32px; | ||||||||||
| color: #888; | ||||||||||
| display: flex; | ||||||||||
| align-items: center; | ||||||||||
| justify-content: center; | ||||||||||
| border-radius: 6px; | ||||||||||
| cursor: pointer; | ||||||||||
| transition: all 0.2s ease-in-out; | ||||||||||
|
|
||||||||||
| &:hover { | ||||||||||
| border-color: #6c5ce7; | ||||||||||
| color: #6c5ce7; | ||||||||||
| background-color: rgba(108, 92, 231, 0.1); | ||||||||||
| } | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| export const ToggleSwitch = styled.div` | ||||||||||
| position: relative; | ||||||||||
| width: 50px; | ||||||||||
| height: 24px; | ||||||||||
|
|
||||||||||
| input { | ||||||||||
| opacity: 0; | ||||||||||
| width: 0; | ||||||||||
| height: 0; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| label { | ||||||||||
| position: absolute; | ||||||||||
| background: #ccc; | ||||||||||
|
||||||||||
| border-radius: 999px; | ||||||||||
| width: 100%; | ||||||||||
| height: 100%; | ||||||||||
| cursor: pointer; | ||||||||||
| transition: background 0.2s ease-in-out; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| label::after { | ||||||||||
| content: ''; | ||||||||||
| position: absolute; | ||||||||||
| top: 2px; | ||||||||||
| left: 2px; | ||||||||||
| width: 20px; | ||||||||||
| height: 20px; | ||||||||||
| background: #fff; | ||||||||||
| border-radius: 50%; | ||||||||||
| transition: transform 0.2s ease-in-out; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| input:checked + label { | ||||||||||
| background-color: #6c5ce7; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| input:checked + label::after { | ||||||||||
| transform: translateX(26px); | ||||||||||
| } | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| export const RadioGroup = styled.div` | ||||||||||
| display: flex; | ||||||||||
| justify-content: center; | ||||||||||
| gap: 12px; | ||||||||||
| font-size: 14px; | ||||||||||
|
|
||||||||||
| input { | ||||||||||
| display: none; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| label { | ||||||||||
| position: relative; | ||||||||||
| padding-left: 22px; | ||||||||||
| cursor: pointer; | ||||||||||
|
|
||||||||||
| &::before { | ||||||||||
| content: ''; | ||||||||||
| position: absolute; | ||||||||||
| left: 0; | ||||||||||
| top: 2px; | ||||||||||
| width: 16px; | ||||||||||
| height: 16px; | ||||||||||
| border: 2px solid #666; | ||||||||||
|
||||||||||
| border-radius: 50%; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| &::after { | ||||||||||
| content: ''; | ||||||||||
| position: absolute; | ||||||||||
| left: 4px; | ||||||||||
| top: 6px; | ||||||||||
| width: 8px; | ||||||||||
| height: 8px; | ||||||||||
| background-color: #6c5ce7; | ||||||||||
| border-radius: 50%; | ||||||||||
| opacity: 0; | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| input:checked + label::after { | ||||||||||
| opacity: 1; | ||||||||||
| } | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| export const DateRange = styled.div` | ||||||||||
| display: flex; | ||||||||||
| align-items: center; | ||||||||||
| justify-content: center; | ||||||||||
| gap: 8px; | ||||||||||
|
|
||||||||||
| span { | ||||||||||
| font-size: 14px; | ||||||||||
| } | ||||||||||
| `; | ||||||||||
| export const DateInput = styled.input` | ||||||||||
| width: 120px; | ||||||||||
| height: 36px; | ||||||||||
| padding: 0 12px; | ||||||||||
| font-size: 14px; | ||||||||||
| border-radius: 18px; | ||||||||||
| border: 1px solid #ccc; | ||||||||||
|
||||||||||
| border: 1px solid #ccc; | |
| font-size: 14px; | |
| border-radius: 18px; | |
| border: 1px solid ${({ theme }) => theme.color.gray300}; |
🤖 Prompt for AI Agents
In src/components/admin/banner/BannerList.styled.ts at line 220, the border
color for the DateInput is hardcoded as #ccc. Replace this hardcoded color with
the appropriate theme variable for border color to ensure consistent theming
across the application.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
250과 중복입니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
감사합니다
Uh oh!
There was an error while loading. Please reload this page.