Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
students
Today KU
Commits
660e363c
"client/git@compmath.korea.ac.kr:students/butter-studio.git" did not exist on "4e907cdc099892e32022c0b860ae0a9107f55c25"
Commit
660e363c
authored
Nov 05, 2021
by
Kim, Subin
Browse files
Merge branch 'kimpen'
parents
52f6e103
b7b819be
Changes
15
Hide whitespace changes
Inline
Side-by-side
client/src/apis/todo.api.js
View file @
660e363c
...
...
@@ -6,6 +6,11 @@ const getTodo = async (userId, date = "", todoId = "") => {
return
data
}
const
getTodopercent
=
async
(
userId
,
start
,
end
=
""
)
=>
{
const
{
data
}
=
await
axios
.
get
(
`
${
baseUrl
}
/api/todo/percent/
${
userId
}
?start=
${
start
}
&end=
${
end
}
`
)
return
data
}
const
submit
=
async
(
todo
,
userId
)
=>
{
const
{
data
}
=
await
axios
.
post
(
`
${
baseUrl
}
/api/todo/
${
userId
}
`
,
todo
)
return
data
...
...
@@ -23,6 +28,7 @@ const remove = async (todoId, userId) => {
const
todoApi
=
{
getTodo
,
getTodopercent
,
submit
,
edit
,
remove
...
...
client/src/components/Form/ScheduleForm.js
View file @
660e363c
...
...
@@ -97,7 +97,7 @@ const ScheduleForm = () => {
return
(
<
form
className
=
"
pt-5
"
>
<
div
>
<
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
/>
<
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
autoComplete
=
"
off
"
/>
<
/div
>
<
div
className
=
"
d-flex mb-4
"
>
<
label
className
=
"
col col-form-label align-self-center py-0
"
>
시작
<
/label
>
...
...
client/src/components/Form/StudyPlanEditForm.js
View file @
660e363c
...
...
@@ -119,7 +119,7 @@ const StudyPlanEditForm = () => {
<
/select
>
<
input
type
=
"
text
"
name
=
"
studyplanTitle
"
className
=
{
`form-control shadow-none rounded-0 mb-5
${
styles
.
textInput
}
`
}
placeholder
=
"
제목
"
value
=
{
studyplan
.
studyplanTitle
}
onChange
=
{
handleChange
}
/
>
placeholder
=
"
제목
"
value
=
{
studyplan
.
studyplanTitle
}
onChange
=
{
handleChange
}
autoComplete
=
"
off
"
/>
<
div
className
=
"
d-flex mb-3
"
>
<
label
className
=
"
col col-form-label align-self-center py-0
"
>
마감일
<
/label
>
<
div
className
=
{
studyplan
.
deadline
===
"
on
"
?
"
col-5
"
:
"
col-7
"
}
>
...
...
client/src/components/Form/SubjectForm.js
View file @
660e363c
...
...
@@ -83,15 +83,15 @@ const SubjectForm = () => {
<
div
>
<
div
className
=
"
mb-5 d-flex flex-row
"
>
<
label
className
=
"
form-label fs-4
"
style
=
{{
width
:
"
100px
"
}}
>
강의명
<
/label
>
<
input
className
=
{
`form-control shadow-none rounded-0
${
styles
.
textInput
}
`
}
value
=
{
subject
.
lectureName
}
name
=
"
lectureName
"
onChange
=
{
handleChange
}
/
>
<
input
className
=
{
`form-control shadow-none rounded-0
${
styles
.
textInput
}
`
}
value
=
{
subject
.
lectureName
}
name
=
"
lectureName
"
onChange
=
{
handleChange
}
autoComplete
=
"
off
"
/>
<
/div
>
<
div
className
=
"
mb-5 pt-2 d-flex flex-row
"
>
<
label
className
=
"
form-label fs-4
"
style
=
{{
width
:
"
100px
"
}}
>
교수명
<
/label
>
<
input
className
=
{
`form-control shadow-none rounded-0
${
styles
.
textInput
}
`
}
value
=
{
subject
.
prof
}
name
=
"
prof
"
onChange
=
{
handleChange
}
/
>
<
input
className
=
{
`form-control shadow-none rounded-0
${
styles
.
textInput
}
`
}
value
=
{
subject
.
prof
}
name
=
"
prof
"
onChange
=
{
handleChange
}
autoComplete
=
"
off
"
/>
<
/div
>
<
div
className
=
"
mb-5 pt-2 d-flex flex-row
"
>
<
label
className
=
"
form-label fs-4
"
style
=
{{
width
:
"
100px
"
,
letterSpacing
:
"
15px
"
}}
>
장소
<
/label
>
<
input
className
=
{
`form-control shadow-none rounded-0
${
styles
.
textInput
}
`
}
value
=
{
subject
.
classRoom
}
name
=
"
classRoom
"
onChange
=
{
handleChange
}
/
>
<
input
className
=
{
`form-control shadow-none rounded-0
${
styles
.
textInput
}
`
}
value
=
{
subject
.
classRoom
}
name
=
"
classRoom
"
onChange
=
{
handleChange
}
autoComplete
=
"
off
"
/>
<
/div
>
<
/div
>
<
div
className
=
"
pt-2
"
>
...
...
client/src/components/Menu/Menu.js
View file @
660e363c
...
...
@@ -8,7 +8,7 @@ import styles from "./menu.module.scss";
const
Menu
=
()
=>
{
const
{
user
,
logout
}
=
useAuth
();
const
[
todoList
,
setTodoList
]
=
useState
(
[]
)
const
[
todoList
,
setTodoList
]
=
useState
(
{
percent
:
0
,
list
:
[]
}
)
const
[
error
,
setError
]
=
useState
(
""
);
useEffect
(()
=>
{
...
...
@@ -18,9 +18,9 @@ const Menu = () => {
async
function
todayTodo
()
{
try
{
setError
(
""
)
const
result
=
await
todoApi
.
getTodo
(
user
.
id
,
moment
().
format
(
"
YYYY-MM-DD
"
))
const
result
=
await
todoApi
.
getTodo
percent
(
user
.
id
,
moment
().
format
(
"
YYYY-MM-DD
"
))
console
.
log
(
"
client resList
"
,
result
)
setTodoList
(
result
)
setTodoList
(
{...
todoList
,
...
result
}
)
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
}
...
...
@@ -36,23 +36,17 @@ const Menu = () => {
<
button
type
=
"
button
"
className
=
{
`btn-close btn-close-white btn-lg position-absolute
${
styles
.
close
}
`
}
data
-
bs
-
toggle
=
"
collapse
"
data
-
bs
-
target
=
"
#menuContent
"
aria
-
controls
=
"
menuContent
"
aria
-
expanded
=
"
true
"
aria
-
label
=
"
menu
"
><
/button
>
<
div
className
=
"
d-flex flex-column align-items-center text-white py-5
"
style
=
{{
backgroundColor
:
"
crimson
"
}}
>
<
h1
className
=
"
my-3
"
>
{
user
.
name
}
님
<
/h1
>
<
h2
className
=
"
my-2
"
>
오늘의
목표
95
%
달성
!<
/h2
>
<
h2
className
=
"
my-2
"
>
오늘의
목표
{
todoList
.
percent
}
%
달성
!<
/h2
>
<
/div
>
<
div
className
=
"
d-flex flex-column justify-content-between flex-grow-1 py-4 ps-3 text-dark
"
>
<
div
className
=
"
user-select-none w-75 ps-3
"
>
<
h2
className
=
"
mb-5
"
>
To
-
do
<
/h2
>
<
div
className
=
"
d-flex mt-2
"
>
<
p
className
=
{
`form-check-label border-bottom border-2 fs-5 pb-1 me-3
${
styles
.
title
}
`
}
>
sdasdsasdasdsadsadsadsadsadsadsadaddad
<
/p
>
<
input
className
=
{
`form-check-input rounded-0 border-dark shadow-none mt-1
${
styles
.
checkBox
}
`
}
type
=
"
checkbox
"
id
=
"
inlineCheckbox1
"
value
=
""
aria
-
label
=
"
checkbox
"
/>
<
/div
>
<
div
className
=
"
d-flex
"
>
<
p
className
=
{
`form-check-label border-bottom border-2 fs-5 pb-1 me-3
${
styles
.
title
}
`
}
>
sdasdsadad
<
/p
>
<
input
className
=
{
`form-check-input rounded-0 border-dark shadow-none mt-1
${
styles
.
checkBox
}
`
}
type
=
"
checkbox
"
id
=
"
inlineCheckbox1
"
value
=
""
aria
-
label
=
"
checkbox
"
/>
<
/div
>
<
div
className
=
"
d-flex
"
>
<
p
className
=
{
`form-check-label border-bottom border-2 fs-5 pb-1 me-3
${
styles
.
title
}
`
}
>
sdasdsadad
<
/p
>
<
input
className
=
{
`form-check-input rounded-0 border-dark shadow-none mt-1
${
styles
.
checkBox
}
`
}
type
=
"
checkbox
"
id
=
"
inlineCheckbox1
"
value
=
""
aria
-
label
=
"
checkbox
"
/>
<
h2
className
=
"
mb-4
"
>
To
-
do
<
/h2
>
{
todoList
.
list
.
length
!==
0
?
todoList
.
list
.
map
((
todo
,
idx
)
=>
{
if
(
idx
<=
2
)
return
<
div
className
=
"
d-flex
"
>
<
p
className
=
{
`form-check-label border-bottom border-2 fs-5 pb-1 me-3
${
styles
.
title
}
`
}
>
{
todo
.
title
}
<
/p
>
<
input
className
=
{
`form-check-input rounded-0 border-dark shadow-none mt-1
${
styles
.
checkBox
}
`
}
type
=
"
checkbox
"
id
=
"
inlineCheckbox1
"
aria
-
label
=
"
checkbox
"
checked
=
{
todo
.
done
}
/
>
<
/div
>
})
:
null
}
<
Link
className
=
"
d-flex justify-content-center text-dark text-decoration-none
"
to
=
{
`/todo/
${
moment
().
format
(
"
YYYY-MM-DD
"
)}
`
}
>
<
i
className
=
"
bi bi-plus-lg me-2
"
><
/i
>
<
p
className
=
"
mb-0
"
>
더보기
<
/p
>
...
...
client/src/components/Modal/PlanAlertModal.js
deleted
100644 → 0
View file @
52f6e103
const
PlanAlertModal
=
({
planId
,
handleClick
})
=>
{
return
(
<
div
className
=
"
modal fade
"
id
=
"
planmodal
"
data
-
bs
-
backdrop
=
"
static
"
data
-
bs
-
keyboard
=
"
false
"
tabIndex
=
"
-1
"
aria
-
labelledby
=
"
planLabel
"
aria
-
hidden
=
"
true
"
>
<
div
className
=
"
modal-dialog modal-dialog-centered
"
>
<
div
className
=
"
modal-content
"
>
<
div
className
=
"
modal-body
"
>
관련
학업계획까지
삭제됩니다
.
정말
삭제하시겠습니까
?
<
/div
>
<
div
className
=
"
modal-footer p-1
"
>
<
button
type
=
"
button
"
className
=
"
btn btn-secondary btn-sm
"
data
-
bs
-
dismiss
=
"
modal
"
>
취소
<
/button
>
<
button
type
=
"
button
"
className
=
"
btn btn-crimson btn-sm
"
onClick
=
{()
=>
handleClick
(
planId
)}
>
삭제
<
/button
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
)
}
export
default
PlanAlertModal
\ No newline at end of file
client/src/components/Modal/TodoModal.js
View file @
660e363c
import
{
useState
,
useEffect
,
useRef
}
from
"
react
"
;
import
{
useState
,
useEffect
}
from
"
react
"
;
import
todoApi
from
"
../../apis/todo.api
"
;
import
{
useAuth
}
from
"
../../utils/context
"
;
import
catchErrors
from
"
../../utils/catchErrors
"
;
...
...
@@ -47,7 +47,6 @@ const TodoModal = ({ curDate, selectTodo = "" }) => {
return
(
<
div
className
=
"
modal fade
"
id
=
"
todomodal
"
data
-
bs
-
backdrop
=
"
static
"
data
-
bs
-
keyboard
=
"
false
"
tabIndex
=
"
-1
"
aria
-
labelledby
=
"
todoLabel
"
aria
-
hidden
=
"
true
"
>
{
console
.
log
(
"
Modal date==
"
,
curDate
,
selectTodo
)}
<
div
className
=
"
modal-dialog modal-dialog-centered
"
>
<
div
className
=
"
modal-content
"
style
=
{{
backgroundColor
:
"
crimson
"
}}
>
<
div
className
=
"
modal-header px-2 py-1
"
>
...
...
client/src/components/StudyPlan/AddplanList.js
View file @
660e363c
...
...
@@ -2,7 +2,7 @@ import PlanItem from "./PlanItem";
import
styles
from
"
./studyplan.module.scss
"
;
const
AddplanList
=
({
planList
})
=>
{
console
.
log
(
"
planList
"
,
planList
)
return
(
<
div
className
=
{
`mt-5
${
styles
.
list
}
`
}
>
<
div
className
=
{
`accordion accordion-flush`
}
id
=
"
addplanlist
"
>
...
...
client/src/components/StudyPlan/PlanItem.js
View file @
660e363c
import
{
useState
}
from
"
react
"
;
import
{
Link
,
useHistory
}
from
"
react-router-dom
"
;
import
AlertModal
from
"
../Modal/PlanAlertModal
"
;
import
planApi
from
"
../../apis/plan.api
"
;
import
{
useAuth
}
from
"
../../utils/context
"
;
import
catchErrors
from
"
../../utils/catchErrors
"
;
...
...
@@ -46,8 +45,7 @@ const PlanItem = ({ planList = [], subjectId }) => {
{
plan
.
memo
}
<
div
className
=
"
d-flex justify-content-end mt-3
"
>
<
Link
className
=
"
btn btn-light btn-sm border-dark
"
to
=
{
`/studyplan/edit/
${
plan
.
id
}
`
}
>
수정
<
/Link
>
<
button
type
=
"
button
"
className
=
"
btn btn-crimson btn-sm ms-2
"
data
-
bs
-
toggle
=
"
modal
"
data
-
bs
-
target
=
"
#planmodal
"
>
삭제
<
/button
>
<
AlertModal
planId
=
{
plan
.
id
}
handleClick
=
{
delPlan
}
/
>
<
button
type
=
"
button
"
className
=
"
btn btn-crimson btn-sm ms-2
"
onClick
=
{()
=>
delPlan
(
plan
.
id
)}
>
삭제
<
/button
>
<
/div
>
<
/div
>
<
/div
>
...
...
client/src/components/StudyPlan/PlanLineList.js
View file @
660e363c
...
...
@@ -3,7 +3,7 @@ import styles from "./studyplan.module.scss";
const
PlanLineList
=
({
subjectId
,
planList
=
[]
})
=>
{
return
(
<>
<
Link
to
=
{
`/studyplan/
${
subjectId
}
`
}
>
{
planList
.
length
!==
0
?
planList
.
map
(
plan
=>
<
div
className
=
"
d-flex justify-content-between
"
>
<
p
className
=
{
`card-text mb-1
${
styles
.
text
}
`
}
>-
{
plan
.
title
}
<
/p
>
<
input
className
=
{
`form-check-input shadow-none
${
styles
.
checkBox
}
`
}
type
=
"
checkbox
"
/>
...
...
@@ -13,7 +13,7 @@ const PlanLineList = ({ subjectId, planList = [] }) => {
<p className="card-text mb-1">새로운 계획 추가하기</p>
</div>
</Link>}
</>
</
Link
>
)
}
...
...
client/src/components/StudyPlan/StudyPlanCard.js
View file @
660e363c
import
{
Link
}
from
"
react-router-dom
"
;
import
PlanLineList
from
"
./PlanLineList
"
;
const
StudyPlanCard
=
({
renList
})
=>
{
const
StudyPlanCard
=
({
renList
,
handleClick
})
=>
{
return
(
<
Link
className
=
"
card text-decoration-none link-dark mb-3
"
style
=
{{
width
:
"
20rem
"
}}
to
=
{
`/studyplan/
${
renList
.
id
}
`
}
>
<
div
className
=
"
card text-decoration-none link-dark mb-3
"
style
=
{{
width
:
"
20rem
"
}}
>
<
div
className
=
"
card-body
"
>
<
div
className
=
"
d-flex
"
>
<
h5
className
=
"
card-title col-10 text-nowrap
"
style
=
{{
overflow
:
"
hidden
"
,
textOverflow
:
"
ellipsis
"
}}
>
{
renList
.
name
}
<
/h5
>
<
div
className
=
"
col-2 d-flex justify-content-end
"
>
<
Link
className
=
"
text-decoration-none link-dark
"
to
=
{
`/subject/edit/
${
renList
.
id
}
`
}
><
i
className
=
"
bi bi-pencil-square pe-2
"
><
/i></
Link
>
<
i
className
=
"
bi bi-trash
"
><
/i
>
<
i
className
=
"
bi bi-trash
"
onClick
=
{()
=>
handleClick
(
renList
.
id
)}
>
<
/i
>
<
/div
>
<
/div
>
<
p
className
=
"
card-subtitle ms-1 mb-2 text-muted
"
>
{
renList
.
prof
&&
renList
.
room
?
renList
.
prof
+
'
-
'
+
renList
.
room
:
(
renList
.
prof
||
renList
.
room
)}
<
/p
>
<
PlanLineList
subjectId
=
{
renList
.
id
}
planList
=
{
renList
.
planList
}
/
>
<
/div
>
<
/
Link
>
<
/
div
>
)
}
...
...
client/src/components/StudyPlan/StudyPlanList.js
View file @
660e363c
import
{
useState
,
useEffect
}
from
'
react
'
;
import
{
Link
}
from
"
react-router-dom
"
;
import
{
Link
,
useHistory
}
from
"
react-router-dom
"
;
import
StudyPlanCard
from
"
./StudyPlanCard
"
;
import
subjectApi
from
'
../../apis/subject.api
'
;
import
catchErrors
from
"
../../utils/catchErrors
"
;
...
...
@@ -9,7 +9,9 @@ import styles from "./studyplan.module.scss";
const
StudyPlanList
=
()
=>
{
const
{
user
}
=
useAuth
();
const
[
renList
,
setRenList
]
=
useState
([])
const
[
success
,
setSuccess
]
=
useState
(
false
)
const
[
error
,
setError
]
=
useState
(
""
)
const
history
=
useHistory
()
useEffect
(()
=>
{
getList
(
user
.
id
);
...
...
@@ -25,10 +27,23 @@ const StudyPlanList = () => {
}
}
async
function
delSubject
(
subjectId
)
{
try
{
setError
(
""
)
await
subjectApi
.
removeSubject
(
subjectId
,
user
.
id
)
alert
(
"
해당 과목 정보가 성공적으로 삭제되었습니다.
"
)
setSuccess
(
true
)
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
}
}
if
(
success
)
history
.
push
(
"
/home
"
)
return
(
<
div
className
=
{
`mt-4
${
styles
.
list
}
`
}
>
<
div
className
=
"
d-flex flex-column align-items-center
"
>
{
renList
.
length
!==
0
?
renList
.
map
((
info
,
idx
)
=>
<
StudyPlanCard
key
=
{
idx
}
renList
=
{
info
}
/>
)
: null
}
{
renList
.
length
!==
0
?
renList
.
map
((
info
,
idx
)
=>
<
StudyPlanCard
key
=
{
idx
}
renList
=
{
info
}
handleClick
=
{
delSubject
}
/>
)
: null
}
<
Link
className
=
"
card text-decoration-none link-dark
"
to
=
"
/subject/edit
"
style
=
{{
width
:
"
20rem
"
}}
>
<
div
className
=
"
card-body d-flex flex-column bg-secondary bg-opacity-25
"
>
<
i
className
=
"
bi bi-plus-lg d-flex justify-content-center fs-3
"
><
/i
>
...
...
server/controllers/todo.controller.js
View file @
660e363c
...
...
@@ -35,6 +35,30 @@ const findbyDate = async (req, res, next) => {
}
}
const
findforPercent
=
async
(
req
,
res
)
=>
{
try
{
let
doneTodo
=
null
const
userId
=
req
.
userId
const
{
start
,
end
}
=
req
.
query
if
(
end
)
{
const
{
count
,
rows
}
=
await
Todo
.
findAndCountAll
({
where
:
{
[
Op
.
and
]:
[{
date
:
{
[
Op
.
eq
]:
start
}
},
{
userId
:
userId
}]
}
})
}
else
{
let
percent
=
0
console
.
log
(
"
findforPercent end 없음
"
)
const
nonCheck
=
await
Todo
.
findAndCountAll
({
where
:
{
[
Op
.
and
]:
[{
date
:
{
[
Op
.
eq
]:
start
}
},
{
userId
:
userId
},
{
done
:
false
}]
}
})
const
check
=
await
Todo
.
findAndCountAll
({
where
:
{
[
Op
.
and
]:
[{
date
:
{
[
Op
.
eq
]:
start
}
},
{
userId
:
userId
},
{
done
:
true
}]
}
})
let
total
=
nonCheck
.
count
+
check
.
count
check
.
rows
.
forEach
(
el
=>
nonCheck
.
rows
.
push
(
el
.
dataValues
))
console
.
log
(
"
non
"
,
nonCheck
)
if
(
total
===
0
)
percent
=
0
else
percent
=
Math
.
round
((
check
.
count
/
total
)
*
100
)
return
res
.
json
({
percent
:
percent
,
list
:
nonCheck
.
rows
})
}
}
catch
(
error
)
{
return
res
.
status
(
500
).
send
(
error
.
message
||
"
todo 가져오는 중 에러 발생
"
)
}
}
const
create
=
async
(
req
,
res
)
=>
{
try
{
const
userId
=
req
.
userId
...
...
@@ -95,6 +119,7 @@ const send = async (req, res) => {
export
default
{
findbyId
,
findbyDate
,
findforPercent
,
create
,
edit
,
remove
,
...
...
server/db/index.js
View file @
660e363c
...
...
@@ -34,6 +34,11 @@ const Plan = PlanModel(sequelize)
Schedule
.
belongsTo
(
User
)
Subject
.
belongsTo
(
User
)
Todo
.
belongsTo
(
User
)
Subject
.
hasOne
(
Plan
,
{
onDelete
:
"
CASCADE
"
})
Plan
.
belongsTo
(
Subject
)
export
{
...
...
server/routes/todo.route.js
View file @
660e363c
...
...
@@ -3,6 +3,10 @@ import todoCtrl from "../controllers/todo.controller.js";
const
router
=
express
.
Router
();
router
.
route
(
"
/percent/:userId
"
)
.
get
(
todoCtrl
.
findforPercent
)
router
.
route
(
"
/:userId
"
)
.
get
(
todoCtrl
.
findbyId
,
todoCtrl
.
findbyDate
,
todoCtrl
.
send
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment