Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 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
61 changes: 61 additions & 0 deletions src/api/admin/customerService/inquiry.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { ApiCommonBasicType } from '../../../models/apiCommon';
import type {
ApiAdminInquiry,
ApiAdminInquiryDetail,
InquiryAnswerBody,
} from '../../../models/inquiry';
import { httpClient } from '../../http.api';

export const getAllInquiries = async () => {
try {
const response = await httpClient.get<ApiAdminInquiry>(`/inquiry`);
return response.data.data;
} catch (e) {
console.error('전체 문의 조회 에러', e);
throw e;
}
};

export const getInquiryDetail = async (id: string) => {
try {
const response = await httpClient.get<ApiAdminInquiryDetail>(
`/inquiry/${id}`
);

return response.data.data;
} catch (e) {
console.error(e);
throw e;
}
};

export const postInquiryAnswer = async ({ id, answer }: InquiryAnswerBody) => {
try {
await httpClient.post<ApiCommonBasicType>(`/inquiry/${id}/answer`, {
answer,
});
} catch (e) {
console.error(e);
throw e;
}
};

export const patchInquiryAnswer = async ({ id, answer }: InquiryAnswerBody) => {
try {
await httpClient.patch<ApiCommonBasicType>(`/inquiry/${id}/answer`, {
answer,
});
} catch (e) {
console.error(e);
throw e;
}
};

export const deleteInquiry = async (id: string) => {
try {
await httpClient.delete<ApiCommonBasicType>(`/inquiry/${id}`);
} catch (e) {
console.error(e);
throw e;
}
};
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;
}
};
69 changes: 69 additions & 0 deletions src/api/admin/tag.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import type { ApiCommonBasicType } from '../../models/apiCommon';
import type { TagFormType } from '../../models/tags';
import { httpClient } from '../http.api';

export const postSkillTag = async (formData: FormData) => {
try {
await httpClient.post<ApiCommonBasicType>(`/skill-tag`, formData);
} catch (e) {
console.error(e);
throw e;
}
};

export const putSkillTag = async ({
formData,
id,
}: {
formData: FormData;
id: number;
}) => {
try {
await httpClient.put<ApiCommonBasicType>(`/skill-tag/${id}`, formData);
} catch (e) {
console.error(e);
throw e;
}
};

export const deleteSkillTag = async (id: number) => {
try {
await httpClient.delete<ApiCommonBasicType>(`/skill-tag/${id}`);
} catch (e) {
console.error(e);
throw e;
}
};

export const postPositionTag = async (name: string) => {
try {
await httpClient.post<ApiCommonBasicType>(`/position-tag`, { name });
} catch (e) {
console.error(e);
throw e;
}
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

포지션 태그 API에 입력 검증을 추가하세요.

빈 문자열이나 유효하지 않은 이름에 대한 검증이 필요합니다.

 export const postPositionTag = async (name: string) => {
+  if (!name || name.trim().length === 0) {
+    throw new Error('Tag name cannot be empty');
+  }
   try {
-    await httpClient.post<ApiCommonBasicType>(`/position-tag`, { name });
+    await httpClient.post<ApiCommonBasicType>(`/position-tag`, { name: name.trim() });
   } catch (e) {
     console.error(e);
     throw e;
   }
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const postPositionTag = async (name: string) => {
try {
await httpClient.post<ApiCommonBasicType>(`/position-tag`, { name });
} catch (e) {
console.error(e);
throw e;
}
};
export const postPositionTag = async (name: string) => {
if (!name || name.trim().length === 0) {
throw new Error('Tag name cannot be empty');
}
try {
await httpClient.post<ApiCommonBasicType>(`/position-tag`, { name: name.trim() });
} catch (e) {
console.error(e);
throw e;
}
};
🤖 Prompt for AI Agents
In src/api/admin/tag.api.ts around lines 38 to 45, the postPositionTag function
lacks input validation for the name parameter. Add validation to check if the
name is a non-empty string and meets any required format criteria before making
the HTTP POST request. If the validation fails, throw an appropriate error or
reject the input to prevent sending invalid data to the API.


export const putPositionTag = async ({
name,
id,
}: {
name: string;
id: number;
}) => {
try {
await httpClient.put<ApiCommonBasicType>(`/position-tag/${id}`, { name });
} catch (e) {
console.error(e);
throw e;
}
};

export const deletePositionTag = async (id: number) => {
try {
await httpClient.delete<ApiCommonBasicType>(`/position-tag/${id}`);
} catch (e) {
console.error(e);
throw e;
}
};
84 changes: 84 additions & 0 deletions src/components/admin/adminTags/AdminTagCRUD.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import styled from 'styled-components';
import { SendButton } from '../../user/customerService/inquiry/Inquiry.styled';

export const CRUDContainer = styled.form`
width: 100%;
height: 100%;
`;

export const CRUDWrapper = styled.div`
width: 70%;
height: 100%;
display: flex;
gap: 1rem;
font-size: 1.2rem;
justify-content: space-between;
`;

export const InfoContainer = styled.div`
display: flex;
height: 100%;
flex-direction: column;
gap: 1.5rem;
justify-content: center;
/* align-items: center; */
`;

export const CRUDButtonWrapper = styled.div`
display: grid;
gap: 1rem;
`;

export const CRUDButton = styled(SendButton)`
height: 2.3rem;
`;

export const CRUDTitleWrapper = styled.div`
display: flex;
align-items: center;
gap: 1rem;
`;

export const CRUDTitleHead = styled.span``;

export const CRUDTitle = styled.input`
border-bottom: 1px solid ${({ theme }) => theme.color.placeholder};
padding-left: 0.3rem;
font-size: 1rem;
`;

export const CRUDDefaultButton = styled.button`
svg {
width: 1rem;
height: 1rem;
}
`;

export const CRUDImgWrapper = styled.div`
display: flex;
align-items: center;
gap: 1rem;
`;

export const CRUDImgHead = styled.span``;

export const CRUDImg = styled.img`
width: 3rem;
border: 1px solid ${({ theme }) => theme.color.grey};
`;

export const CRUDImgExplore = styled(SendButton)`
cursor: pointer;
border-radius: ${({ theme }) => theme.borderRadius.primary};
padding: 0.4rem 1rem;
`;

export const CRUDImgExplain = styled.span`
max-width: 10rem;
`;

export const CRUDImgInput = styled.input`
visibility: hidden;
width: 0;
height: 0;
`;
Loading