Skip to content

Commit

Permalink
Feat - 개발자 테스트 링크. 스택 이슈 개선 (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
cheonseunghyeon committed Sep 26, 2023
1 parent 6ebed1d commit cb62173
Show file tree
Hide file tree
Showing 3 changed files with 219 additions and 25 deletions.
42 changes: 27 additions & 15 deletions src/component/project/publish/ProjectPublish.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import {
StackInput,
DateRanges,
CustomSelect,
StackInputContainer,
StackInput2,
} from './component';
import {
updateProjectCrew,
Expand Down Expand Up @@ -115,8 +117,8 @@ const ProjectPublish = () => {
const doAsyncWork = async (data: any) => {
try {
await mutation[0]({ accessToken, newProjectData: data });
console.log(data);
navigate('/project');
// console.log(data);
} catch (error) {
console.error('데이터 전송 중 오류 발생:', error);
navigate('/project/publish');
Expand Down Expand Up @@ -173,10 +175,6 @@ const ProjectPublish = () => {
display: none;
`}
/>
<TagList>
<Tag>서비스 형태가 들어가요</Tag>
<Tag>소속 클럽 이름이 들어가요</Tag>
</TagList>

<Section gap="0.8">
<TextInputBox
Expand Down Expand Up @@ -304,16 +302,30 @@ const ProjectPublish = () => {
{/* <DateSelector onDateRangeChange={DateRangeChange} /> */}

<Header2>사용된 기술 스택</Header2>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.8rem' }}>
{StackTags.length > 0 &&
StackTags.map((StackTag) => {
return (
<button type="button" key={v4()} onClick={() => removeStackTag(StackTag)}>
<Tag>{StackTag}</Tag>
</button>
);
})}
<StackInput onAddStackTag={AddStackTag} />
<div
style={{
display: 'flex',
maxWidth: '80rem',
}}
>
<div
style={{
display: 'flex',
alignItems: 'center',
gap: '0.8rem',
flexWrap: 'wrap',
}}
>
{StackTags.length > 0 &&
StackTags.map((StackTag) => {
return (
<button type="button" key={v4()} onClick={() => removeStackTag(StackTag)}>
<Tag>{StackTag}</Tag>
</button>
);
})}
<StackInput onAddStackTag={AddStackTag} />
</div>
</div>
</GridBox>
</ContainerComponent>
Expand Down
180 changes: 176 additions & 4 deletions src/component/project/publish/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -453,17 +453,19 @@ export const DateSelector = ({
// 기술 스택 컴포넌트
export function StackInput({ onAddStackTag }: StackInputProps) {
const [inputStackTag, setInputStackTag] = useState<string>('');
const [alertShown, setAlertShown] = useState<boolean>(false);

const changeStackTagInput = (e: ChangeEvent<HTMLInputElement>) => {
setInputStackTag(e.target.value);
setAlertShown(false);
};

const isEmptyValue = (value: string) => {
return !value.trim();
};

const addStackTag = () => {
if (inputStackTag.length < 10) {
if (inputStackTag.length < 20) {
if (isEmptyValue(inputStackTag)) {
setInputStackTag('');
return;
Expand All @@ -483,8 +485,10 @@ export function StackInput({ onAddStackTag }: StackInputProps) {
onAddStackTag(newStackTag);

setInputStackTag('');
} else {
alert('10개 이상 불가능');
} else if (!alertShown) {
alert('최대 글자를 초과했습니다.');
setAlertShown(true);
setInputStackTag('');
}
};

Expand All @@ -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;
Expand All @@ -523,6 +528,173 @@ export function StackInput({ onAddStackTag }: StackInputProps) {
);
}

export function StackInput2({ onAddStackTag }: StackInputProps) {
const [inputStackTag, setInputStackTag] = useState<string>('');
const [isInputVisible, setInputVisible] = useState(false);

const changeStackTagInput = (e: ChangeEvent<HTMLInputElement>) => {
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<HTMLInputElement>) => {
const allowedCommand = [' ', 'Enter', ','];
if (allowedCommand.includes(e.key)) {
e.preventDefault();
addStackTag();
}
};

const onBlur = () => {
addStackTag();
setInputVisible(false);
};

const toggleInputVisibility = () => {
setInputVisible(!isInputVisible);
};

return (
<div style={{ position: 'relative' }}>
<button
type="button"
onClick={toggleInputVisibility}
style={{
background: 'none',
fontSize: '2rem',
letterSpacing: '-0.6px',
cursor: 'pointer',
color: '#cbcbcb',
}}
>
스택을 입력해주세요 (최대 10개)
</button>
{isInputVisible && (
<div
style={{
position: 'absolute',
top: '100%',
left: 0,
zIndex: 2,
width: '100%',
backgroundColor: 'white',
boxShadow: '0px 10px 10px 10px rgba(0, 0, 0, 0.5)',
}}
>
<input
type="text"
value={inputStackTag}
onChange={changeStackTagInput}
onKeyDown={onkeyDown}
onBlur={onBlur}
/>
</div>
)}
</div>
);
}

export const StackInputContainer = ({
onAddStackTag,
}: {
onAddStackTag: (tag: string) => void;
}) => {
const [newStackTag, setNewStackTag] = useState('');
const [stackTags, setStackTags] = useState<string[]>([]);

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setNewStackTag(event.target.value);
};

const handleAddStackTag = () => {
if (newStackTag.trim() !== '') {
onAddStackTag(newStackTag);
setStackTags([...stackTags, newStackTag]); // 스택 태그 추가
setNewStackTag('');
}
};

return (
<div style={{ position: 'relative' }}>
<input
type="text"
placeholder="Add Stack Tag"
value={newStackTag}
onChange={handleInputChange}
style={{
zIndex: 1,
padding: '0.5rem',
fontSize: '1rem',
border: '1px solid #ccc',
}}
/>
<div
style={{
position: 'absolute',
top: '100%',
left: 0,
zIndex: 2,
width: '100%', // 너비를 조절하여 입력 필드와 동일하게 확장
backgroundColor: 'white',
boxShadow: '0px 10px 10px 10px rgba(0, 0, 0, 0.5)',
}}
>
{stackTags.map((tag) => (
<div key={tag} style={{ padding: '0.5rem', color: '#000' }}>
{tag}
</div>
))}
</div>
<button
type="button"
onClick={handleAddStackTag}
style={{
position: 'absolute',
right: '0',
top: '50%',
transform: 'translateY(-50%)',
padding: '0.5rem 1rem',
background: 'blue',
color: 'white',
cursor: 'pointer',
zIndex: 2,
}}
>
Add
</button>
</div>
);
};

export const OptionData = ({ data }: { data: any }) => {
const [options, setOptions] = useState([{ value: 0, label: '소속 클럽 없음' }]);

Expand Down
22 changes: 16 additions & 6 deletions src/component/project/publish/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down Expand Up @@ -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';
Expand Down

0 comments on commit cb62173

Please sign in to comment.