Skip to content

Commit

Permalink
[FEATURE] 공홈 어드민 배포 전 모달 띄우고 성공 시 성공 alert 띄우기
Browse files Browse the repository at this point in the history
  • Loading branch information
eonseok-jeon authored Jan 11, 2025
2 parents 170821e + 371639f commit cb684d2
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 99 deletions.
38 changes: 0 additions & 38 deletions src/components/org/OrgAdmin/HomeSection/Modal.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,6 @@ import { colors } from '@sopt-makers/colors';
import { fontsObject } from '@sopt-makers/fonts';
import { Button } from '@sopt-makers/ui';

export const StModalContainer = styled.div`
display: flex;
flex-direction: column;
gap: 12px;
padding: 24px;
& > h2 {
${fontsObject.TITLE_4_20_SB};
color: ${colors.gray10};
}
& > p {
${fontsObject.BODY_2_16_R};
color: ${colors.gray100};
}
`;

export const StModalBtnWrapper = styled.div`
place-self: end;
display: flex;
gap: 12px;
padding-top: 24px;
`;

export const StCancelButton = styled(Button)`
background-color: ${colors.gray600};
color: ${colors.white};
Expand All @@ -39,17 +12,6 @@ export const StCancelButton = styled(Button)`
}
`;

export const StActionButton = styled(Button)<{ btntype: 'add' | 'delete' }>`
color: ${(props) => (props.btntype === 'add' ? colors.black : colors.white)};
background-color: ${(props) =>
props.btntype === 'add' ? colors.white : colors.error};
&:disabled {
cursor: default;
}
`;

export const StAddButton = styled(Button)`
background-color: ${colors.white};
color: ${colors.black};
Expand Down
57 changes: 4 additions & 53 deletions src/components/org/OrgAdmin/HomeSection/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
'use client';

import { CheckBox, TextField } from '@sopt-makers/ui';
import { HTMLAttributes, useState } from 'react';
import { TextField } from '@sopt-makers/ui';
import { useState } from 'react';
import { useFormContext } from 'react-hook-form';

import Modal from '@/components/common/modal';
import ImageInput from '@/components/org/OrgAdmin/HomeSection/ImageInput';
import {
StActionButton,
StAddButton,
StAddModalBtnWrapper,
StAddModalContainer,
StCancelButton,
StModalBtnWrapper,
StModalContainer,
} from '@/components/org/OrgAdmin/HomeSection/Modal.style';
import { useAddNewsMutation } from '@/components/org/OrgAdmin/HomeSection/queries';
import { useBooleanState } from '@/hooks/useBooleanState';

import { ActionModal } from '../common/ActionModal';

/** 최신 소식 추가 모달 */
type AddNewsModalProps = {
isOpen: boolean;
Expand Down Expand Up @@ -96,7 +95,6 @@ export const AddNewsModal = ({ isOpen, onCancel }: AddNewsModalProps) => {

{isConfirmModalOpen && (
<ActionModal
id="add news"
variant="add"
isOpen={isConfirmModalOpen}
onCancel={closeConfirmModal}
Expand All @@ -109,50 +107,3 @@ export const AddNewsModal = ({ isOpen, onCancel }: AddNewsModalProps) => {
)
);
};

interface ActionModalProps extends Omit<HTMLAttributes<HTMLDivElement>, 'id'> {
isOpen: boolean;
onCancel?: () => void;
onAction?: () => void;
id?: number | string;
variant: 'add' | 'delete';
alertText: string;
description?: string;
}

export const ActionModal = ({
isOpen,
onCancel,
onAction,
variant,
alertText,
description,
}: ActionModalProps) => {
const [checked, setChecked] = useState(false);

return (
isOpen && (
<Modal>
<StModalContainer>
<h2>{alertText}</h2>
<p>{description}</p>

<CheckBox
label="확인했어요."
checked={checked}
onChange={() => setChecked((prev) => !prev)}
/>
<StModalBtnWrapper>
<StCancelButton onClick={onCancel}>취소</StCancelButton>
<StActionButton
btntype={variant}
disabled={!checked}
onClick={onAction}>
{variant === 'add' ? '추가' : '삭제'}
</StActionButton>
</StModalBtnWrapper>
</StModalContainer>
</Modal>
)
);
};
6 changes: 2 additions & 4 deletions src/components/org/OrgAdmin/HomeSection/NewsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ import { IconInfoCircle, IconPlus } from '@sopt-makers/icons';
import { Button } from '@sopt-makers/ui';
import { useState } from 'react';

import {
ActionModal,
AddNewsModal,
} from '@/components/org/OrgAdmin/HomeSection/Modal';
import { AddNewsModal } from '@/components/org/OrgAdmin/HomeSection/Modal';
import NewsItem from '@/components/org/OrgAdmin/HomeSection/NewsItem';
import { useDeleteNewsMutation } from '@/components/org/OrgAdmin/HomeSection/queries';
import {
Expand All @@ -21,6 +18,7 @@ import {
import { useBooleanState } from '@/hooks/useBooleanState';

import RequiredIcon from '../assets/RequiredIcon';
import { ActionModal } from '../common/ActionModal';
import Modal from '../common/Modal';
import useModal from '../common/Modal/useModal';

Expand Down
70 changes: 70 additions & 0 deletions src/components/org/OrgAdmin/common/ActionModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { CheckBox } from '@sopt-makers/ui';
import { type HTMLAttributes, useState } from 'react';
import type { FieldValues, SubmitHandler } from 'react-hook-form';

import Modal from '@/components/common/modal';

import {
StActionButton,
StCancelButton,
StModalBtnWrapper,
StModalContainer,
} from './style';

interface ActionModalProps extends Omit<HTMLAttributes<HTMLDivElement>, 'id'> {
isOpen: boolean;
onCancel?: () => void;
onAction?: () => void | SubmitHandler<FieldValues>;
variant: 'add' | 'delete' | 'deploy';
alertText: string;
description?: string;
}

export const ActionModal = ({
isOpen,
onCancel,
onAction,
variant,
alertText,
description,
}: ActionModalProps) => {
const [checked, setChecked] = useState(false);

return (
isOpen && (
<Modal>
<StModalContainer>
<h2>{alertText}</h2>
<p>{description}</p>
<CheckBox
label="확인했어요."
checked={checked}
onChange={() => setChecked((prev) => !prev)}
/>
<StModalBtnWrapper>
<StCancelButton
onClick={() => {
onCancel && onCancel();
setChecked(false);
}}>
취소
</StCancelButton>
<StActionButton
btntype={variant}
disabled={!checked}
onClick={() => {
setChecked(false);
onAction && onAction();
}}>
{variant === 'add'
? '추가'
: variant === 'delete'
? '삭제'
: '배포'}
</StActionButton>
</StModalBtnWrapper>
</StModalContainer>
</Modal>
)
);
};
54 changes: 54 additions & 0 deletions src/components/org/OrgAdmin/common/ActionModal/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import styled from '@emotion/styled';
import { colors } from '@sopt-makers/colors';
import { fontsObject } from '@sopt-makers/fonts';
import { Button } from '@sopt-makers/ui';

export const StModalContainer = styled.div`
display: flex;
flex-direction: column;
gap: 12px;
padding: 24px;
& > h2 {
${fontsObject.TITLE_4_20_SB};
color: ${colors.gray10};
}
& > p {
${fontsObject.BODY_2_16_R};
color: ${colors.gray100};
white-space: pre-line;
}
`;

export const StModalBtnWrapper = styled.div`
place-self: end;
display: flex;
gap: 12px;
padding-top: 24px;
`;

export const StCancelButton = styled(Button)`
background-color: ${colors.gray600};
color: ${colors.white};
&:hover {
color: ${colors.black};
}
`;

export const StActionButton = styled(Button)<{
btntype: 'add' | 'delete' | 'deploy';
}>`
color: ${(props) => (props.btntype === 'add' ? colors.black : colors.white)};
background-color: ${(props) =>
props.btntype === 'add' ? colors.white : colors.error};
&:disabled {
cursor: default;
}
`;
9 changes: 9 additions & 0 deletions src/components/org/OrgAdmin/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useToast } from '@sopt-makers/ui';
import { useMutation } from 'react-query';

import {
Expand Down Expand Up @@ -46,6 +47,8 @@ const useMutateSendData = ({
memberImageFile12,
recruitHeaderImageFile,
}: UseMutateSendDataProps) => {
const { open } = useToast();

const { mutate: sendMutate, isLoading: sendIsLoading } = useMutation({
mutationFn: (
data: AddAdminRequestDto,
Expand Down Expand Up @@ -174,6 +177,12 @@ const useMutateSendData = ({

const finalResponse = await sendDataConfirm({ generation });

if (finalResponse.response.status === 201)
open({
icon: 'success',
content: '성공적으로 배포했어요.',
});

return finalResponse;
} catch (err) {
console.error('최종 배포 실패: ', err);
Expand Down
37 changes: 33 additions & 4 deletions src/components/org/OrgAdmin/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {

import AboutSection from './AboutSection';
import SubmitIcon from './assets/SubmitIcon';
import { ActionModal } from './common/ActionModal';
import CommonSection from './CommonSection';
import HomeSection from './HomeSection/HomeSection';
import useMutateSendData from './hooks';
Expand All @@ -34,7 +35,9 @@ import {
} from './utils';

function OrgAdmin() {
const [isActionModalOpen, setIsActionModalOpen] = useState(false);
const [selectedPart, setSelectedPart] = useState<ORG_ADMIN>('공통');

const [group, setGroup] = useState<Group>('OB');

const [selectedPartInHomeTap, setSelectedPartInHomeTap] =
Expand Down Expand Up @@ -82,7 +85,7 @@ function OrgAdmin() {
setIntroPart(part);
};

const onSubmit: SubmitHandler<FieldValues> = (data) => {
const handleCheckNonFilledInputs = () => {
const handleValidateCommonInputs = () =>
validationCommonInputs(getValues, setError, setGroup);
const handleValidateHomeInputs = () =>
Expand Down Expand Up @@ -148,9 +151,14 @@ function OrgAdmin() {
content: `${getPartForValidation(validate)}탭에 아직 채우지 않은 필드가 있어요.`,
});
setSelectedPart(getPartForValidation(validate));
return;
return false;
}
}

return true;
};

const onSubmit: SubmitHandler<FieldValues> = (data) => {
const {
generation,
brandingColor,
Expand Down Expand Up @@ -278,7 +286,7 @@ function OrgAdmin() {
/>
</StListHeader>
<FormProvider {...methods}>
<form noValidate onSubmit={handleSubmit(onSubmit)}>
<form noValidate>
{selectedPart === '공통' ? (
<CommonSection
group={group}
Expand Down Expand Up @@ -312,12 +320,33 @@ function OrgAdmin() {
onChangeFnaPart={(part: PART_KO) => setFnaPart(part)}
/>
)}
<StSubmitButton>
<StSubmitButton
type="button"
onClick={() => {
if (handleCheckNonFilledInputs()) {
setIsActionModalOpen(true);
}
}}>
<SubmitIcon />
<StSubmitText>{sendIsLoading ? '배포 중...' : '배포'}</StSubmitText>
</StSubmitButton>
</form>
</FormProvider>
<ActionModal
isOpen={isActionModalOpen}
onCancel={() => {
setIsActionModalOpen(false);
}}
onAction={() => {
setIsActionModalOpen(false);
handleSubmit(onSubmit)();
}}
variant="deploy"
alertText="배포하시겠습니까?"
description={
'입력한 내용은 공홈에 즉시 반영돼요.\n잘못 기입된 부분이 없는지 마지막으로 확인해주세요.'
}
/>
</>
);
}
Expand Down

0 comments on commit cb684d2

Please sign in to comment.