SNU-Sigma / sigma-intelligence-community-web

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

이미지 미리 업로드 안 하고 미리보기 가능하게 하기

jihoon416 opened this issue · comments

  1. 게시물 업로드에서, 사진을 선택하면 무조건 사진이 업로드되게 됩니다. 이렇게 하지 않고, 사진을 선택했을 때는 미리보기만 보여주고 실제 게시물 등록할 때 사진도 같이 업로드되도록 하면 좋을 것 같습니다.

    참고 코드 https://svelte.dev/repl/b5333059a2f548809a3ac3f60a17a8a6?version=3.31.2

  2. (옵셔널) 추가적으로, 사진을 매번 새로 업로드할 필요 없이 하나씩 추가/삭제 할 수 있도록 아래 디자인 같은 모습을 따라갈 수 있도록 코드 구조가 바뀔 수 있으면 좋을 것 같습니다.

아래 이미지들은 캡처할 필요 없이 링크 타고 들어가서 Ctrl+S 누르면 svg 파일 형태로 저장이 되게 됩니다. 이들을 assets 폴더 안에 images 폴더를 새로 만들고 넣어주면 됩니다.

+버튼 : https://user-images.githubusercontent.com/63445490/218482134-857fdf27-4e62-463b-aca9-c3d5ca531f2d.svg 다운로드

x 버튼 : https://user-images.githubusercontent.com/63445490/218482215-041a1b07-dcf7-4045-ac5e-f18da067096c.svg 다운로드

2번에 대한 힌트 코드

<script lang="ts">
    import { toastStore } from '@skeletonlabs/skeleton'
    import { createImageUpload } from '../lib/util/createImageUpload'
    import { PostAPIImpl } from '../lib/infrastructure/sigma-api/PostAPIImpl'
    import OverlaySpinner from '../lib/ui/common/OverlaySpinner.svelte'
    import PlusIcon from '../assets/images/+.svg'
    import DeleteIcon from '../assets/images/X.svg'

    let isLoading = false

    let title = ''
    let description = ''
    let images: Array<string> = []

    const { files$, validFileTypes, handleMultiUpload } = createImageUpload()

    $: if ($files$) {
        ;(async () => {
            images = await handleMultiUpload()
        })()
    }

    function postUpload() {
        if (title.trim().length && description.trim().length) {
            isLoading = true
            PostAPIImpl.createPost({
                title,
                description,
                images,
            })
                .then(() => {
                    toastStore.trigger({
                        message: '게시글이 업로드 되었습니다.',
                        preset: 'success',
                    })
                })
                .catch(() => {
                    toastStore.trigger({
                        message:
                            '게시글 업로드 중 오류가 발생했습니다. 다시 시도해주세요.',
                        preset: 'error',
                    })
                })
                .finally(() => {
                    isLoading = false
                })
            // TODO: 게시글 목록으로 이동해야 함
        } else {
            toastStore.trigger({
                message: '제목과 내용이 비어있지 않아야 합니다.',
                preset: 'error',
            })
        }
    }
</script>

{#if isLoading}
    <OverlaySpinner />
{/if}
<div class="mx-auto flex w-11/12 flex-col items-center gap-3 pt-10">
    <div class="text-xl">게시글 작성하기</div>
    <input
        type="text"
        placeholder="제목"
        class="w-full text-sm"
        bind:value={title}
    />
    <textarea
        name="content"
        id="content"
        cols="30"
        rows="20"
        placeholder="게시글을 작성해주세요."
        class="w-full text-sm"
        bind:value={description}
    />
    <div class="relative w-full">
        <div
            class="flex gap-3 overflow-x-auto overflow-y-hidden whitespace-nowrap pt-3"
        >
            <div
                class="flex h-44 w-44 flex-shrink-0 items-center justify-center bg-surface-500"
            >
                <img src={PlusIcon} alt="" class="h-14 w-14" />
            </div>
            <div class="relative flex-shrink-0">
                <img
                    src={'https://picsum.photos/400/200'}
                    alt=""
                    class="h-44 w-44 object-cover"
                />
                <div class="absolute top-0 right-0 h-5 w-5 bg-error-900 p-0.5">
                    <img src={DeleteIcon} alt="" />
                </div>
            </div>
            <div class="relative flex-shrink-0">
                <img
                    src={'https://picsum.photos/500/300'}
                    alt=""
                    class="h-44 w-44 object-cover"
                />
                <div class="absolute top-0 right-0 h-5 w-5 bg-error-900 p-0.5">
                    <img src={DeleteIcon} alt="" />
                </div>
            </div>
        </div>
    </div>
</div>
<div class="absolute bottom-6 right-6">
    <button class="btn variant-filled-primary" on:click={postUpload}>
        게시
    </button>
</div>