diff --git a/components/admin/agenda/SideNavAgenda.tsx b/components/admin/agenda/SideNavAgenda.tsx index e796077d1..8898a4b6d 100644 --- a/components/admin/agenda/SideNavAgenda.tsx +++ b/components/admin/agenda/SideNavAgenda.tsx @@ -40,14 +40,6 @@ export default function SideNavParty() { > - - - > ); } diff --git a/components/admin/agenda/agendaList/AgendaTable.tsx b/components/admin/agenda/agendaList/AgendaTable.tsx index d38d01fa3..ab3c06cbd 100644 --- a/components/admin/agenda/agendaList/AgendaTable.tsx +++ b/components/admin/agenda/agendaList/AgendaTable.tsx @@ -85,7 +85,6 @@ export default function AgendaTable({ status, isOfficial }: AgendaTableProps) { }); const [currentPage, setCurrentPage] = useState(1); - const setSnackBar = useSetRecoilState(toastState); const { openModal, closeModal } = useModal(); const buttonList: string[] = [ @@ -165,13 +164,6 @@ export default function AgendaTable({ status, isOfficial }: AgendaTableProps) { const getData = await instanceInAgenda.get( `/admin/request/list?page=${currentPage}&size=${itemsPerPage}` ); - // setSnackBar({ - // toastName: 'GET request', - // message: 'agenda List를 가져오는데 실패했습니다.', - // severity: 'error', - // clicked: true, - // }); - const filteredAgendaList = getData.data.content.filter( (agenda: IAgenda) => { const matchesStatus = status ? agenda.agendaStatus === status : true; diff --git a/components/admin/agenda/teamList/TeamTable.tsx b/components/admin/agenda/teamList/TeamTable.tsx index a3e4078ed..61fd3745c 100644 --- a/components/admin/agenda/teamList/TeamTable.tsx +++ b/components/admin/agenda/teamList/TeamTable.tsx @@ -11,7 +11,6 @@ import { TableContainer, TableRow, } from '@mui/material'; -import { TeamDetailProps } from 'types/agenda/teamDetail/TeamDetailTypes'; import { instance } from 'utils/axios'; import { toastState } from 'utils/recoil/toast'; import { agendaTableFormat } from 'constants/admin/agendaTable'; @@ -33,6 +32,7 @@ const tableTitle: { [key: string]: string } = { teamAward: '상', teamAwardPriority: '등수', teamStatus: '상태', + teamLocation: '위치', etc: '기타', }; @@ -45,6 +45,7 @@ export interface ITeam { teamAward: string; teamAwardPriority: number; teamStatus: string; + teamLocation: string; coalitions: string[]; } @@ -72,34 +73,28 @@ export default function TeamTable() { const buttonList: string[] = [styles.coin, styles.penalty]; - const deleteTeam = async (teamInfo: TeamDetailProps) => { - const updateTeam = { - teamKey: teamInfo.teamKey, - teamName: teamInfo.teamName, - teamContent: 'content', // 이후 제거 - teamStatus: TeamStatus.CANCEL, - teamIsPrivate: teamInfo.teamIsPrivate, - teamLocation: 'SEOUL', // 이후 제거 - teamAward: teamInfo.teamAward, - teamAwardPriority: teamInfo.teamAwardPriority, - teamMates: [{ intraId: 'jihylim' }], - }; - await sendRequest('PATCH', 'admin/team', updateTeam, {}, () => { - getTeamList(); - }); + const deleteTeam = async (teamKey: string) => { + await sendRequest( + 'PATCH', + 'admin/team/cancel', + {}, + { team_key: teamKey }, + () => { + getTeamList(); + } + ); }; - const handleButtonAction = ( - buttonName: string, - teamInfo: TeamDetailProps - ) => { - const teamKey = teamInfo.teamKey; + const handleButtonAction = (buttonName: string, team: ITeam) => { + const teamKey = team.teamKey; switch (buttonName) { case '수정': - router.push(`/admin/agenda/teamModify?team_key=${teamKey}`); + router.push( + `/admin/agenda/teamModify?team_key=${teamKey}&location=${team.teamLocation}` + ); break; case '취소': - deleteTeam(teamInfo); + deleteTeam(teamKey as string); break; } }; diff --git a/components/admin/agenda/ticket/TicketTable.tsx b/components/admin/agenda/ticket/TicketTable.tsx index 27745d026..09e18d29a 100644 --- a/components/admin/agenda/ticket/TicketTable.tsx +++ b/components/admin/agenda/ticket/TicketTable.tsx @@ -1,4 +1,3 @@ -import router, { useRouter } from 'next/router'; import { useCallback, useEffect, useState } from 'react'; import { Paper, @@ -8,161 +7,91 @@ import { TableContainer, TableRow, } from '@mui/material'; -// import { instance } from 'utils/axios'; -// import { dateToStringShort } from 'utils/handleTime'; +import { ITicket } from 'types/agenda/ticket/ticketTypes'; +import { instance } from 'utils/axios'; import { agendaTableFormat } from 'constants/admin/agendaTable'; import { NoContent } from 'components/admin/agenda/utils'; import { AdminAgendaTableHead } from 'components/admin/takgu/common/AdminTable'; +import AdminTicketForm from 'components/agenda/Form/AdminTicketForm'; +import { useModal } from 'components/agenda/modal/useModal'; import PageNation from 'components/Pagination'; -// import useFetchGet from 'hooks/agenda/useFetchGet'; import styles from 'styles/admin/agenda/agendaList/AgendaTable.module.scss'; -import ticketStyles from 'styles/admin/agenda/TicketTable.module.scss'; const itemsPerPage = 10; // 한 페이지에 보여줄 항목 수 -export const mockAgendaList = [ - { - ticketId: 1, - createdAt: '2024-08-01', - issuedFrom: '대회 1', - issuedFromKey: '1', - usedTo: '대회 2', - usedToKey: '2', - isApproved: true, - approvedAt: '2024-08-01', - isUsed: true, - usedAt: '2024-08-01', - }, - { - ticketId: 2, - createdAt: '2024-08-02', - issuedFrom: '대회 2', - issuedFromKey: '2', - usedTo: '대회 1', - usedToKey: '1', - isApproved: false, - approvedAt: '2024-08-02', - isUsed: false, - usedAt: '2024-08-02', - }, - { - ticketId: 3, - createdAt: '2024-08-03', - issuedFrom: '대회 3', - issuedFromKey: '3', - usedTo: '대회 4', - usedToKey: '4', - isApproved: true, - approvedAt: '2024-08-03', - isUsed: true, - usedAt: '2024-08-03', - }, -]; - const tableTitle: { [key: string]: string } = { ticketId: '티켓 ID', - createdAt: '발급 시작 시간', - issuedFrom: '발급된 곳', - // issuedFromKey: '발급된 곳 키', + createdAt: '발급 시간', + issuedFrom: '발급처', usedTo: '사용처', - // usedToKey: '사용처 키', - isApproved: '발급 여부', - approvedAt: '발급된 시간', + isApproved: '승인 여부', + approvedAt: '승인 시간', isUsed: '사용 여부', - usedAt: '사용된 시간', + usedAt: '사용 시간', etc: '기타', }; -export interface ITicket { - ticketId: number; - createdAt: string; - issuedFrom: string; - issuedFromKey: string; - usedTo: string; - usedToKey: string; - isApproved: boolean; - approvedAt: string; - isUsed: boolean; - usedAt: string; -} - export interface ITicketTable { ticketList: ITicket[]; totalPage: number; currentPage: number; } -export default function TicketTable() { +interface TicketTableProps { + intraId: string; +} + +const TicketTable = ({ intraId }: TicketTableProps) => { const [ticketInfo, setTicketInfo] = useState({ ticketList: [], totalPage: 0, currentPage: 0, }); const [currentPage, setCurrentPage] = useState(1); + const { openModal, closeModal } = useModal(); - // const modal = useRecoilValue(modalState); - const buttonList: string[] = [styles.detail, styles.coin, styles.penalty]; - - const handleButtonAction = (buttonName: string) => { - switch (buttonName) { - case '자세히': - // setModal({ modalName: 'ADMIN-PROFILE', intraId }); - alert('자세히'); - break; - case '대회 수정': - // setModal({ modalName: 'ADMIN-PROFILE', intraId }); - alert('대회 수정'); - break; - case '대회 삭제': - // 모달 추가 - alert('대회 삭제'); - break; - } - }; - - const handleCellClick = (agedaKey) => { - router.push(`/admin/agenda/${agedaKey}`); + const handleButtonAction = (ticket: ITicket) => { + openModal({ + type: 'modify', + title: '티켓 수정', + description: '변경 후 수정 버튼을 눌러주세요.', + FormComponent: AdminTicketForm, + data: ticket, + isAdmin: true, + stringKey: intraId, + onProceed: () => { + closeModal(); + getTicketList(); + }, + }); }; const getTicketList = useCallback(async () => { - try { - // const res = await instance.get(`/agenda/admin/request/list`, { - // params: { page: currentPage, size: 10 }, - // }); - // const res = await instance.get( - // `/agenda/admin/request/list?page=${currentPage}&size=10` - // ); - const res = mockAgendaList; - // const params = { - // page: currentPage, - // size: itemsPerPage, - // }; - // const res = useFetchGet(`/agenda/admin/request/list`, params).data; - - const totalPage = Math.ceil(res.length / itemsPerPage); - const paginatedList = res.slice( - (currentPage - 1) * itemsPerPage, - currentPage * itemsPerPage - ); + const response = await instance.get( + `/agenda/admin/ticket/list/${intraId}`, + { + params: { + page: currentPage, + size: itemsPerPage, + }, + } + ); - setTicketInfo({ - ticketList: paginatedList, - totalPage: totalPage, - currentPage: currentPage, - }); - } catch (e) { - console.error('MS00'); - } - }, [currentPage]); + setTicketInfo({ + ticketList: response.data.content, + totalPage: Math.ceil(response.data.totalSize / itemsPerPage), + currentPage: currentPage, + }); + }, [currentPage, intraId]); useEffect(() => { getTicketList(); }, [getTicketList]); - const renderApprove = (isApproved: boolean) => { + const renderApprove = (isApproved?: boolean) => { return isApproved ? '발급완료' : '발급대기'; }; - const renderUsed = (isUsed: boolean) => { + const renderUsed = (isUsed?: boolean) => { return isUsed ? '사용완료' : '사용대기'; }; @@ -180,43 +109,25 @@ export default function TicketTable() { {agendaTableFormat['ticket'].columns.map( (columnName: string, index: number) => { - const isClickable = - columnName === 'issuedFrom' || columnName === 'usedTo'; return ( { - if (isClickable) { - handleCellClick( - columnName === 'issuedFrom' - ? ticket.issuedFromKey - : ticket.usedToKey - ); - } - }} > - {columnName === 'isApproved' - ? renderApprove(ticket.isApproved) // 상태 표시 - : columnName === 'isUsed' - ? renderUsed(ticket.isUsed) // 사용 여부 표시 - : columnName !== 'etc' - ? ticket[columnName as keyof ITicket] // 다른 열의 기본 값 표시 - : agendaTableFormat['ticket'].etc?.value.map( - (buttonName: string, index: number) => ( - - handleButtonAction(buttonName) - } - > - {buttonName} - - ) - )} + {columnName === 'isApproved' ? ( + renderApprove(ticket.isApproved) // 상태 표시 + ) : columnName === 'isUsed' ? ( + renderUsed(ticket.isUsed) // 사용 여부 표시 + ) : columnName !== 'etc' ? ( + ticket[columnName as keyof ITicket] + ) : ( + handleButtonAction(ticket)} + > + 수정 + + )} ); } @@ -241,4 +152,6 @@ export default function TicketTable() { ); -} +}; + +export default TicketTable; diff --git a/components/admin/agenda/users/UserTable.tsx b/components/admin/agenda/users/UserTable.tsx index 8b14f551f..dde4b53bd 100644 --- a/components/admin/agenda/users/UserTable.tsx +++ b/components/admin/agenda/users/UserTable.tsx @@ -1,5 +1,5 @@ +import router from 'next/router'; import { useCallback, useEffect, useState } from 'react'; -import { useSetRecoilState } from 'recoil'; import { Paper, Table, @@ -10,13 +10,15 @@ import { } from '@mui/material'; import { IUser, IUserTable } from 'types/admin/takgu/adminUserTypes'; import { instanceInManage } from 'utils/axios'; -import { modalState } from 'utils/recoil/takgu/modal'; import { agendaTableFormat } from 'constants/admin/agendaTable'; import AdminSearchBar from 'components/admin/takgu/common/AdminSearchBar'; import { AdminAgendaTableHead, AdminEmptyItem, } from 'components/admin/takgu/common/AdminTable'; +import TicketForm from 'components/agenda/Form/TicketForm'; +import UserForm from 'components/agenda/Form/userForm'; +import { useModal } from 'components/agenda/modal/useModal'; import PageNation from 'components/Pagination'; import styles from 'styles/admin/takgu/users/UserManagementTable.module.scss'; @@ -35,10 +37,34 @@ export default function UserTable() { }); const [currentPage, setCurrentPage] = useState(1); const [intraId, setIntraId] = useState(''); - const setModal = useSetRecoilState(modalState); + const { openModal } = useModal(); + const buttonList: string[] = [styles.detail, styles.coin, styles.penalty]; - const handleButtonAction = (intraId: string) => { - alert('자세히'); + const handleButtonAction = (buttonName: string, intraId: string) => { + switch (buttonName) { + case '프로필': + openModal({ + type: 'modify', + title: '프로필 수정', + description: '변경 후 수정 버튼을 눌러주세요.', + FormComponent: UserForm, + stringKey: intraId, + }); + break; + + case '티켓발급': + openModal({ + type: 'modify', + title: '티켓 발급', + description: '티켓을 발급하시겠습니까?', + FormComponent: TicketForm, + stringKey: intraId, + }); + break; + case '티켓조회': + router.push(`/admin/agenda/ticket?intraId=${intraId}`); + break; + } }; const initSearch = useCallback((intraId?: string) => { @@ -101,19 +127,24 @@ export default function UserTable() { className={styles.tableBodyItem} key={columnName} > - {columnName !== 'etc' ? ( - userInfo[columnName as keyof IUser] - ) : ( - - handleButtonAction(userInfo.intraId) - } - > - {'자세히'} - - )} + {columnName !== 'etc' + ? userInfo[columnName as keyof IUser] + : agendaTableFormat['user'].etc?.value.map( + (buttonName: string, index: number) => ( + + handleButtonAction( + buttonName, + userInfo.intraId + ) + } + > + {buttonName} + + ) + )} ); } diff --git a/components/agenda/Form/AdminTeamForm.tsx b/components/agenda/Form/AdminTeamForm.tsx index 861cc8820..abd4be503 100644 --- a/components/agenda/Form/AdminTeamForm.tsx +++ b/components/agenda/Form/AdminTeamForm.tsx @@ -1,6 +1,10 @@ import router from 'next/router'; +import { useState } from 'react'; import { TeamDetailProps } from 'types/agenda/teamDetail/TeamDetailTypes'; import { transformTeamLocation } from 'utils/agenda/transformLocation'; +import { Coalition } from 'constants/agenda/agenda'; +import Participant from 'components/agenda/agendaDetail/tabs/Participant'; +import { AddElementBtn, CancelBtn } from 'components/agenda/button/Buttons'; import CheckBoxInput from 'components/agenda/Input/CheckboxInput'; import DescriptionInput from 'components/agenda/Input/DescriptionInput'; import SelectInput from 'components/agenda/Input/SelectInput'; @@ -11,10 +15,16 @@ import styles from 'styles/agenda/Form/Form.module.scss'; interface AdminTeamFormProps { teamKey: string; teamData: TeamDetailProps; + teamLocation: string; } -const AdminTeamFrom = ({ teamKey, teamData }: AdminTeamFormProps) => { +const AdminTeamFrom = ({ + teamKey, + teamData, + teamLocation, +}: AdminTeamFormProps) => { const sendRequest = useFetchRequest().sendRequest; + const [teamMates, setTeamMates] = useState(teamData.teamMates); const transformFormData = (formData: FormData) => { const data = JSON.parse(JSON.stringify(Object.fromEntries(formData))); @@ -31,17 +41,44 @@ const AdminTeamFrom = ({ teamKey, teamData }: AdminTeamFormProps) => { return data; }; + const handleDeleteParticipant = (index: number) => { + setTeamMates((prev) => prev.filter((_, i) => i !== index)); + }; + + const isLeader = (intraId: string) => { + return teamData.teamLeaderIntraId === intraId; + }; + + const handleAddMember = () => { + const newMemberIdInput = document.getElementById( + 'newMemberId' + ) as HTMLInputElement; + const newMemberId = newMemberIdInput?.value.trim(); + + if (newMemberId === '') { + alert('intra ID를 입력해주세요.'); + return; + } + if (teamMates.some((member) => member.intraId === newMemberId)) { + alert('이미 존재하는 팀원입니다.'); + return; + } + setTeamMates((prev) => [ + ...prev, + { intraId: newMemberId, coalition: Coalition.OTHER }, + ]); + newMemberIdInput.value = ''; // 입력 필드 초기화 + }; + const SubmitTeamForm = (target: React.FormEvent) => { target.preventDefault(); const formData = new FormData(target.currentTarget); - // formData.delete('teamContent'); // 제거해야함 - const data = transformFormData(formData); if ( data.teamName === '' || - // data.teamContent === '' || + data.teamContent === '' || data.teamStatus === '' ) { alert('모든 항목을 입력해주세요.'); // 임시 @@ -49,7 +86,7 @@ const AdminTeamFrom = ({ teamKey, teamData }: AdminTeamFormProps) => { } data.teamKey = teamKey; - data.teamMates = teamData.teamMates; + data.teamMates = teamMates; data.teamAward = teamData.teamAward; data.teamAwardPriority = teamData.teamAwardPriority; @@ -68,7 +105,11 @@ const AdminTeamFrom = ({ teamKey, teamData }: AdminTeamFormProps) => { }; return ( - + { selected={teamData.teamStatus} /> - {teamData.teamLocation === 'MIX' ? ( + {teamLocation === 'MIX' ? ( ) : ( )} + { 상 순위 : {teamData.teamAwardPriority} + 팀원 + + + + + + {teamMates.map((participant, index) => ( + + + {!isLeader(participant.intraId) && ( + handleDeleteParticipant(index)} /> + )} + + ))} + { > 취소 - + 수정 diff --git a/components/agenda/Form/AdminTicketForm.tsx b/components/agenda/Form/AdminTicketForm.tsx new file mode 100644 index 000000000..a30c83b49 --- /dev/null +++ b/components/agenda/Form/AdminTicketForm.tsx @@ -0,0 +1,161 @@ +import { json } from 'stream/consumers'; +import { useState } from 'react'; +import { ITicket } from 'types/agenda/ticket/ticketTypes'; +import AgendaSelect from 'components/agenda/Input/AgendaSelect'; +import { useModal } from 'components/agenda/modal/useModal'; +import useFetchGet from 'hooks/agenda/useFetchGet'; +import useFetchRequest from 'hooks/agenda/useFetchRequest'; +import styles from 'styles/agenda/Form/Form.module.scss'; +import CheckboxInput from '../Input/CheckboxInput'; +import DateInput from '../Input/TimeInput'; + +interface userFormProps { + stringKey: string; + data: ITicket; + onProceed?: () => void; +} + +const AdminTicketForm = ({ stringKey, data, onProceed }: userFormProps) => { + const { closeModal } = useModal(); + const sendRequest = useFetchRequest().sendRequest; + const agendaList = useFetchGet('admin/list').data || []; + + const [issuedFromKey, setIssuedFromKey] = useState( + data.issuedFromKey ? data.issuedFromKey : '' + ); + const [usedToKey, setUsedToKey] = useState( + data.usedToKey ? data.usedToKey : '' + ); + const [isApproved, setIsApproved] = useState(data ? data.isApproved : false); + const [isUsed, setIsUsed] = useState(data ? data.isUsed : false); + + const handleissuedFrom = (e: { target: { value: any } }) => { + setIssuedFromKey(e.target.value); + }; + const handleusedTo = (e: { target: { value: any } }) => { + setUsedToKey(e.target.value); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + const formData = new FormData(e.currentTarget); + const jsonData: any = {}; + + formData.forEach((value, key) => { + jsonData[key] = value; + }); + + jsonData.issuedFromKey = issuedFromKey; + jsonData.usedToKey = usedToKey; + jsonData.isApproved = isApproved; + jsonData.isUsed = isUsed; + + if (!jsonData.issuedFromKey) { + alert('발급처는 반드시 선택해야 합니다.'); + return; + } + if ((jsonData.isUsed || jsonData.usedAt) && !jsonData.usedToKey) { + alert('사용처는 반드시 선택해야 합니다.'); + return; + } + + sendRequest( + 'PATCH', + 'admin/ticket', + jsonData, + { ticketId: data.ticketId }, + () => { + onProceed && onProceed(); + }, + (error: string) => { + console.error(error); + } + ); + }; + + return ( + { + handleSubmit(e); + }} + className={styles.container} + > + + IntraId : {stringKey} + + + 발급처 + + + + 사용처 + + + + setIsApproved(e.target.checked)} + /> + + {isApproved && ( + + + + )} + + setIsUsed(e.target.checked)} + /> + + {isUsed && ( + + + + )} + + + + + { + e.preventDefault(); + closeModal(); + }} + className={`${styles.formBtn} ${styles.cancel}`} + > + 취소 + + + 수정 + + + + ); +}; + +export default AdminTicketForm; diff --git a/components/agenda/Form/AgendaForm.tsx b/components/agenda/Form/AgendaForm.tsx index 2f4bce4f1..4491abc74 100644 --- a/components/agenda/Form/AgendaForm.tsx +++ b/components/agenda/Form/AgendaForm.tsx @@ -54,7 +54,7 @@ const AgendaForm = ({ ]); const [dateWarn, setDateWarn] = useState(['', '']); const [teamLimit, setTeamLimit] = useState([ - isEdit ? data.agendaMinPeople : 10, + isEdit ? data.agendaMinTeam : 10, isEdit ? data.agendaMaxTeam : 50, ]); const [peopleLimit, setPeopleLimit] = useState([ diff --git a/components/agenda/Form/TicketForm.tsx b/components/agenda/Form/TicketForm.tsx new file mode 100644 index 000000000..056b01b8a --- /dev/null +++ b/components/agenda/Form/TicketForm.tsx @@ -0,0 +1,83 @@ +import { useState } from 'react'; +import AgendaSelect from 'components/agenda/Input/AgendaSelect'; +import { useModal } from 'components/agenda/modal/useModal'; +import useFetchGet from 'hooks/agenda/useFetchGet'; +import useFetchRequest from 'hooks/agenda/useFetchRequest'; +import styles from 'styles/agenda/Form/Form.module.scss'; + +interface userFormProps { + stringKey: string; +} + +const TicketForm = ({ stringKey }: userFormProps) => { + const { closeModal } = useModal(); + const sendRequest = useFetchRequest().sendRequest; + const agendaList = useFetchGet('admin/list').data || []; + const [selectedAgendaKey, setSelectedAgendaKey] = useState(''); + + const handleSelectChange = (e: { target: { value: any } }) => { + setSelectedAgendaKey(e.target.value); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + const formData = new FormData(e.currentTarget); + const jsonData: any = {}; + + formData.forEach((value, key) => { + jsonData[key] = value; + }); + + jsonData.issuedFromKey = selectedAgendaKey; + + console.log('data', jsonData); + sendRequest( + 'POST', + 'admin/ticket', + jsonData, + { intraId: stringKey }, + () => { + closeModal(); + }, + (error: string) => { + console.error(error); + } + ); + }; + + return ( + { + handleSubmit(e); + }} + className={styles.container} + > + + IntraId : {stringKey} + + + + + { + e.preventDefault(); + closeModal(); + }} + className={`${styles.formBtn} ${styles.cancel}`} + > + 취소 + + + 수정 + + + + ); +}; + +export default TicketForm; diff --git a/components/agenda/Form/userForm.tsx b/components/agenda/Form/userForm.tsx new file mode 100644 index 000000000..d9cd2155b --- /dev/null +++ b/components/agenda/Form/userForm.tsx @@ -0,0 +1,108 @@ +import DescriptionInput from 'components/agenda/Input/DescriptionInput'; +import SelectInput from 'components/agenda/Input/SelectInput'; +import TitleInput from 'components/agenda/Input/TitleInput'; +import { useModal } from 'components/agenda/modal/useModal'; +import useFetchGet from 'hooks/agenda/useFetchGet'; +import useFetchRequest from 'hooks/agenda/useFetchRequest'; +import styles from 'styles/agenda/Form/Form.module.scss'; + +interface userFormProps { + stringKey: string; +} +interface dataType { + userIntraId: string; + userContent: string; + userGithub: string; + userLocation: string; +} + +const SubmitUserForm = async ( + e: React.FormEvent, + sendRequest: any, + data: any, + handleProceed?: () => void +) => { + e.preventDefault(); + const formData = new FormData(e.currentTarget); + const jsonData: any = {}; + + formData.forEach((value, key) => { + jsonData[key] = value; + }); + + sendRequest( + 'PATCH', + 'admin/profile', + jsonData, + { intraId: data.userIntraId }, + () => { + handleProceed && handleProceed(); + }, + (error: string) => { + console.error(error); + } + ); +}; + +const UserForm = ({ stringKey }: userFormProps) => { + const { closeModal } = useModal(); + const sendRequest = useFetchRequest().sendRequest; + + const { data }: { data: dataType | null } = useFetchGet( + `profile/${stringKey}` + ); + + if (!data) { + return loading...; + } + + return ( + { + SubmitUserForm(e, sendRequest, data, closeModal); + }} + className={styles.container} + > + + IntraId : {data.userIntraId} + + + + + + + + { + e.preventDefault(); + closeModal(); + }} + className={`${styles.formBtn} ${styles.cancel}`} + > + 취소 + + + 수정 + + + + ); +}; + +export default UserForm; diff --git a/components/agenda/Input/AgendaSelect.tsx b/components/agenda/Input/AgendaSelect.tsx new file mode 100644 index 000000000..9ecd59dde --- /dev/null +++ b/components/agenda/Input/AgendaSelect.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import MenuItem from '@mui/material/MenuItem'; +import Select from '@mui/material/Select'; +import { AgendaListProps } from 'types/agenda/agendaDetail/agendaTypes'; + +interface AgendaSelectProps { + selectedKey: string; + dataList: any; + handleSelectChange: (event: { target: { value: any } }) => void; +} + +const AgendaSelect = ({ + selectedKey, + dataList, + handleSelectChange, +}: AgendaSelectProps) => { + return ( + + + Choose an agenda... + + {Array.isArray(dataList) && + dataList.map((agenda) => ( + + {agenda.agendaTitle} + + ))} + + ); +}; + +export default AgendaSelect; diff --git a/components/agenda/button/Buttons.tsx b/components/agenda/button/Buttons.tsx index 70e02faa5..1b4e9d03e 100644 --- a/components/agenda/button/Buttons.tsx +++ b/components/agenda/button/Buttons.tsx @@ -6,7 +6,11 @@ const CancelBtn = ({ onClick: (e: React.MouseEvent) => void; }) => { return ( - onClick(e)}> + onClick(e)} + > ); @@ -54,7 +58,11 @@ const AddElementBtn = ({ onClick: (e: React.MouseEvent) => void; }) => { return ( - onClick(e)}> + onClick(e)} + > ); @@ -66,7 +74,11 @@ const RemoveElementBtn = ({ onClick: (e: React.MouseEvent) => void; }) => { return ( - onClick(e)}> + onClick(e)} + > ); diff --git a/components/agenda/utils/coalition/getCoalitionEnum.tsx b/components/agenda/utils/coalition/getCoalitionEnum.tsx index 99ce61298..34494039e 100644 --- a/components/agenda/utils/coalition/getCoalitionEnum.tsx +++ b/components/agenda/utils/coalition/getCoalitionEnum.tsx @@ -1,7 +1,13 @@ import { coalitionValues } from 'types/agenda/coalitionTypes'; import { Coalition } from 'constants/agenda/agenda'; -export function getCoalitionEnum(input: string[] | Coalition[]): Coalition[] { +export function getCoalitionEnum( + input: string[] | Coalition[] | string | Coalition +): Coalition[] { + if (!Array.isArray(input)) { + return getCoalitionEnum([input]); + } + return input .map((item) => { if (typeof item === 'string') { diff --git a/constants/admin/agendaTable.ts b/constants/admin/agendaTable.ts index d8daa5136..6447040d2 100644 --- a/constants/admin/agendaTable.ts +++ b/constants/admin/agendaTable.ts @@ -32,6 +32,7 @@ export const agendaTableFormat: AgendaTableFormat = { columns: [ 'teamName', 'teamLeaderIntraId', + 'teamLocation', 'teamMateCount', 'teamIsPrivate', 'teamAward', @@ -77,5 +78,9 @@ export const agendaTableFormat: AgendaTableFormat = { user: { name: '사용자 정보', columns: ['id', 'roleType', 'intraId', 'etc'], + etc: { + type: 'button', + value: ['프로필', '티켓발급', '티켓조회'], + }, }, }; diff --git a/pages/admin/agenda/index.tsx b/pages/admin/agenda/index.tsx new file mode 100644 index 000000000..46acf2fa6 --- /dev/null +++ b/pages/admin/agenda/index.tsx @@ -0,0 +1,6 @@ +import styles from 'styles/admin/index.module.scss'; +const AdminAgenda = () => { + return agenda admin main page; +}; + +export default AdminAgenda; diff --git a/pages/admin/agenda/teamModify.tsx b/pages/admin/agenda/teamModify.tsx index 4ed8e67f9..6e6715c98 100644 --- a/pages/admin/agenda/teamModify.tsx +++ b/pages/admin/agenda/teamModify.tsx @@ -5,7 +5,7 @@ import useFetchGet from 'hooks/agenda/useFetchGet'; import styles from 'styles/agenda/pages/create-team.module.scss'; const TeamModify = () => { - const { team_key } = router.query; + const { team_key, location } = router.query; const teamData = useFetchGet('admin/team', { team_key: team_key as string, @@ -17,7 +17,11 @@ const TeamModify = () => { 팀 수정하기 팀 인원 : 3명-8명까지 가능 {teamData && ( - + )} > diff --git a/pages/admin/agenda/ticket.tsx b/pages/admin/agenda/ticket.tsx index a28fd6cca..90c435ff1 100644 --- a/pages/admin/agenda/ticket.tsx +++ b/pages/admin/agenda/ticket.tsx @@ -1,10 +1,15 @@ +import router from 'next/router'; import TicketTable from 'components/admin/agenda/ticket/TicketTable'; export default function Ticket() { + const { intraId } = router.query; + + if (!intraId) { + return 유저 목록에서 티켓조회를 클릭해주세요!; + } return ( <> - ticket - + > ); } diff --git a/pages/admin/agenda/userList.tsx b/pages/admin/agenda/userList.tsx index 6ec27be14..b09dd9178 100644 --- a/pages/admin/agenda/userList.tsx +++ b/pages/admin/agenda/userList.tsx @@ -3,7 +3,6 @@ import UserTable from 'components/admin/agenda/users/UserTable'; export default function userList() { return ( <> - users > ); diff --git a/pages/admin/index.tsx b/pages/admin/index.tsx index f806af513..596901a85 100644 --- a/pages/admin/index.tsx +++ b/pages/admin/index.tsx @@ -1,16 +1,5 @@ +import styles from 'styles/admin/index.module.scss'; + export default function Admin() { - return ( - - admin main page - - ); + return admin main page; } diff --git a/pages/admin/takgu/index.tsx b/pages/admin/takgu/index.tsx new file mode 100644 index 000000000..8bc4ac98e --- /dev/null +++ b/pages/admin/takgu/index.tsx @@ -0,0 +1,6 @@ +import styles from 'styles/admin/index.module.scss'; +const AdminTakgu = () => { + return 42gg admin main page; +}; + +export default AdminTakgu; diff --git a/styles/admin/agenda/TicketTable.module.scss b/styles/admin/agenda/TicketTable.module.scss deleted file mode 100644 index 9aaeb40c8..000000000 --- a/styles/admin/agenda/TicketTable.module.scss +++ /dev/null @@ -1,10 +0,0 @@ -.clickableCell { - font-weight: bold; - color: yellow; - text-decoration: underline; - cursor: pointer; -} - -.clickableCell:hover { - color: darkorange; -} diff --git a/styles/admin/index.module.scss b/styles/admin/index.module.scss new file mode 100644 index 000000000..39ee4ea32 --- /dev/null +++ b/styles/admin/index.module.scss @@ -0,0 +1,8 @@ +.index { + display: flex; + width: 100%; + height: 100%; + font-size: 2rem; + justify-content: center; + align-items: center; +} diff --git a/styles/agenda/Form/Form.module.scss b/styles/agenda/Form/Form.module.scss index c89ced0ed..5ce426afa 100644 --- a/styles/agenda/Form/Form.module.scss +++ b/styles/agenda/Form/Form.module.scss @@ -67,6 +67,10 @@ flex-direction: column; gap: 1rem; } + > h3 { + @include text('default'); + margin-left: 0.5rem; + } } .label_container { @@ -85,6 +89,11 @@ margin: 0.5rem; } +.label_title { + @include text('label'); + margin: 0rem 0.5rem 2rem; +} + .highlight { color: var(--highlight-violet); } @@ -113,3 +122,19 @@ @include textButton('cancel', 'default'); } } + +.ListContainer { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 1rem 2rem; + width: 100%; +} + +.input { + padding: 0.5rem; + background: none; + border: none; + border-bottom: var(--default-border); + -webkit-appearance: none; + appearance: none; +} diff --git a/types/agenda/agendaDetail/tabs/participantTypes.ts b/types/agenda/agendaDetail/tabs/participantTypes.ts index e2d7171ee..8692942ff 100644 --- a/types/agenda/agendaDetail/tabs/participantTypes.ts +++ b/types/agenda/agendaDetail/tabs/participantTypes.ts @@ -22,12 +22,13 @@ export interface ParticipantTeamListProps { // 개인 참가자 타입 export interface ParticipantProps { - teamName: string; + teamName?: string; teamLeaderIntraId?: string; teamMateCount?: number; teamAward?: string; awardPriority?: number; - coalitions: string[] | Coalition[]; + coalitions: string[] | Coalition[] | string | Coalition; + delete?: boolean; } export interface ParticipantTeamProps { diff --git a/types/agenda/ticket/ticketTypes.ts b/types/agenda/ticket/ticketTypes.ts new file mode 100644 index 000000000..99fb123a4 --- /dev/null +++ b/types/agenda/ticket/ticketTypes.ts @@ -0,0 +1,12 @@ +export interface ITicket { + ticketId: number; + createdAt?: string; + issuedFrom?: string; + issuedFromKey?: string; + usedTo?: string; + usedToKey?: string; + isApproved?: boolean; + approvedAt?: string; + isUsed?: boolean; + usedAt?: string; +}
팀 인원 : 3명-8명까지 가능
ticket
users