Skip to content

Commit

Permalink
Merge pull request #81 from BCSDLab/feature/#71
Browse files Browse the repository at this point in the history
Feature/#71 글쓰기 페이지
  • Loading branch information
hyejun0228 authored Jul 24, 2023
2 parents 3425801 + b6545bc commit b8521e1
Show file tree
Hide file tree
Showing 17 changed files with 364 additions and 213 deletions.
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export default function App(): JSX.Element {
<Suspense fallback={<div />}>
<Routes>
<Route path="/" element={<DefaultLayout />}>
<Route path="/post" element={<Post />} />
<Route path="/search" element={<Search />} />
<Route path="/search/:keyword" element={<SearchDetails />} />
<Route path="/inquiry" element={<Inquiry />} />
Expand All @@ -43,6 +42,7 @@ export default function App(): JSX.Element {
<Route path="/friend-list" element={<FollowPage />} />
</Route>
<Route path="/withdrawal" element={<Withdrawal />} />
<Route path="/post" element={<Post />} />
</Route>
<Route element={<AuthRoute needAuth={false} redirectRoute="/" />}>
<Route path="/login" element={<Login />} />
Expand Down
4 changes: 4 additions & 0 deletions src/assets/svg/post/cancel.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/assets/svg/post/picture.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/components/MyInquiry/MyInquiry.module.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
$highlight: #ff7f23;

.my-inquiry {
.title {
display: flex;
justify-content: center;
align-items: center;
Expand All @@ -18,6 +18,6 @@ $highlight: #ff7f23;
text-decoration: none;
}

.move {
.move-icon {
margin-left: 9px;
}
8 changes: 4 additions & 4 deletions src/components/MyInquiry/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Link } from 'react-router-dom';
import { ReactComponent as Move } from 'assets/svg/inquiry/myinquiry.svg';
import { ReactComponent as MoveIcon } from 'assets/svg/inquiry/myinquiry.svg';
import styles from './MyInquiry.module.scss';

export default function MyInquiry(): JSX.Element {
return (
<div>
<Link to="/myinquiry" className={styles.link}>
<div className={styles['my-inquiry']}>
<div className={styles.title}>
나의 문의 바로가기
<div className={styles.move}>
<Move />
<div className={styles['move-icon']}>
<MoveIcon />
</div>
</div>
</Link>
Expand Down
4 changes: 3 additions & 1 deletion src/components/StarRating/StarRating.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
align-items: center;
width: 160px;
height: 32px;
margin-bottom: 24px;
margin-bottom: 16px;
}

.wrapper {
Expand All @@ -14,6 +14,8 @@
justify-content: center;
background: none;
border: none;
padding-top: 35px;
padding-bottom: 35px;

&__star {
transition: all 0.2s ease-out;
Expand Down
87 changes: 87 additions & 0 deletions src/components/editor/TextEditor/AddImage/AddImage.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
@use "src/utils/styles/mediaQuery" as media;

.container {
display: flex;
width: 100%;
white-space: nowrap;
overflow-x: scroll;
margin-left: 25px;

&__item {
display: flex;
margin: 14px 3px 0;
position: relative;
}

&__button {
position: absolute;
width: 18px;
height: 18px;
margin-left: 62px;
border: solid 5px;
border-color: #ff7f23;
border-radius: 50%;
background-color: transparent;
z-index: 2;
}

&__image {
display: flex;
width: 80px;
height: 80px;
object-fit: cover;
border-radius: 10px;
cursor: pointer;
}

&::-webkit-scrollbar {
display: none;
scrollbar-width: none;
}
}

.editor {
line-height: 15px;
height: 650px;
width: 100%;
font-size: 16px;
color: #222222;
z-index: 1;

@include media.media-breakpoint-down(mobile) {
height: 340px;
}

&--withImage {
line-height: 15px;
height: 600px;
width: 100%;
font-size: 16px;
color: #222222;
z-index: 1;

@include media.media-breakpoint-down(mobile) {
height: 260px;
}
}

&__add-image {
display: flex;
justify-content: center;
z-index: 2;
background-color: white;
width: 48px;
height: 48px;
align-items: center;
border-radius: 50px;
box-shadow: 2px 3px 12px 1px rgb(0 0 0 / 10%);
position: fixed;
right: 35px;
bottom: 55px;
cursor: pointer;

input {
display: none;
}
}
}
33 changes: 13 additions & 20 deletions src/components/editor/TextEditor/AddImage/ImageItem.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,32 @@
import { ReactComponent as Trash } from 'assets/svg/post/trash.svg';
import { ReactComponent as Trash } from 'assets/svg/post/cancel.svg';
import { useRef } from 'react';
import useBooleanState from 'utils/hooks/useBooleanState';
import useOnClickOutside from 'utils/hooks/useOnClickOutside';
import styles from '../TextEditor.module.scss';
import styles from './AddImage.module.scss';

interface Props {
value: string,
onDelete: (value: string) => void,
}

export default function ImageItem({ value, onDelete }: Props) {
const [opened, open, close] = useBooleanState(false);
const imageRef = useRef<HTMLInputElement>(null);
useOnClickOutside(imageRef, close);

return (
<>
{ opened && (
<button
type="button"
aria-label="trash"
className={styles['image-container__button']}
onClick={() => onDelete(value)}
>
<Trash />
</button>
)}
<div>
<button
type="button"
aria-label="trash"
className={styles.container__button}
onClick={() => onDelete(value)}
>
<Trash />
</button>
<input
type="image"
alt=""
className={styles['image-container__image']}
className={styles.container__image}
src={value}
ref={imageRef}
onClick={open}
/>
</>
</div>
);
}
51 changes: 32 additions & 19 deletions src/components/editor/TextEditor/AddImage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,51 @@
import { ReactComponent as Picture } from 'assets/svg/post/picture.svg';
import { useEffect } from 'react';
import styles from '../TextEditor.module.scss';
import { useEffect, useRef } from 'react';
import Wysiwyg, { WysiwygType } from 'components/editor/Wysiwyg';
import useBooleanState from 'utils/hooks/useBooleanState';
import cn from 'utils/ts/classNames';
import styles from './AddImage.module.scss';
import useImageList from '../hooks/useImageList';
import ImageItem from './ImageItem';

interface Props {
active: () => void,
inActive: () => void,
}

function AddImage({ active, inActive }: Props) {
function AddImage() {
const { imageList, addImage, removeImage } = useImageList();
const wysiwygRef = useRef<WysiwygType | null>(null);
const [opened, active, inActive] = useBooleanState(false);
useEffect(() => {
if (imageList === null || imageList.length === 0) inActive();
else active();
}, [imageList, active, inActive]);

return (
<>
<button
type="button"
className={styles.item__button}
onClick={addImage}
>
<Picture />
</button>
<div className={styles['image-container']}>
<div>
<div className={styles.container}>
{ imageList?.map((value) => (
<div key={value} className={styles['image-container__item']}>
<div key={value} className={styles.container__item}>
<ImageItem value={value} onDelete={removeImage} />
</div>
))}
</div>
</>
<div
className={cn({
[styles.editor]: true,
[styles['editor--withImage']]: opened,
})}
>
<Wysiwyg ref={wysiwygRef} />
</div>
<div className={styles['button-container']}>
<label htmlFor="image" className={styles['editor__add-image']}>
<Picture />
<input
type="file"
onChange={addImage}
id="image"
multiple
accept="image/jpeg,image/gif,image/png"
/>
</label>
</div>
</div>
);
}

Expand Down
47 changes: 47 additions & 0 deletions src/components/editor/TextEditor/AddImageFile/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, { useState, ChangeEvent } from 'react';
import { ReactComponent as Plus } from 'assets/svg/post/picture.svg';
import styles from './AddImageFile.module.scss';

function AddImageFile() {
const [imageSrc, setImageSrc] = useState<string>();

const encodeFileToBase64 = (fileBlob: Blob) => {
const reader = new FileReader();
reader.readAsDataURL(fileBlob);
return new Promise<void>((resolve) => {
reader.onload = () => {
setImageSrc(reader.result as string);
resolve();
};
});
};

const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
const file = e.target.files && e.target.files[0];
if (file) {
encodeFileToBase64(file);
}
};

return (
<main>
<label htmlFor="image">
<div className={styles.getImage}>
<Plus className={styles.getImage__Image} />
</div>
<input
type="file"
onChange={handleFileChange}
id="image"
className={styles.input}
multiple
/>
</label>
<div>
{imageSrc && <img src={imageSrc} alt="preview-img" width="80" height="80" className={styles.preview} />}
</div>
</main>
);
}

export default AddImageFile;
Loading

0 comments on commit b8521e1

Please sign in to comment.