Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/api/admin/customerService/Notice.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { ApiCommonBasicType } from '../../../models/apiCommon';
import type { WriteBody } from '../../../models/customerService';
import { httpClient } from '../../http.api';

export const postNotice = async (formData: WriteBody) => {
try {
await httpClient.post<ApiCommonBasicType>(`/notice`, formData);
} catch (e) {
console.error(e);
throw e;
}
};

export const putNotice = async (id: string, formData: WriteBody) => {
try {
await httpClient.put<ApiCommonBasicType>(`/notice/${id}`, formData);
} catch (e) {
console.error(e);
throw e;
}
};

export const deleteNotice = async (id: string) => {
try {
await httpClient.delete<ApiCommonBasicType>(`/notice/${id}`);
} catch (e) {
console.error(e);
throw e;
}
};
62 changes: 62 additions & 0 deletions src/components/admin/searchBar/SearchBar.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Link } from 'react-router-dom';
import styled from 'styled-components';

export const AdminSearchBarContainer = styled.form`
width: 100%;
display: flex;
justify-content: space-evenly;
margin-bottom: 2rem;
`;

export const AdminSearchBarWrapper = styled.div`
display: flex;
width: 60%;
`;

export const AdminSearchBarInputWrapper = styled.div`
display: flex;
width: 100%;
justify-content: space-between;
padding: 0.5rem 0.5rem 0.5rem 1rem;
border: 1px solid ${({ theme }) => theme.color.deepGrey};
border-radius: ${({ theme }) => theme.borderRadius.large} 0 0
${({ theme }) => theme.borderRadius.large};
`;

export const AdminSearchBarInput = styled.input`
width: 100%;
font-size: 1.3rem;
`;

export const AdminSearchBarBackIcon = styled.button`
svg {
width: 1.5rem;
}
`;

export const AdminSearchBarButton = styled.button`
width: 15%;
min-width: 5rem;
border: 1px solid ${({ theme }) => theme.color.navy};
background: ${({ theme }) => theme.color.navy};
border-radius: 0 ${({ theme }) => theme.borderRadius.large}
${({ theme }) => theme.borderRadius.large} 0;
font-size: 1.3rem;
color: ${({ theme }) => theme.color.white};
padding: 0.5rem 1rem 0.5rem 0.5rem;
`;

export const WriteLink = styled(Link)`
border: 1px solid ${({ theme }) => theme.color.navy};
background: ${({ theme }) => theme.color.navy};
border-radius: ${({ theme }) => theme.borderRadius.large};
font-size: 1rem;
color: ${({ theme }) => theme.color.white};
padding: 0.5rem 1rem;
transition: all 300ms ease-in-out;

&:hover {
background: ${({ theme }) => theme.color.white};
color: ${({ theme }) => theme.color.navy};
}
`;
84 changes: 84 additions & 0 deletions src/components/admin/searchBar/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { XMarkIcon } from '@heroicons/react/24/outline';
import { MODAL_MESSAGE_CUSTOMER_SERVICE } from '../../../constants/user/customerService';
import * as S from './SearchBar.styled';
import { useState } from 'react';
import { useLocation, useSearchParams } from 'react-router-dom';
import { useModal } from '../../../hooks/useModal';
import Modal from '../../common/modal/Modal';
import { ADMIN_ROUTE } from '../../../constants/routes';

interface SearchBarProps {
onGetKeyword: (keyword: string) => void;
value: string;
}

export default function SearchBar({ onGetKeyword, value }: SearchBarProps) {
const [inputValue, setInputValue] = useState<string>('');
const { isOpen, message, handleModalOpen, handleModalClose } = useModal();
const [searchParams, setSearchParams] = useSearchParams();
const location = useLocation();
const keyword = inputValue ? inputValue : value;

const handleKeyword = (inputValue: string) => {
const newSearchParams = new URLSearchParams(searchParams);
if (inputValue === '') {
newSearchParams.delete('keyword');
} else {
newSearchParams.set('keyword', inputValue);
}
setSearchParams(newSearchParams);
};

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

if (inputValue.trim() === '') {
return handleModalOpen(MODAL_MESSAGE_CUSTOMER_SERVICE.noKeyword);
} else {
onGetKeyword(inputValue);
handleKeyword(inputValue);
return;
}
};

const handleChangeKeyword = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
setInputValue(value);
};

const handleClickSearchDefault = () => {
setInputValue('');
onGetKeyword('');
handleKeyword('');
};

return (
<S.AdminSearchBarContainer onSubmit={handleSubmit}>
<S.AdminSearchBarWrapper>
<S.AdminSearchBarInputWrapper>
<S.AdminSearchBarInput
placeholder={MODAL_MESSAGE_CUSTOMER_SERVICE.noKeyword}
value={keyword}
onChange={handleChangeKeyword}
/>
{keyword && (
<S.AdminSearchBarBackIcon
type='button'
aria-label='show all result'
onClick={handleClickSearchDefault}
>
<XMarkIcon />
</S.AdminSearchBarBackIcon>
)}
</S.AdminSearchBarInputWrapper>
<S.AdminSearchBarButton>검색</S.AdminSearchBarButton>
</S.AdminSearchBarWrapper>
<S.WriteLink to={ADMIN_ROUTE.write} state={{ form: location.pathname }}>
작성하기
</S.WriteLink>
<Modal isOpen={isOpen} onClose={handleModalClose}>
{message}
</Modal>
</S.AdminSearchBarContainer>
);
}
1 change: 1 addition & 0 deletions src/components/common/admin/sidebar/AdminSidebar.styled.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import styled from 'styled-components';

export const LayoutContainer = styled.div`
max-width: 1440px;
height: 100vh;
display: flex;
`;
Expand Down
4 changes: 3 additions & 1 deletion src/components/common/admin/title/AdminTitle.styled.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import styled from 'styled-components';

export const TitleContainer = styled.header``;
export const TitleContainer = styled.header`
margin-bottom: 1rem;
`;

export const TitleWrapper = styled.div`
margin-bottom: 2rem;
Expand Down
4 changes: 2 additions & 2 deletions src/components/common/dropDown/DropDown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ interface DropDownProps {
children: React.ReactNode;
toggleButton: React.ReactNode;
isOpen?: boolean;
comment: boolean;
comment?: boolean;
}

const DropDown = ({
children,
toggleButton,
isOpen = false,
comment,
comment = false,
...props
}: DropDownProps) => {
const [open, setOpen] = useState(isOpen);
Expand Down
5 changes: 3 additions & 2 deletions src/components/user/customerService/CustomerServiceHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ interface CustomerServiceHeaderProps {

export default function CustomerServiceHeader({
title,
keyword,
keyword: value,
onGetKeyword,
}: CustomerServiceHeaderProps) {
const [inputValue, setInputValue] = useState<string>('');
const { isOpen, message, handleModalOpen, handleModalClose } = useModal();
const [searchParams, setSearchParams] = useSearchParams();
const keyword = value ? value : inputValue;

const handleKeyword = (inputValue: string) => {
const newSearchParams = new URLSearchParams(searchParams);
Expand Down Expand Up @@ -64,7 +65,7 @@ export default function CustomerServiceHeader({
<S.SearchBarInput
type='text'
placeholder='궁금한 내용을 검색해보세요.'
value={keyword ? keyword : inputValue}
value={keyword}
onChange={handleChangeValue}
/>
<S.ButtonWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { SpinnerWrapperStyled } from '../../mypage/Spinner.styled';

export const SpinnerWrapper = styled(SpinnerWrapperStyled)``;

export const Container = styled.section`
width: 75%;
export const Container = styled.section<{ $width: string }>`
width: ${({ $width }) => $width};
margin: 0 auto;
margin-bottom: 2rem;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@ import NoticeDetailHeader from './header/NoticeDetailHeader';
import Spinner from '../../mypage/Spinner';
import ListButton from './bottom/button/ListButton';

export default function NoticeDetailBundle() {
interface NoticeDetailBundleProps {
$width: string;
}

export default function NoticeDetailBundle({
$width,
}: NoticeDetailBundleProps) {
const location = useLocation();
const { noticeId } = useParams();
const id = noticeId || String(location.state.id);
const keyword = location.state?.keyword ?? '';
const includesAdmin = location.pathname.includes('admin') ?? false;

const { noticeDetail: noticeDetailData, isLoading } = useGetNoticeDetail(id);

Expand All @@ -25,7 +32,7 @@ export default function NoticeDetailBundle() {

if (!noticeDetailData) {
return (
<S.Container>
<S.Container $width={$width}>
<NoticeDetailContent
id={0}
title='해당 공지사항을 찾을 수 없습니다.'
Expand All @@ -49,8 +56,8 @@ export default function NoticeDetailBundle() {
} = noticeDetailData;

return (
<S.Container>
<NoticeDetailHeader />
<S.Container $width={$width}>
{!includesAdmin && <NoticeDetailHeader />}
<NoticeDetailContent
id={detailId}
title={title}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ROUTES } from '../../../../../../constants/routes';
import { useLocation } from 'react-router-dom';
import { ADMIN_ROUTE, ROUTES } from '../../../../../../constants/routes';
import ContentBorder from '../../../../../common/contentBorder/ContentBorder';
import * as S from './ListButton.styled';

Expand All @@ -7,14 +8,20 @@ interface ListButtonProps {
}

export default function ListButton({ keyword }: ListButtonProps) {
const location = useLocation();
const includesAdmin = location.pathname.includes('admin') ?? false;
const isKeyword = keyword ? `?keyword=${keyword}` : ``;

return (
<>
<ContentBorder />
<S.ListWrapper>
<S.ListLink
to={`${ROUTES.customerService}/${ROUTES.notice}${isKeyword}`}
to={
includesAdmin
? `${ADMIN_ROUTE.admin}/${ADMIN_ROUTE.notice}${isKeyword}`
: `${ROUTES.customerService}/${ROUTES.notice}${isKeyword}`
}
>
<S.ListTitle>목록</S.ListTitle>
</S.ListLink>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Link } from 'react-router-dom';
import styled from 'styled-components';

export const Container = styled.div`
Expand Down Expand Up @@ -33,6 +34,52 @@ export const InfoWrapper = styled.div`
gap: 1rem;
`;

export const AdminAuthWrapper = styled.div`
display: flex;
justify-content: space-between;
`;

export const AdminAuthButton = styled.button`
height: fit-content;
display: flex;
justify-content: center;
align-items: center;

svg {
width: 1rem;
height: 1rem;
}
`;

export const AdminDropdownWrapper = styled.div`
position: relative;
`;

export const AdminLinkWrapper = styled.nav`
position: absolute;
top: -1rem;
left: -5.5rem;
width: 5.5rem;
display: flex;
flex-direction: column;
background: ${({ theme }) => theme.color.white};
border-radius: ${({ theme }) => theme.borderRadius.primary};
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
overflow: hidden;
`;

export const AdminLink = styled(Link)`
width: 100%;
padding: 0.5rem;
display: flex;
justify-content: center;

&:hover {
background: ${({ theme }) => theme.color.lightgrey};
color: ${({ theme }) => theme.color.deepGrey};
}
`;

export const NoticeContentDate = styled.span`
font-size: 0.8rem;
`;
Expand Down
Loading