#15. ๋งํฌ์„œ๋น„์Šค ๊ด€๋ฆฌ์žํ™”๋ฉด ๋ฐ ๋งํฌ๋ฆฌ์ŠคํŠธ ํŽธ์ง‘

 

#15. ๋งํฌ์„œ๋น„์Šค ๊ด€๋ฆฌ์žํ™”๋ฉด ๋ฐ ๋งํฌ๋ฆฌ์ŠคํŠธ ํŽธ์ง‘

โŽŸโŽœ๊ด€๋ฆฌ์ž ํ™”๋ฉด ์ œ์ž‘ โŒ˜ manager.jsx ( ์œ„์น˜: linkservice/client/src/component/manager.jsx ) -------------------------------------------------------------------------------------------------- CSS ์„ ๋จผ์ € ์ถ”๊ฐ€ํ•œ๋‹ค. ( links.css ํŒŒ์ผ์— ์ถ”

firstvalue.tistory.com

์šฐ์„  ๋งํฌ์ •๋ณด๋ฅผ ํŽธ์ง‘ํ•˜๋ฉด์„œ ๋งํฌ์ •๋ณด๋ฅผ ์‚ญ์ œ์ฒ˜๋ฆฌ์‹œ ์ด๋ฏธ ๋“ฑ๋ก๋œ ์ด๋ฏธ์ง€๋ฅผ ์‚ญ์ œํ•˜๋Š” ๋ฐฑ์—”๋“œ๋ฅผ ์ œ์ž‘ํ•˜์ž

 

โŒ˜ links.py ( ์œ„์น˜: linkservice/server/src/links.py)

---------------------------------------------------------------------------------------------------

Python๋ฐฑ์—”๋“œ links.py์˜ LinkRemove(Resource) ์„ ์ˆ˜์ •ํ•œ๋‹ค.

๊ด€๋ จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ import ํ•œ๋‹ค. ( current_app, os )

from flask import jsonify, request, current_app
import os
"""
DELETE /api/link/delete/<int:id> - ๋งํฌ์ •๋ณด์‚ญ์ œ
"""
class LinkRemove(Resource):
    def delete(self, id):
        # id์— ํ•ด๋‹น๋˜๋Š” ๋งํฌ ์ •๋ณด ์กฐํšŒ
        link_data = LinkModel.find_by_id(id)
        folder = current_app.config.get('IMAGE_FORDER')
        # ์ด๋ฏธ์ง€ ๋งํฌ ํ•ญ๋ชฉ ๊ฐ€์ ธ์˜ค๊ธฐ
        if link_data.imageurl is not None:
            imageurl = link_data.imageurl.split('/')
            file_name = imageurl[len(imageurl) - 1]
            #ํŒŒ์ผ ์กด์žฌ์—ฌ๋ถ€ ํ™•์ธํ›„ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ์‚ญ์ œํ•œ๋‹ค.
            if os.path.isfile(folder + file_name):
                os.remove(folder + file_name)

        # ์ •๋ณด ์‚ญ์ œ ( links_model์˜ delete_by_id ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ )
        LinkModel.delete_by_id(id)

        return {'message':'์ •์ƒ์ ์œผ๋กœ ์‚ญ์ œ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.'},201

โŽŸโŽœ๋งํฌ์ •๋ณด๋ฅผ ํŽธ์ง‘ํ•˜๋Š” ํ™”๋ฉด ์ œ์ž‘

 

โŒ˜ links.edit.jsx ( ์œ„์น˜: linkservice/client/src/component/links.edit.jsx )

-------------------------------------------------------------------------------------------------

links.edit.jsx๋Š” ๋งํฌ ์ •๋ณด๋ฅผ ํŽธ์ง‘ ํ•˜๋Š” ํ™”๋ฉด์ด๋‹ค.

ํ™”๋ฉด ๊ตฌ์„ฑ๊ณผ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋“ค์€ ๋ชจ๋‘ ์‹ ๊ทœ ๋“ฑ๋ก(links.create.jsx) ๊ณผ ๋™์ผํ•˜๋ฉฐ,

 

๋‹จ useEffect์—์„œ ํŽธ์ง‘ํ•˜๊ณ ์ž ํ•˜๋Š” ๋งํฌ์ •๋ณด์˜ id ๊ฐ’์„ ๋ฐ›์•„ ์ถœ๋ ฅํ•˜๋Š” ๋ถ€๋ถ„๊ณผ handleSubmit์— ์—…๋ฐ์ดํŠธํ•˜๋Š”

์„œ๋น„์Šค๋ฅผ ์ถ”๊ฐ€ ํ•˜๋ฉด ๋œ๋‹ค.

 

import React, { useState, useEffect } from "react"
import { useParams, useNavigate } from "react-router-dom"
import linkService from "./service/service";
import {useDropzone} from 'react-dropzone'

export default function LinkEdit () {

    //id๊ฐ’์„ ๋ฐ›์•„์˜ค๊ธฐ ์œ„ํ•ด์„œ react์—์„œ ์ œ๊ณตํ•œ useParams์„ ํ™œ์šฉํ•œ๋‹ค.
    let params = useParams()
    const [data, setData] = useState({})
    const [values, setValues] = useState({})
    const [image, setImage] = useState(null)
    const [preview, setPreview] = useState('/assets/default.jpg')
    const navigate = useNavigate();

      useEffect(() => {
        linkService.getSelectLink(params.id).then(
            (res)=> {
            setData(res.data)
             // ์ˆ˜์ • ์„œ๋น„์Šค์ธ linkService.updateLink ์— ๋„˜๊ฒจ์ฃผ๊ธฐ ์œ„ํ•œ values            
            setValues(res.data.links)
            // preview์„ ์œ„ํ•œ setProview๊ฐ’ 
            setPreview(res.data.links.imageurl)
          }, (error) => {
            alert(error.res.data.message )
          }
          )
        // eslint-disable-next-line 
      }, [params.id])

      // Drag & Drap ๊ด€๋ จ ์‹คํ–‰ function 
      function onDrop(acceptedFiles) {
        const reader = new FileReader();
        const file = acceptedFiles
        if (file) {
          reader.readAsDataURL(file[0]);
          setImage(file[0]);
        }
        reader.onload = (e) => {
            setPreview(reader.result);
            setValues((prevValues) => ({
                ...prevValues,
                [`imageurl`]: file[0].name,
            }))
            document.getElementsByName("imageurl")[0].value = ''
        };
    }

    const handleChange = async (e) => {
        const nextValues = {
            ...values,
            [e.target.name]: e.target.value
        }
        setValues(nextValues)
        // ์‚ฌ์ง„๋งํฌ์ •๋ณด ์ž…๋ ฅ์‹œ preview๋ฅผ ์œ„ํ•œ set
        if (e.target.name === 'imagelink') {
            setPreview(e.target.value)
        }
    }

    const handleSubmit = async (e) => {
        e.preventDefault();
        const formData = new FormData();
        linkService.updateLink(params.id, values).then(
            (res)=> {
            // image file์„ ์„ ํƒ์‹œ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ๋ฅผ ์œ„ํ•ด์„œ ์ง„ํ–‰
            if (image) {
                formData.append('image', image)
                linkService.changeImage(formData, params.id).then(
                    (res)=> {
                    // console.log(res)
                    }
                )
            }
            alert(res.data.message)
            navigate("/links/list", { replace: true})

         }, (error) => {
            alert(error.res.data.message )
         }
        )
    }
    // Drag & Drop์„ ์œ„ํ•œ ๊ธฐ์กด const ์„ ์–ธ
    const {getRootProps, getInputProps} = useDropzone({onDrop})

    return (
        <div>
      {(typeof data.links ==='undefined') ? (
        <p>Loading....</p>
      ) : (
        <>            
            <div className="title-container">
                <h1 className="text-title">๋งํฌ ์ˆ˜์ •</h1>
            </div>

            <form  onSubmit={handleSubmit}>                            
                <div className="input-wrap">
                    <label>๋งํฌ๋ช…</label>
                    <div className="input-box">
                        <input type="text" name="name" 
                            defaultValue={data.links.name} 
                            className="input-css"
                            onChange={handleChange}
                            autoFocus="autofocus"
                        />  
                    </div> 
                </div>
                <div className="input-wrap">
                    <label>ํƒœ๊ทธ ์ •๋ณด ( ํƒœ๊ทธ์—ฌ๋Ÿฌ๊ฐœ ๋“ฑ๋ก์‹œ / ๋กœ ๊ตฌ๋ถ„ )</label>
                    <div className="input-box">
                        <input type="text" name="tag"
                            defaultValue={data.links.tag} 
                            className="input-css"
                            onChange={handleChange}
                        />
                    </div>
                </div>
                <div className="input-wrap">
                    <label>๋งํฌ URL (์—ฐ๊ฒฐํ•˜๊ณ ์ž ํ•˜๋Š” URL)</label>
                    <div className="input-box">                                 
                    <input type="text" name="linkurl" 
                        defaultValue={data.links.linkurl} 
                        className="input-css"
                        onChange={handleChange}
                        />    
                    </div>                                 
                </div>
                <div className="input-wrap">
                    <label>์‚ฌ์ง„ ๋งํฌ ์ •๋ณด</label>
                    <div className="input-box">                                 
                    <input type="text" name="imageurl" 
                        defaultValue={data.links.imageurl} 
                        className="input-css"
                        onChange={handleChange}
                        />     
                    </div>                                  
                </div>   
                <div className="img_contain" >
                    <div className="img_wrap" {...getRootProps()} > 
                        <img src =  { preview }
                            alt='์ด๋ฏธ์ง€' className="img_box" />
                        <input {...getInputProps()} multiple={false} name='imageurl'/>
                    </div> 
                        <div className="text_type">
                        <span>์‚ฌ์ง„ ๋งํฌ ์ •๋ณด๋ฅผ ๋“ฑ๋กํ•˜๊ฑฐ๋‚˜ <br></br>
                        ์ด๋ฏธ์ง€๋ฅผ ์ง์ ‘ ๋Œ์–ด์˜ค๊ฑฐ๋‚˜<br></br>
                        ํŒŒ์ผ์„ ์„ ํƒํ•ด์ฃผ์„ธ์š”</span>
                        </div>

                </div> 
                <div>
                    <button type="submit" className="btn btn-primary">์ˆ˜ ์ •</button>
                </div>
            </form>
            </>
         )}                          
        </div>
    )
}

๋งํฌ์ •๋ณด์— ๋Œ€ํ•œ ๋“ฑ๋ก/์ˆ˜์ •/์‚ญ์ œ๊ฐ€ ๋ชจ๋‘ ๋๋‚ฌ๋‹ค.

 

๋‹ค์ŒํŽธ์—๋Š” ๋งŒ๋“ค์–ด์ง„ ์†Œ์Šค๋กœ ์ข€๋” ํ•„์š”ํ•œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๊ธฐ๋Šฅ๊ณผ ๋””ํ…Œ์ผํ•œ ์ž‘์—…์„ ์ง„ํ–‰ํ•ด ๋ณด์ž.

+ Recent posts