Toggle navigation
Toggle navigation
This project
Loading...
Sign in
HyeonJun Jeon
/
Extended-Calendar
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
HyeonJun Jeon
2022-06-07 10:08:41 +0900
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
aec0b571265bdde66b9ccbf22da1957f227bb6ed
aec0b571
1 parent
8ee8e5bd
[Add] Schedule add popup
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
257 additions
and
24 deletions
server/routers/DB.js
server/routers/Schedules_date.js
server/routers/Schedules_repeat.js
server/routers/Schedules_time.js
src/components/GridItem.js
src/components/ScheduleItem.js
src/components/SideSubject.js
src/pages/Calendar.js
src/styles/App.css
src/styles/Side.css
server/routers/DB.js
View file @
aec0b57
...
...
@@ -21,8 +21,7 @@ async function route() {
DELETE FROM \`
${
req
.
body
.
table
}
\` sc
WHERE sc.userID =
${
req
.
body
.
userID
}
AND sc.uid =
${
req
.
body
.
uid
}
`
;
const
[
result
]
=
await
connection
.
query
(
queryString
);
console
.
log
(
req
.
body
);
await
connection
.
query
(
queryString
);
res
.
end
();
}
catch
(
e
)
{
console
.
log
(
e
);
...
...
server/routers/Schedules_date.js
View file @
aec0b57
...
...
@@ -30,6 +30,41 @@ async function route() {
res
.
end
();
}
});
// (userID, label, subjectID, type, description, url, date)
schedules_dateRouter
.
post
(
"/"
,
async
(
req
,
res
)
=>
{
console
.
log
(
"post /db/schedules_date"
);
try
{
let
queryString
=
`
INSERT INTO \`schedules_date\`
(userID, label, subjectID, type, description, url, date, status)
VALUES (
${
req
.
body
.
userID
}
, "
${
req
.
body
.
label
}
",
${
req
.
body
.
subjectID
}
, "
${
req
.
body
.
type
}
",
"
${
req
.
body
.
description
}
", "
${
req
.
body
.
url
}
", "
${
req
.
body
.
date
}
", 1);`
;
await
connection
.
query
(
queryString
);
queryString
=
`UPDATE \`schedules_date\`
SET uid = -ID
WHERE ID = LAST_INSERT_ID();`
;
await
connection
.
query
(
queryString
);
queryString
=
`
SELECT sc.label, sc.type, sc.description, sc.url, sc.detail,
sbj.name, us.nickname, us.color, sc.uid, "schedules_date" \`table\`
FROM schedules_date sc
INNER JOIN \`user-subject\` us
ON sc.userID = us.userID
AND sc.subjectID = us.subjectID
AND us.status = 1
INNER JOIN subjects sbj
ON sc.subjectID = sbj.ID
WHERE sc.ID = LAST_INSERT_ID()`
;
[
results
]
=
await
connection
.
query
(
queryString
);
res
.
send
(
results
[
0
]);
}
catch
(
e
)
{
console
.
log
(
e
);
res
.
end
();
}
});
}
route
();
...
...
server/routers/Schedules_repeat.js
View file @
aec0b57
...
...
@@ -38,12 +38,29 @@ async function route() {
try
{
const
queryString
=
`
INSERT INTO schedules_repeat (userID, label, subjectID, type, status, day, startTime, endTime)
VALUE (
${
req
.
body
.
userID
}
,
${
req
.
body
.
label
}
,
${
req
.
body
.
subjectID
}
,
${
req
.
body
.
type
}
,
${
req
.
body
.
status
}
,
${
req
.
body
.
day
}
,
${
req
.
body
.
startTime
}
,
${
req
.
body
.
endTime
}
);
VALUE (
${
req
.
body
.
userID
}
, "
${
req
.
body
.
label
}
",
${
req
.
body
.
subjectID
}
, "
${
req
.
body
.
type
}
",
1,
${
req
.
body
.
day
}
, "
${
req
.
body
.
startTime
}
", "
${
req
.
body
.
endTime
}
");`
;
queryString
=
`
UPDATE schedules_repeat
SET uid = -id;`
;
SET uid = -ID
WHERE ID = LAST_INSERT_ID()`
;
await
connection
.
query
(
queryString
);
res
.
end
();
queryString
=
`
SELECT sc.label, sc.type, sc.description, sc.uid, sc.url, sc.detail, sbj.name,
us.nickname, us.color, sc.startTime, sc.endTime, "schedules_repeat" \`table\`
FROM schedules_repeat sc
INNER JOIN \`user-subject\` us
ON sc.userID = us.userID
AND sc.subjectID = us.subjectID
AND us.status = 1
INNER JOIN subjects sbj
ON sc.subjectID = sbj.ID
WHERE sc.ID = LAST_INSERT_ID()
ORDER BY sc.startTime`
;
[
results
]
=
await
connection
.
query
(
queryString
);
res
.
send
(
results
[
0
]);
}
catch
(
e
)
{
console
.
log
(
e
);
res
.
end
();
...
...
server/routers/Schedules_time.js
View file @
aec0b57
...
...
@@ -31,6 +31,44 @@ async function route() {
res
.
end
();
}
});
// (userID, label, subjectID, type, description, url, date, startTime, endTime)
schedules_timeRouter
.
post
(
"/"
,
async
(
req
,
res
)
=>
{
console
.
log
(
"post /db/schedules_time"
);
try
{
const
startTime
=
req
.
body
.
startTime
?
`"
${
req
.
body
.
startTime
}
"`
:
"null"
;
const
endTime
=
req
.
body
.
endTime
?
`"
${
req
.
body
.
endTime
}
"`
:
"null"
;
let
queryString
=
`
INSERT INTO \`schedules_time\`
(userID, label, subjectID, type, description, url, date, status, startTime, endTime)
VALUES (
${
req
.
body
.
userID
}
, "
${
req
.
body
.
label
}
",
${
req
.
body
.
subjectID
}
, "
${
req
.
body
.
type
}
", "
${
req
.
body
.
description
}
",
"
${
req
.
body
.
url
}
", "
${
req
.
body
.
date
}
", 1,
${
startTime
}
,
${
endTime
}
);`
;
await
connection
.
query
(
queryString
);
queryString
=
`
UPDATE schedules_time
SET uid = -ID
WHERE ID = LAST_INSERT_ID()`
;
await
connection
.
query
(
queryString
);
queryString
=
`SELECT sc.label, sc.type, sc.description, sc.url, sc.detail, sbj.name, us.nickname,
us.color, sc.uid, sc.startTime, sc.endTime, "schedules_time" \`table\`
FROM schedules_time sc
INNER JOIN \`user-subject\` us
ON sc.userID = us.userID
AND sc.subjectID = us.subjectID
AND us.status = 1
INNER JOIN subjects sbj
ON sc.subjectID = sbj.ID
WHERE sc.ID = LAST_INSERT_ID()
ORDER BY sc.endTime`
;
[
results
]
=
await
connection
.
query
(
queryString
);
res
.
send
(
results
[
0
]);
}
catch
(
e
)
{
console
.
log
(
e
);
res
.
end
();
}
});
}
route
();
...
...
src/components/GridItem.js
View file @
aec0b57
import
{
useContext
,
useEffect
,
useState
}
from
"react"
;
import
{
useContext
,
useEffect
,
use
Ref
,
use
State
}
from
"react"
;
import
localforage
from
"localforage"
;
import
{
toYMD
,
toYMDStr
}
from
"../utils/Dates"
;
...
...
@@ -8,10 +8,19 @@ import ScheduleItem from "./ScheduleItem";
import
axios
from
"axios"
;
const
GridItem
=
({
targetDate
})
=>
{
const
{
state
}
=
useContext
(
CalendarStateContext
);
const
{
month
:
calMonth
}
=
toYMD
(
s
tate
.
date
);
const
{
state
:
calState
,
subsObj
}
=
useContext
(
CalendarStateContext
);
const
{
month
:
calMonth
}
=
toYMD
(
calS
tate
.
date
);
const
{
month
,
date
}
=
toYMD
(
targetDate
);
const
[
schedules
,
setSchedules
]
=
useState
();
const
[
state
,
setState
]
=
useState
({
label
:
""
,
startTime
:
""
,
endTime
:
""
,
description
:
""
,
url
:
""
,
type
:
"assignment"
,
subjectID
:
0
,
});
useEffect
(()
=>
{
async
function
loadScheduleItems
()
{
...
...
@@ -32,11 +41,20 @@ const GridItem = ({ targetDate }) => {
"http://localhost:3001/db/schedules_repeat"
,
{
params
}
);
const
subs
=
await
localforage
.
getItem
(
"subjects"
);
setState
({
...
state
,
subjectID
:
subs
[
0
].
subjectID
});
setSchedules
(
scrpeat
.
concat
(
scdate
,
sctime
));
}
loadScheduleItems
();
},
[
targetDate
]);
const
handleChangeState
=
(
e
)
=>
{
setState
({
...
state
,
[
e
.
target
.
name
]:
e
.
target
.
value
,
});
};
const
finishSchedule
=
async
(
table
,
uid
)
=>
{
for
(
const
i
in
schedules
)
if
(
schedules
[
i
].
uid
===
uid
)
{
...
...
@@ -52,15 +70,96 @@ const GridItem = ({ targetDate }) => {
}
};
const
popupRef
=
useRef
();
const
click
=
async
(
e
)
=>
{
if
(
e
.
target
.
classList
.
contains
(
"gi"
))
{
popupRef
.
current
.
style
.
display
=
"flex"
;
}
else
if
(
e
.
target
.
className
===
"gipc"
)
{
popupRef
.
current
.
style
.
display
=
"none"
;
}
else
if
(
e
.
target
.
className
===
"gipa"
)
{
// (userID, label, subjectID, type, description, url, date)
const
table
=
state
.
startTime
||
state
.
endTime
?
"schedules_time"
:
"schedules_date"
;
const
{
data
:
sche
}
=
await
axios
.
post
(
"http://localhost:3001/db/"
+
table
,
{
userID
:
await
localforage
.
getItem
(
"userID"
),
...
state
,
date
:
toYMDStr
(
targetDate
,
"-"
),
}
);
setSchedules
(
schedules
.
concat
(
sche
));
popupRef
.
current
.
style
.
display
=
"none"
;
}
};
return
(
<
div
className
=
"GridItem"
relative
=
{
month
-
calMonth
||
null
}
>
<
span
className
=
"date"
>
<
div
className
=
"GridItem gi"
relative
=
{
month
-
calMonth
||
null
}
onClick
=
{
click
}
>
<
span
className
=
"date gi"
>
{
calMonth
!==
month
?
month
+
"/"
+
date
:
date
}
<
/span
>
{
schedules
&&
schedules
.
map
((
sche
,
index
)
=>
(
<
ScheduleItem
key
=
{
index
}
schedule
=
{
sche
}
finish
=
{
finishSchedule
}
/
>
))}
<
div
className
=
"gi_popup"
popup
=
"true"
ref
=
{
popupRef
}
>
<
span
>
일정
추가
<
/span
>
<
div
className
=
"gipd"
>
<
input
name
=
"label"
placeholder
=
"이름"
value
=
{
state
.
label
}
onChange
=
{
handleChangeState
}
/
>
<
select
name
=
"subjectID"
value
=
{
state
.
subjectID
}
onChange
=
{
handleChangeState
}
>
{
Object
.
values
(
subsObj
).
map
((
sub
,
index
)
=>
(
<
option
key
=
{
index
}
value
=
{
sub
.
subjectID
}
>
{
sub
.
name
}
<
/option
>
))}
<
/select
>
<
select
name
=
"type"
value
=
{
state
.
type
}
onChange
=
{
handleChangeState
}
>
<
option
value
=
{
"assignment"
}
>
E
-
Campus
<
/option
>
<
option
value
=
{
"zoom"
}
>
Zoom
<
/option
>
<
/select
>
<
input
name
=
"startTime"
placeholder
=
"시작 (HH:MM)"
value
=
{
state
.
startTime
}
onChange
=
{
handleChangeState
}
/
>
<
input
name
=
"endTime"
placeholder
=
"종료 (HH:MM)"
value
=
{
state
.
endTime
}
onChange
=
{
handleChangeState
}
/
>
<
textarea
name
=
"description"
placeholder
=
"설명"
value
=
{
state
.
description
}
onChange
=
{
handleChangeState
}
/
>
<
textarea
name
=
"url"
placeholder
=
"링크"
value
=
{
state
.
url
}
onChange
=
{
handleChangeState
}
/
>
<
/div
>
<
div
className
=
"gip_btn"
>
<
button
className
=
"gipc"
>
취소
<
/button
>
<
button
className
=
"gipa"
>
추가
<
/button
>
<
/div
>
<
/div
>
<
/div
>
);
};
...
...
src/components/ScheduleItem.js
View file @
aec0b57
...
...
@@ -62,7 +62,7 @@ const ScheduleItem = ({ schedule, finish }) => {
{
endTime
&&
<
span
className
=
"s_end ss"
>
{
eTime
}
<
/span>
}
<
span
className
=
"s_slabel ss"
>
{
label
}
<
/span
>
<
div
className
=
"s_popup"
ref
=
{
popupRef
}
>
<
div
className
=
"s_popup"
popup
=
"true"
ref
=
{
popupRef
}
>
<
div
className
=
"spl"
>
<
span
>
{
subjectName
}
<
/span
>
{
url
?
(
...
...
src/components/SideSubject.js
View file @
aec0b57
...
...
@@ -65,7 +65,7 @@ const SideSubject = ({ subject, dispatch }) => {
<
span
className
=
"ssl"
onClick
=
{
labelClick
}
>
{
subject
.
nickname
||
subject
.
name
}
<
/span
>
<
div
className
=
"ss_popup"
ref
=
{
popupRef
}
>
<
div
className
=
"ss_popup"
popup
=
"true"
ref
=
{
popupRef
}
>
<
div
className
=
"sspd"
>
<
div
className
=
"sspd_1"
>
<
span
>
이름
<
/span
>
...
...
src/pages/Calendar.js
View file @
aec0b57
...
...
@@ -59,6 +59,7 @@ const Calendar = () => {
"http://localhost:3001/db/user-subject"
,
{
params
:
{
userID
}
}
);
await
localforage
.
setItem
(
"subjects"
,
subjects
);
let
tsubsObj
=
{};
for
(
const
sub
of
subjects
)
{
tsubsObj
[
sub
.
subjectID
]
=
sub
;
...
...
src/styles/App.css
View file @
aec0b57
...
...
@@ -47,6 +47,54 @@ button:disabled {
display
:
flex
;
}
.GridItem
{
position
:
relative
;
}
.gi_popup
{
flex-direction
:
column
;
padding
:
5px
;
top
:
30px
;
}
.gi_popup
>
span
{
font-size
:
large
;
}
.gip_btn
{
display
:
flex
;
flex-direction
:
row-reverse
;
}
.gip_btn
>
button
{
padding
:
5px
9px
5px
9px
;
margin-left
:
2px
;
}
.gipd
{
margin
:
5px
0
5px
0
;
display
:
grid
;
grid-template-columns
:
repeat
(
2
,
minmax
(
100px
,
auto
));
grid-template-rows
:
repeat
(
6
,
minmax
(
30px
,
auto
));
row-gap
:
5px
;
column-gap
:
5px
;
}
.gipd
>
*
{
grid-column
:
1
/
span
2
;
}
.gipd
>
:nth-child
(
4
)
{
grid-column
:
1
;
}
.gipd
>
:nth-child
(
5
)
{
grid-column
:
2
;
}
.gipd
>
:nth-child
(
6
),
.gipd
>
:nth-child
(
7
)
{
resize
:
none
;
height
:
60px
;
}
.ScheduleItem
{
display
:
flex
;
margin
:
1px
0
1px
0
;
...
...
@@ -80,18 +128,21 @@ button:disabled {
padding
:
0
;
}
.s_popup
{
[
popup
]
{
position
:
absolute
;
z-index
:
1000
;
top
:
calc
(
100%
+
5px
);
left
:
20px
;
background
:
rgb
(
250
,
250
,
250
);
box-shadow
:
0px
0px
5px
gray
;
border
:
solid
thin
grey
;
border-radius
:
5px
;
display
:
none
;
padding
:
10px
;
cursor
:
auto
;
}
.s_popup
{
top
:
calc
(
100%
+
5px
);
left
:
20px
;
padding
:
10px
;
width
:
300px
;
}
...
...
src/styles/Side.css
View file @
aec0b57
...
...
@@ -28,18 +28,11 @@ aside {
.ss_popup
{
flex-direction
:
column
;
align-items
:
flex-end
;
position
:
absolute
;
z-index
:
1000
;
top
:
30px
;
left
:
30px
;
/* height: 150px;
width: 250px; */
/* transform: translate(-50%, -50%); */
background
:
rgb
(
250
,
250
,
250
);
box-shadow
:
0px
0px
5px
gray
;
border
:
solid
thin
grey
;
border-radius
:
5px
;
display
:
none
;
padding
:
5px
;
}
...
...
Please
register
or
login
to post a comment