ScheduleForm.js 5.87 KB
Newer Older
Kim, Subin's avatar
Kim, Subin committed
1
import { useState, useEffect } from "react";
2
import { Redirect, useParams } from "react-router-dom";
Kim, Subin's avatar
Kim, Subin committed
3
import BtnGroup from "../Buttons/BtnGroup.js";
4
import scheduleApi from "../../apis/schedule.api";
Kim, Subin's avatar
Kim, Subin committed
5
import catchErrors from "../../utils/catchErrors.js";
Kim, Subin's avatar
Kim, Subin committed
6
7
8
import styles from "./form.module.scss";

const ScheduleForm = () => {
Kim, Subin's avatar
Kim, Subin committed
9
10
11
12
13
14
15
16
17
18
19
20
    const [schedule, setSchedule] = useState({
        title: "",
        startDate: "",
        endDate: "",
        startTime: "",
        endTime: "",
        allDay: "",
        location: "",
        memo: ""
    })
    const [disabled, setDisabled] = useState(true)
    const [success, setSuccess] = useState(false)
Kim, Subin's avatar
Kim, Subin committed
21
    const [error, setError] = useState("")
22
23
24
25
26
    const { scheduleId } = useParams()

    useEffect(() => {
        if (scheduleId) getOne(scheduleId)
    }, [])
Kim, Subin's avatar
Kim, Subin committed
27
28

    useEffect(() => {
Kim, Subin's avatar
Kim, Subin committed
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
        let isMounted = true;
        const checkInfo = { title: schedule.title, startDate: schedule.startDate, endDate: schedule.endDate }
        if (schedule.allDay !== "on") {
            checkInfo.startTime = schedule.startTime
            checkInfo.endTime = schedule.endTime
        } else {
            delete checkInfo.startTime
            delete checkInfo.endTime
        }
        if (isMounted) {
            const isSchedule = Object.values(checkInfo).every((el) => Boolean(el));
            isSchedule ? setDisabled(false) : setDisabled(true);
        }
        return () => {
            isMounted = false;
        };
    }, [schedule])

47
48
49
50
51
52
53
54
55
56
    async function getOne(id) {
        try {
            setError("")
            const resSchedule = await scheduleApi.getOne(id)
            setSchedule({ ...schedule, ...resSchedule })
        } catch (error) {
            catchErrors(error, setError)
        }
    }

Kim, Subin's avatar
Kim, Subin committed
57
58
59
60
61
62
63
64
65
66
    function handleChange(e) {
        const { name, value } = e.target
        if (name === "allDay") {
            schedule.allDay !== "on" ? setSchedule({ ...schedule, [name]: value }) : setSchedule({ ...schedule, [name]: "off" })
        } else if (name === "startDate") {
            setSchedule({ ...schedule, [name]: value, endDate: value })
        } else if (name === "startTime") {
            setSchedule({ ...schedule, [name]: value, endTime: value })
        } else setSchedule({ ...schedule, [name]: value })
    }
Kim, Subin's avatar
Kim, Subin committed
67
68
69
70
71

    async function handleSubmit(e) {
        e.preventDefault()
        try {
            setError("")
72
73
74
75
76
77
78
79
            if (scheduleId) {
                await scheduleApi.edit(scheduleId, schedule)
                alert('해당 일정이 성공적으로 수정되었습니다.')
            }
            else {
                await scheduleApi.submit(schedule)
                alert('해당 일정이 성공적으로 등록되었습니다.')
            }
Kim, Subin's avatar
Kim, Subin committed
80
            setSuccess(true)
Kim, Subin's avatar
Kim, Subin committed
81
82
83
        } catch (error) {
            catchErrors(error, setError)
        }
Kim, Subin's avatar
Kim, Subin committed
84
85
86
87
88
    }

    if (success) {
        return <Redirect to="/home" />
    }
Kim, Subin's avatar
Kim, Subin committed
89
90

    return (
91
        <form className="pt-5">
92
            <div>
93
                <input className={`form-control form-control-lg shadow-none rounded-0 px-1 mb-5 ${styles.textInput}`} type="text" name="title" value={schedule.title} placeholder="제목" aria-label="title" onChange={handleChange} autoFocus />
94
            </div>
Kim, Subin's avatar
Kim, Subin committed
95
            <div className="d-flex mb-4">
Kim, Subin's avatar
Kim, Subin committed
96
                <label className="col col-form-label align-self-center py-0">시작</label>
Kim, Subin's avatar
Kim, Subin committed
97
                <div className={schedule.allDay === "on" ? "col-7" : "col-5"}>
98
                    <input className={`form-control shadow-none ${styles.dateInput}`} type="date" name="startDate" value={schedule.startDate} aria-label="startDate" onChange={handleChange} />
Kim, Subin's avatar
Kim, Subin committed
99
                </div>
Kim, Subin's avatar
Kim, Subin committed
100
101
                <div className={"col-5 " + (schedule.allDay === "on" ? "d-none" : "d-block")}>
                    <input className={`form-control shadow-none ${styles.dateInput}`} type="time" name="startTime" aria-label="startTime" onChange={handleChange} />
Kim, Subin's avatar
Kim, Subin committed
102
103
104
                </div>
            </div>
            <div className="d-flex mb-3">
Kim, Subin's avatar
Kim, Subin committed
105
                <label className="col col-form-label align-self-center py-0">종료</label>
Kim, Subin's avatar
Kim, Subin committed
106
107
                <div className={schedule.allDay === "on" ? "col-7" : "col-5"}>
                    <input className={`form-control shadow-none ${styles.dateInput}`} type="date" name="endDate" value={schedule.endDate} aria-label="endDate" onChange={handleChange} />
Kim, Subin's avatar
Kim, Subin committed
108
                </div>
Kim, Subin's avatar
Kim, Subin committed
109
110
                <div className={"col-5 " + (schedule.allDay === "on" ? "d-none" : "d-block")}>
                    <input className={`form-control shadow-none ${styles.dateInput}`} type="time" name="endTime" value={schedule.endTime} aria-label="endTime" onChange={handleChange} />
Kim, Subin's avatar
Kim, Subin committed
111
112
                </div>
            </div>
Kim, Subin's avatar
Kim, Subin committed
113
            <div className="d-flex justify-content-end form-check mb-4">
Kim, Subin's avatar
Kim, Subin committed
114
                <input className={`form-check-input shadow-none ${styles.checkBox}`} type="checkbox" id="allDay" name="allDay" onChange={handleChange} />
Kim, Subin's avatar
Kim, Subin committed
115
116
117
118
119
                <label className="form-check-label ms-2" htmlFor="allDay">하루 종일</label>
            </div>
            <div className="d-flex justify-content-between align-items-center mb-4">
                <i className="col bi bi-geo-alt fs-3"></i>
                <div className="col-10">
Kim, Subin's avatar
Kim, Subin committed
120
                    <input className={`form-control shadow-none rounded-0 px-1 ${styles.textInput}`} type="text" name="location" placeholder="장소" aria-label="location" onChange={handleChange} />
Kim, Subin's avatar
Kim, Subin committed
121
122
123
124
125
                </div>
            </div>
            <div className="d-flex justify-content-between mb-5">
                <i className="col bi bi-journal-text fs-3"></i>
                <div className="col-10">
126
                    <textarea className={`form-control shadow-none ${styles.textArea}`} name="memo" value={schedule.memo} rows="5" onChange={handleChange}></textarea>
Kim, Subin's avatar
Kim, Subin committed
127
                </div>
Kim, Subin's avatar
Kim, Subin committed
128
            </div>
129
            <BtnGroup text={scheduleId}  disabled={disabled} handleSubmit={handleSubmit} />
Kim, Subin's avatar
Kim, Subin committed
130
131
132
133
134
        </form>
    )
}

export default ScheduleForm