- {StackTags.length > 0 &&
- StackTags.map((StackTag) => {
- return (
-
- );
- })}
-
+
+
+ {StackTags.length > 0 &&
+ StackTags.map((StackTag) => {
+ return (
+
+ );
+ })}
+
+
diff --git a/src/component/project/publish/component.tsx b/src/component/project/publish/component.tsx
index a16d50e..2de2a24 100644
--- a/src/component/project/publish/component.tsx
+++ b/src/component/project/publish/component.tsx
@@ -453,9 +453,11 @@ export const DateSelector = ({
// 기술 스택 컴포넌트
export function StackInput({ onAddStackTag }: StackInputProps) {
const [inputStackTag, setInputStackTag] = useState
('');
+ const [alertShown, setAlertShown] = useState(false);
const changeStackTagInput = (e: ChangeEvent) => {
setInputStackTag(e.target.value);
+ setAlertShown(false);
};
const isEmptyValue = (value: string) => {
@@ -463,7 +465,7 @@ export function StackInput({ onAddStackTag }: StackInputProps) {
};
const addStackTag = () => {
- if (inputStackTag.length < 10) {
+ if (inputStackTag.length < 20) {
if (isEmptyValue(inputStackTag)) {
setInputStackTag('');
return;
@@ -483,8 +485,10 @@ export function StackInput({ onAddStackTag }: StackInputProps) {
onAddStackTag(newStackTag);
setInputStackTag('');
- } else {
- alert('10개 이상 불가능');
+ } else if (!alertShown) {
+ alert('최대 글자를 초과했습니다.');
+ setAlertShown(true);
+ setInputStackTag('');
}
};
@@ -506,13 +510,14 @@ export function StackInput({ onAddStackTag }: StackInputProps) {
onChange={changeStackTagInput}
onKeyDown={onkeyDown}
onBlur={onBlur}
- placeholder="스택을 입력해주세요 (최대 10개)"
+ placeholder="스택을 입력해주세요"
css={css`
background: none;
color: #fff;
font-size: 2rem;
letter-spacing: -0.6px;
cursor: pointer;
+ width: 80rem;
${theme.typography.body1}
&::placeholder {
color: #cbcbcb;
@@ -523,6 +528,173 @@ export function StackInput({ onAddStackTag }: StackInputProps) {
);
}
+export function StackInput2({ onAddStackTag }: StackInputProps) {
+ const [inputStackTag, setInputStackTag] = useState('');
+ const [isInputVisible, setInputVisible] = useState(false);
+
+ const changeStackTagInput = (e: ChangeEvent) => {
+ setInputStackTag(e.target.value);
+ };
+
+ const isEmptyValue = (value: string) => {
+ return !value.trim();
+ };
+
+ const addStackTag = () => {
+ if (inputStackTag.length < 100) {
+ if (isEmptyValue(inputStackTag)) {
+ setInputStackTag('');
+ return;
+ }
+
+ let newStackTag = inputStackTag.trim();
+ const regExp = /[{}[\]/?.;:|)*~`!^_+<>@#$%&\\=('"]/g;
+ if (regExp.test(newStackTag)) {
+ newStackTag = newStackTag.replace(regExp, '');
+ }
+ if (newStackTag.endsWith(',')) {
+ newStackTag = newStackTag.slice(0, newStackTag.length - 1);
+ }
+
+ if (isEmptyValue(newStackTag)) return;
+
+ onAddStackTag(newStackTag);
+
+ setInputStackTag('');
+ } else {
+ alert('10개 이상 불가능');
+ }
+ };
+
+ const onkeyDown = (e: React.KeyboardEvent) => {
+ const allowedCommand = [' ', 'Enter', ','];
+ if (allowedCommand.includes(e.key)) {
+ e.preventDefault();
+ addStackTag();
+ }
+ };
+
+ const onBlur = () => {
+ addStackTag();
+ setInputVisible(false);
+ };
+
+ const toggleInputVisibility = () => {
+ setInputVisible(!isInputVisible);
+ };
+
+ return (
+
+
+ {isInputVisible && (
+
+
+
+ )}
+
+ );
+}
+
+export const StackInputContainer = ({
+ onAddStackTag,
+}: {
+ onAddStackTag: (tag: string) => void;
+}) => {
+ const [newStackTag, setNewStackTag] = useState('');
+ const [stackTags, setStackTags] = useState([]);
+
+ const handleInputChange = (event: React.ChangeEvent) => {
+ setNewStackTag(event.target.value);
+ };
+
+ const handleAddStackTag = () => {
+ if (newStackTag.trim() !== '') {
+ onAddStackTag(newStackTag);
+ setStackTags([...stackTags, newStackTag]); // 스택 태그 추가
+ setNewStackTag('');
+ }
+ };
+
+ return (
+
+
+
+ {stackTags.map((tag) => (
+
+ {tag}
+
+ ))}
+
+
+
+ );
+};
+
export const OptionData = ({ data }: { data: any }) => {
const [options, setOptions] = useState([{ value: 0, label: '소속 클럽 없음' }]);
diff --git a/src/component/project/publish/hook.ts b/src/component/project/publish/hook.ts
index 5015ec5..7d51a9c 100644
--- a/src/component/project/publish/hook.ts
+++ b/src/component/project/publish/hook.ts
@@ -40,11 +40,21 @@ export const useFormFields = (State: any) => {
export default useFormFields;
export const extractSubstring = (input: string) => {
- const startIndex = input.indexOf('//');
- const endIndex = input.indexOf('.');
-
- if (startIndex !== -1 && endIndex !== -1) {
- return input.slice(startIndex + 2, endIndex);
+ const wwwIndex = input.indexOf('www');
+ if (wwwIndex !== -1) {
+ // 'www'가 있는 경우
+ const startIndex = input.indexOf('.', wwwIndex); // 'www' 다음의 첫 번째 '.'를 찾습니다.
+ const endIndex = input.indexOf('.', startIndex + 1); // 첫 번째 '.' 다음의 '.'를 찾습니다.
+ if (startIndex !== -1 && endIndex !== -1) {
+ return input.slice(startIndex + 1, endIndex); // 'www' 다음의 '.' 다음부터 추출합니다.
+ }
+ } else {
+ // 'www'가 없는 경우
+ const startIndex = input.indexOf('//');
+ const endIndex = input.indexOf('.');
+ if (startIndex !== -1 && endIndex !== -1) {
+ return input.slice(startIndex + 2, endIndex);
+ }
}
return null;
};
@@ -192,7 +202,7 @@ export const validateProjectData = (otherData: any) => {
alert('유효하지 않은 팀원 구성입니다');
return 'teamInfoContainer';
}
- const regex = /^(http|https):\/\/.*\.com$/;
+ const regex = /^(http|https):\/\/.*\./;
if (!otherData.projectLink.every((item: any) => regex.test(item.linkUrl.trim()))) {
alert('한 개 이상의 유효하지 않은 링크가 존재합니다');
return 'LinkContainer';