mirror of
https://github.com/aaronleetw/Attendance.git
synced 2024-11-14 19:11:39 -08:00
Prototype Finish
This commit is contained in:
parent
a47d69a954
commit
6ee0ce15d5
14 changed files with 841 additions and 484 deletions
|
@ -1,35 +0,0 @@
|
||||||
number,name,eng_name
|
|
||||||
1,朱昱翧,Themis
|
|
||||||
2,余欣璇,Zoe
|
|
||||||
3,吳丞育,Audrey
|
|
||||||
4,吳欣芃,Lisa
|
|
||||||
5,吳苡瑄,Rachel
|
|
||||||
6,王怡捷,Audrey
|
|
||||||
7,林子琳,Emma
|
|
||||||
8,林思佑,Una
|
|
||||||
9,林珈年,Jessica
|
|
||||||
10,姜心唯,Misha
|
|
||||||
11,張庭暄,Chang
|
|
||||||
12,許詠淳,Catherine
|
|
||||||
13,陳宣彤,idk
|
|
||||||
14,羅子珊,Shannon
|
|
||||||
15,蘇宜柔,Chloe
|
|
||||||
16,王邦熹,Wallace
|
|
||||||
17,李秉謙,Alan
|
|
||||||
18,劉青懷,idk
|
|
||||||
19,林稟翔,Wilbert
|
|
||||||
20,柯喬勳,Joshua
|
|
||||||
21,馮顗中,idk
|
|
||||||
22,張睿恩,Brian
|
|
||||||
23,姜廉竣,idk
|
|
||||||
24,陳允昊,Jeremy
|
|
||||||
25,陳宣豪,Demetris
|
|
||||||
26,陳宥嘉,Joseph
|
|
||||||
27,陳麟泳,Aaron
|
|
||||||
28,賀凱強,Jonathan
|
|
||||||
29,楊上霆,Chase
|
|
||||||
30,楊承武,Ben
|
|
||||||
31,廖建瑋,Daniel
|
|
||||||
32,潘逸,James
|
|
||||||
33,朱禹安,Iforgot
|
|
||||||
34,徐敏萱,idk
|
|
|
|
@ -1,35 +0,0 @@
|
||||||
number,3-IG
|
|
||||||
1,1103-01
|
|
||||||
2,1103-01
|
|
||||||
3,1103-02
|
|
||||||
4,1103-01
|
|
||||||
5,1103-01
|
|
||||||
6,1103-02
|
|
||||||
7,1103-01
|
|
||||||
8,1103-01
|
|
||||||
9,1103-01
|
|
||||||
10,1103-01
|
|
||||||
11,1103-01
|
|
||||||
12,1103-01
|
|
||||||
13,1103-02
|
|
||||||
14,1103-01
|
|
||||||
15,1103-02
|
|
||||||
16,1103-01
|
|
||||||
17,1103-02
|
|
||||||
18,1103-02
|
|
||||||
19,1103-01
|
|
||||||
20,1103-02
|
|
||||||
21,1103-01
|
|
||||||
22,1103-02
|
|
||||||
23,1103-01
|
|
||||||
24,1103-02
|
|
||||||
25,1103-02
|
|
||||||
26,1103-02
|
|
||||||
27,1103-01
|
|
||||||
28,1103-02
|
|
||||||
29,1103-01
|
|
||||||
30,1103-01
|
|
||||||
31,1103-01
|
|
||||||
32,1103-01
|
|
||||||
33,1103-02
|
|
||||||
34,1103-01
|
|
|
|
@ -1,35 +0,0 @@
|
||||||
number,name,eng_name,3-IG
|
|
||||||
1,王子芯,Heidi,1103-01
|
|
||||||
2,朱宸儀,Megan,1103-01
|
|
||||||
3,牟奇薇,Summer,1103-02
|
|
||||||
4,吳偲梵,Sophia,1103-01
|
|
||||||
5,林書誼,Charlotte,1103-01
|
|
||||||
6,林葦亭,Chelsea,1103-02
|
|
||||||
7,凌孟妍,Iris,1103-01
|
|
||||||
8,翁翊婷,Evelyn,1103-01
|
|
||||||
9,郭倚熏,Patty,1103-01
|
|
||||||
10,陳宣穎,Renee,1103-01
|
|
||||||
11,曾若霏,Danielle,1103-01
|
|
||||||
12,湯家綺,Joanna,1103-01
|
|
||||||
13,黃以甯,Kate,1103-02
|
|
||||||
14,黃玄,Cheryl,1103-01
|
|
||||||
15,劉煒琪,Winona,1103-02
|
|
||||||
16,潘俞希,Alina,1103-01
|
|
||||||
17,鄭軒,Jasper,1103-02
|
|
||||||
18,吳彥縢,Austin,1103-02
|
|
||||||
19,吳昶佑,Eric,1103-01
|
|
||||||
20,李翊愷,Aaron Lee,1103-02
|
|
||||||
21,李翊誠,Alex,1103-01
|
|
||||||
22,曹庭睿,Alvin,1103-02
|
|
||||||
23,莊家睿,Gary,1103-01
|
|
||||||
24,張馨予,Cindy,1103-02
|
|
||||||
25,常有慈,Cindy,1103-02
|
|
||||||
26,陳柏元,Michael,1103-02
|
|
||||||
27,陳雋喆,Derek,1103-01
|
|
||||||
28,曾柏皓,Cory,1103-02
|
|
||||||
29,黃獻主,Arthur,1103-01
|
|
||||||
30,盧秉漢,Hiro,1103-01
|
|
||||||
31,李文,Tom,1103-01
|
|
||||||
32,謝承霖,Walter,1103-01
|
|
||||||
33,關義,Aaron Kuan,1103-02
|
|
||||||
34,謝佾儒,Yi-Ju,1103-01
|
|
|
|
@ -1,35 +0,0 @@
|
||||||
number,3-IG,2-TEST
|
|
||||||
1,1103-01,1102-5
|
|
||||||
2,1103-01,1102-5
|
|
||||||
3,1103-02,1102-5
|
|
||||||
4,1103-01,1102-5
|
|
||||||
5,1103-01,1102-5
|
|
||||||
6,1103-02,1102-5
|
|
||||||
7,1103-01,1102-5
|
|
||||||
8,1103-01,1102-5
|
|
||||||
9,1103-01,1102-5
|
|
||||||
10,1103-01,1102-5
|
|
||||||
11,1103-01,1102-5
|
|
||||||
12,1103-01,1102-5
|
|
||||||
13,1103-02,1102-5
|
|
||||||
14,1103-01,1102-5
|
|
||||||
15,1103-02,1102-5
|
|
||||||
16,1103-01,1102-5
|
|
||||||
17,1103-02,1102-5
|
|
||||||
18,1103-02,1102-5
|
|
||||||
19,1103-01,1102-5
|
|
||||||
20,1103-02,1102-5
|
|
||||||
21,1103-01,1102-9
|
|
||||||
22,1103-02,1102-9
|
|
||||||
23,1103-01,1102-9
|
|
||||||
24,1103-02,1102-9
|
|
||||||
25,1103-02,1102-9
|
|
||||||
26,1103-02,1102-9
|
|
||||||
27,1103-01,1102-9
|
|
||||||
28,1103-02,1102-9
|
|
||||||
29,1103-01,1102-9
|
|
||||||
30,1103-01,1102-9
|
|
||||||
31,1103-01,1102-9
|
|
||||||
32,1103-01,1102-9
|
|
||||||
33,1103-02,1102-9
|
|
||||||
34,1103-01,1102-9
|
|
|
|
@ -1,35 +0,0 @@
|
||||||
number,name,eng_name
|
|
||||||
1,王子芯,Heidi
|
|
||||||
2,朱宸儀,Megan
|
|
||||||
3,牟奇薇,Summer
|
|
||||||
4,吳偲梵,Sophia
|
|
||||||
5,林書誼,Charlotte
|
|
||||||
6,林葦亭,Chelsea
|
|
||||||
7,凌孟妍,Iris
|
|
||||||
8,翁翊婷,Evelyn
|
|
||||||
9,郭倚熏,Patty
|
|
||||||
10,陳宣穎,Renee
|
|
||||||
11,曾若霏,Danielle
|
|
||||||
12,湯家綺,Joanna
|
|
||||||
13,黃以甯,Kate
|
|
||||||
14,黃玄,Cheryl
|
|
||||||
15,劉煒琪,Winona
|
|
||||||
16,潘俞希,Alina
|
|
||||||
17,鄭軒,Jasper
|
|
||||||
18,吳彥縢,Austin
|
|
||||||
19,吳昶佑,Eric
|
|
||||||
20,李翊愷,Aaron Lee
|
|
||||||
21,李翊誠,Alex
|
|
||||||
22,曹庭睿,Alvin
|
|
||||||
23,莊家睿,Gary
|
|
||||||
24,張馨予,Cindy
|
|
||||||
25,常有慈,Cindy
|
|
||||||
26,陳柏元,Michael
|
|
||||||
27,陳雋喆,Derek
|
|
||||||
28,曾柏皓,Cory
|
|
||||||
29,黃獻主,Arthur
|
|
||||||
30,盧秉漢,Hiro
|
|
||||||
31,李文,Tom
|
|
||||||
32,謝承霖,Walter
|
|
||||||
33,關義,Aaron Kuan
|
|
||||||
34,謝佾儒,Yi-Ju
|
|
|
|
@ -1,35 +0,0 @@
|
||||||
number,3-IG
|
|
||||||
1,1103-01
|
|
||||||
2,1103-01
|
|
||||||
3,1103-02
|
|
||||||
4,1103-01
|
|
||||||
5,1103-01
|
|
||||||
6,1103-02
|
|
||||||
7,1103-01
|
|
||||||
8,1103-01
|
|
||||||
9,1103-01
|
|
||||||
10,1103-01
|
|
||||||
11,1103-01
|
|
||||||
12,1103-01
|
|
||||||
13,1103-02
|
|
||||||
14,1103-01
|
|
||||||
15,1103-02
|
|
||||||
16,1103-01
|
|
||||||
17,1103-02
|
|
||||||
18,1103-02
|
|
||||||
19,1103-01
|
|
||||||
20,1103-02
|
|
||||||
21,1103-01
|
|
||||||
22,1103-02
|
|
||||||
23,1103-01
|
|
||||||
24,1103-02
|
|
||||||
25,1103-02
|
|
||||||
26,1103-02
|
|
||||||
27,1103-01
|
|
||||||
28,1103-02
|
|
||||||
29,1103-01
|
|
||||||
30,1103-01
|
|
||||||
31,1103-01
|
|
||||||
32,1103-01
|
|
||||||
33,1103-02
|
|
||||||
34,1103-01
|
|
|
452
app.py
452
app.py
|
@ -1,12 +1,12 @@
|
||||||
from flask import *
|
from flask import *
|
||||||
import pyrebase
|
import pyrebase
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import time
|
|
||||||
import pytz
|
import pytz
|
||||||
from sendgrid import SendGridAPIClient
|
|
||||||
from sendgrid.helpers.mail import Mail
|
|
||||||
import csv
|
import csv
|
||||||
import os
|
import os
|
||||||
|
import pandas as pd
|
||||||
|
import base64
|
||||||
|
from random import randint
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
@ -26,6 +26,7 @@ config = {
|
||||||
firebase = pyrebase.initialize_app(config)
|
firebase = pyrebase.initialize_app(config)
|
||||||
db = firebase.database()
|
db = firebase.database()
|
||||||
auth = firebase.auth()
|
auth = firebase.auth()
|
||||||
|
storage = firebase.storage()
|
||||||
tz = pytz.timezone('Asia/Taipei')
|
tz = pytz.timezone('Asia/Taipei')
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,149 +43,138 @@ def manageProcess(fCommand, fData):
|
||||||
# end bug fix
|
# end bug fix
|
||||||
pl = db.child("Users").child(
|
pl = db.child("Users").child(
|
||||||
session['uid']).child("permission").get().val()
|
session['uid']).child("permission").get().val()
|
||||||
print(pl)
|
|
||||||
print(db.child("Users").child(
|
|
||||||
'DRZqqSSpg3OkPSCuWkv417dv0vh1').child("permission").get().val())
|
|
||||||
print(fCommand, fData, session['uid'], pl)
|
|
||||||
if pl == 'admin':
|
if pl == 'admin':
|
||||||
return pl
|
homerooms = db.child("Homerooms").get().val()
|
||||||
|
currRoom = []
|
||||||
|
if fCommand == "admin":
|
||||||
|
currRoom = fData[0].split("^")
|
||||||
|
else:
|
||||||
|
for i in homerooms:
|
||||||
|
currRoom.append(i)
|
||||||
|
for j in homerooms[i]:
|
||||||
|
currRoom.append(j)
|
||||||
|
break
|
||||||
|
break
|
||||||
|
homeroomData = homerooms[currRoom[0]][currRoom[1]]
|
||||||
|
absData = homeroomData["Absent"]
|
||||||
|
homeroomData.pop('Absent')
|
||||||
|
homeroomData.pop('placeholder')
|
||||||
|
currDate = ""
|
||||||
|
if fCommand != "":
|
||||||
|
currDate = fData[1]
|
||||||
|
else:
|
||||||
|
for i in absData:
|
||||||
|
currDate = i
|
||||||
|
if i >= datetime.now(tz).strftime("%Y-%m-%d"):
|
||||||
|
break
|
||||||
|
return render_template('admin.html', homerooms=homerooms, absData=absData, homeroomCode=currRoom, homeroomData=homeroomData, currDate=currDate, periods=['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9'])
|
||||||
elif pl == 'group':
|
elif pl == 'group':
|
||||||
classes = db.child("Users").child(
|
classes = db.child("Users").child(
|
||||||
session['uid']).child("class").get().val()
|
session['uid']).child("class").get().val()
|
||||||
cclass = {}
|
cclass = {}
|
||||||
|
cateData = {}
|
||||||
for i in classes:
|
for i in classes:
|
||||||
|
cateData = db.child("Classes").child(
|
||||||
|
"GP_Class").child(i).get().val()
|
||||||
cclass = {
|
cclass = {
|
||||||
"name": db.child("Classes").child(i).child(
|
"name": cateData['Class'][classes[i]]['name'],
|
||||||
"Class").child(classes[i]).child("name").get().val(),
|
"teacher": cateData['Class'][classes[i]]['teacher'],
|
||||||
|
"classroom": cateData['Class'][classes[i]]['classroom'],
|
||||||
"category": i,
|
"category": i,
|
||||||
"class_id": classes[i]
|
"class_id": classes[i]
|
||||||
}
|
}
|
||||||
print("got class")
|
print("got class")
|
||||||
students = db.child("Classes").child(cclass['category']).child(
|
homerooms = cateData['Homerooms']
|
||||||
"Class").child(cclass['class_id']).child("Students").get().val()
|
currDate = ""
|
||||||
print(students['9']['11'])
|
absData = {}
|
||||||
all_stud_list = {}
|
for h in homerooms:
|
||||||
for grade in students:
|
h = h.split('^')
|
||||||
print(grade)
|
print(h)
|
||||||
all_stud_list[grade] = {}
|
hrData = db.child("Homerooms").child(h[0]).child(h[1]).get().val()
|
||||||
print(type(students[grade]))
|
tmpAbsData = hrData['Absent']
|
||||||
for homeroom in students[grade]:
|
hrData.pop('Absent')
|
||||||
print(homeroom)
|
hrData.pop('placeholder')
|
||||||
roomData = db.child("Homerooms").child(
|
periods = []
|
||||||
grade).child(homeroom).get().val()
|
dow = ""
|
||||||
all_stud_list[grade][homeroom] = {}
|
if currDate == "":
|
||||||
if type(students[grade][homeroom]) == list:
|
|
||||||
i = 0
|
|
||||||
for student in students[grade][homeroom]:
|
|
||||||
if student == 0:
|
|
||||||
all_stud_list[grade][homeroom][i] = {
|
|
||||||
"name": roomData[str(i)]["name"],
|
|
||||||
"eng_name": roomData[str(i)]["eng_name"]
|
|
||||||
}
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
for student in students[grade][homeroom]:
|
|
||||||
print(student)
|
|
||||||
all_stud_list[grade][homeroom][student] = {
|
|
||||||
"name": roomData[student]["name"],
|
|
||||||
"eng_name": roomData[student]["eng_name"]
|
|
||||||
}
|
|
||||||
print("got students")
|
|
||||||
dates = db.child("Classes").child(
|
|
||||||
cclass['category']).child("Dates").get().val()
|
|
||||||
status = 0
|
|
||||||
attendance = {}
|
|
||||||
|
|
||||||
if fCommand == 'date':
|
if fCommand == 'date':
|
||||||
currDate = fData
|
currDate = fData
|
||||||
if cclass['class_id'] in dates[currDate]:
|
for j in tmpAbsData[currDate]:
|
||||||
status = 1
|
if j == "dow":
|
||||||
for grade in dates[currDate]['Absent']:
|
dow = tmpAbsData[currDate][j]
|
||||||
attendance[grade] = {}
|
continue
|
||||||
for homeroom in dates[currDate]['Absent'][grade]:
|
elif j == "confirm":
|
||||||
attendance[grade][homeroom] = {}
|
continue
|
||||||
for student in dates[currDate]['Absent'][grade][homeroom]:
|
if (tmpAbsData[currDate][j]['name'] == 'GP' and
|
||||||
attendance[grade][homeroom][student] = 0
|
tmpAbsData[currDate][j]['teacher'] == cclass['category']):
|
||||||
|
periods.append(j)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for i in dates:
|
for i in tmpAbsData:
|
||||||
if i >= datetime.now(tz).strftime("%Y-%m-%d"):
|
|
||||||
currDate = i
|
currDate = i
|
||||||
if cclass['class_id'] in dates[currDate]:
|
if i >= datetime.now(tz).strftime("%Y-%m-%d"):
|
||||||
status = 1
|
tmp = False
|
||||||
for grade in dates[currDate]['Absent']:
|
for j in tmpAbsData[i]:
|
||||||
attendance[grade] = {}
|
if j == "dow":
|
||||||
for homeroom in dates[currDate]['Absent'][grade]:
|
dow = tmpAbsData[i][j]
|
||||||
attendance[grade][homeroom] = {}
|
continue
|
||||||
for student in dates[currDate]['Absent'][grade][homeroom]:
|
elif j == "confirm":
|
||||||
attendance[grade][homeroom][student] = 0
|
continue
|
||||||
|
if (tmpAbsData[i][j]['name'] == 'GP' and
|
||||||
|
tmpAbsData[i][j]['teacher'] == cclass['category']):
|
||||||
|
periods.append(j)
|
||||||
|
tmp = True
|
||||||
|
if tmp == True:
|
||||||
break
|
break
|
||||||
dates[i].pop('placeholder')
|
else:
|
||||||
print("got dates")
|
for j in tmpAbsData[currDate]:
|
||||||
return render_template('group_teach.html', cclass=cclass, all_stud_list=all_stud_list, dates=dates, currDate=currDate, status=status, attendance=attendance)
|
if j == "dow":
|
||||||
|
dow = tmpAbsData[currDate][j]
|
||||||
|
continue
|
||||||
|
elif j == "confirm":
|
||||||
|
continue
|
||||||
|
if (tmpAbsData[currDate][j]['name'] == 'GP' and
|
||||||
|
tmpAbsData[currDate][j]['teacher'] == cclass['category']):
|
||||||
|
periods.append(j)
|
||||||
|
for p in periods:
|
||||||
|
if not p in absData:
|
||||||
|
absData[p] = {}
|
||||||
|
for p in periods:
|
||||||
|
if not h[0] in absData[p]:
|
||||||
|
absData[p][h[0]] = {}
|
||||||
|
absData[p][h[0]][h[1]] = {}
|
||||||
|
for num in hrData:
|
||||||
|
if (cclass['category'] in hrData[num]['GP_Class'] and
|
||||||
|
hrData[num]['GP_Class'][cclass['category']] == cclass['class_id']):
|
||||||
|
for p in periods:
|
||||||
|
absData[p][h[0]][h[1]][num] = {
|
||||||
|
"name": hrData[num]['name'],
|
||||||
|
"eng_name": hrData[num]['eng_name'],
|
||||||
|
"alr_fill": ('signature' in tmpAbsData[currDate][p] and
|
||||||
|
cclass['class_id'] in tmpAbsData[currDate][p]['signature']),
|
||||||
|
"absent": num in tmpAbsData[currDate][p]
|
||||||
|
}
|
||||||
|
print(absData)
|
||||||
|
return render_template('group_teach.html', cclass=cclass, absData=absData, dow=dow, currDate=currDate, tmpAbsData=tmpAbsData)
|
||||||
elif pl == 'homeroom':
|
elif pl == 'homeroom':
|
||||||
homeroom = db.child("Users").child(
|
homeroom = db.child("Users").child(
|
||||||
session['uid']).child("homeroom").get().val()
|
session['uid']).child("homeroom").get().val().split('^')
|
||||||
homeroomCode = homeroom.split('^')
|
homeroomData = db.child("Homerooms").child(homeroom[0]).child(
|
||||||
homeroom = db.child("Homerooms").child(
|
homeroom[1]).get().val()
|
||||||
homeroomCode[0]).child(homeroomCode[1]).get().val()
|
absData = homeroomData["Absent"]
|
||||||
categories = homeroom['Categories'].split('^')
|
homeroomData.pop('Absent')
|
||||||
currCategory = categories[0]
|
homeroomData.pop('placeholder')
|
||||||
currDate = ""
|
currDate = ""
|
||||||
gpClasses = db.child("Classes").child(currCategory).get().val()
|
|
||||||
dates = gpClasses['Dates']
|
|
||||||
confirmedClasses = []
|
|
||||||
status = 0
|
|
||||||
|
|
||||||
if fCommand == 'date':
|
if fCommand == 'date':
|
||||||
currDate = fData
|
currDate = fData
|
||||||
tmp1 = 0
|
|
||||||
tmp2 = 0
|
|
||||||
for k in gpClasses['Class']:
|
|
||||||
if k in dates[currDate]:
|
|
||||||
confirmedClasses.append(k)
|
|
||||||
tmp2 += 1
|
|
||||||
tmp1 += 1
|
|
||||||
if tmp1 == tmp2:
|
|
||||||
status = 1
|
|
||||||
else:
|
else:
|
||||||
for i in dates:
|
for i in absData:
|
||||||
if i >= datetime.now(tz).strftime("%Y-%m-%d"):
|
|
||||||
currDate = i
|
currDate = i
|
||||||
tmp1 = 0
|
if i >= datetime.now(tz).strftime("%Y-%m-%d"):
|
||||||
tmp2 = 0
|
|
||||||
for k in gpClasses['Class']:
|
|
||||||
if k in dates[currDate]:
|
|
||||||
confirmedClasses.append(k)
|
|
||||||
tmp2 += 1
|
|
||||||
tmp1 += 1
|
|
||||||
if tmp1 == tmp2:
|
|
||||||
status = 1
|
|
||||||
break
|
break
|
||||||
print("got dates")
|
return render_template('homeroom.html', absData=absData, homeroomCode=homeroom, homeroomData=homeroomData, currDate=currDate, periods=['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9'])
|
||||||
db.child("Classes").child(currCategory).child("Dates")
|
|
||||||
homeroom.pop('Categories')
|
|
||||||
all_stud_list = {}
|
|
||||||
for i in homeroom:
|
|
||||||
all_stud_list[i] = {}
|
|
||||||
all_stud_list[i]['name'] = homeroom[i]['name']
|
|
||||||
all_stud_list[i]['eng_name'] = homeroom[i]['eng_name']
|
|
||||||
all_stud_list[i]['gpClass'] = homeroom[i]['Classes'][currCategory]
|
|
||||||
if all_stud_list[i]['gpClass'] in confirmedClasses:
|
|
||||||
if (homeroomCode[0] in gpClasses['Dates'][currDate]['Absent'] and
|
|
||||||
homeroomCode[1] in gpClasses['Dates'][currDate]['Absent'][homeroomCode[0]] and
|
|
||||||
i in gpClasses['Dates'][currDate]['Absent'][homeroomCode[0]][homeroomCode[1]]):
|
|
||||||
# confirmed by teacher and absent
|
|
||||||
all_stud_list[i]['status'] = 2
|
|
||||||
else:
|
else:
|
||||||
# confirmed by teacher and not absent
|
return redirect('/logout')
|
||||||
all_stud_list[i]['status'] = 1
|
|
||||||
else:
|
|
||||||
all_stud_list[i]['status'] = 0 # not yet confirmed by teacher
|
|
||||||
return render_template('homeroom.html', all_stud_list=all_stud_list, currDate=currDate, dates=dates, gpClasses=gpClasses, confirmedClasses=confirmedClasses,
|
|
||||||
currCategory=currCategory, categories=categories, homeroomCode=homeroomCode, status=status)
|
|
||||||
|
|
||||||
else:
|
|
||||||
return redirect('/')
|
|
||||||
|
|
||||||
|
|
||||||
@ app.route('/', methods=['GET', 'POST'])
|
@ app.route('/', methods=['GET', 'POST'])
|
||||||
|
@ -211,17 +201,26 @@ def index():
|
||||||
return redirect('/manage')
|
return redirect('/manage')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/manage', methods=['GET'])
|
@ app.route('/manage', methods=['GET'])
|
||||||
def manage():
|
def manage():
|
||||||
return manageProcess("", "")
|
return manageProcess("", "")
|
||||||
|
|
||||||
|
|
||||||
@app.route('/manage/date', methods=['POST'])
|
@ app.route('/manage/date', methods=['POST'])
|
||||||
def manage_date():
|
def manage_date():
|
||||||
return manageProcess("date", request.form['date'])
|
return manageProcess("date", request.form['date'])
|
||||||
|
|
||||||
|
|
||||||
@app.route('/manage/group_teach_publish', methods=['POST'])
|
@app.route('/manage/admin', methods=['POST'])
|
||||||
|
def manage_admin():
|
||||||
|
data = [
|
||||||
|
request.form['grade'] + '^' + request.form['room'],
|
||||||
|
request.form['date']
|
||||||
|
]
|
||||||
|
return manageProcess("admin", data)
|
||||||
|
|
||||||
|
|
||||||
|
@ app.route('/manage/group_teach_publish', methods=['POST'])
|
||||||
def group_teach_publish():
|
def group_teach_publish():
|
||||||
classes = db.child("Users").child(
|
classes = db.child("Users").child(
|
||||||
session['uid']).child("class").get().val()
|
session['uid']).child("class").get().val()
|
||||||
|
@ -231,28 +230,83 @@ def group_teach_publish():
|
||||||
"name": db.child("Classes").child(i).child(
|
"name": db.child("Classes").child(i).child(
|
||||||
"Class").child(classes[i]).child("name").get().val(),
|
"Class").child(classes[i]).child("name").get().val(),
|
||||||
"category": i,
|
"category": i,
|
||||||
"class_id": classes[i]
|
"class_id": classes[i],
|
||||||
|
"homerooms": db.child("Classes").child(
|
||||||
|
"GP_Class").child(i).child("Homerooms").get().val()
|
||||||
}
|
}
|
||||||
print("got class")
|
print("got class")
|
||||||
cDate = ""
|
date = request.form['date']
|
||||||
for key in request.form.keys():
|
period = request.form['period']
|
||||||
print(type(key), key)
|
signature = request.form['signatureData']
|
||||||
if key == 'date':
|
signature = signature.removeprefix('data:image/png;base64,')
|
||||||
print('here')
|
signature = bytes(signature, 'utf-8')
|
||||||
cDate = request.form[key]
|
rand = str(randint(100000000000000, 999999999999999))
|
||||||
db.child("Classes").child(cclass['category']).child(
|
rand += ".png"
|
||||||
"Dates").child(request.form[key]).update({'confirmed': 0})
|
with open(os.path.join('temp', rand), "wb") as fh:
|
||||||
db.child("Classes").child(cclass['category']).child(
|
fh.write(base64.decodebytes(signature))
|
||||||
"Dates").child(request.form[key]).update({cclass['class_id']: request.form['signatureData']})
|
storage.child(os.path.join('signatures', rand)
|
||||||
elif key == 'signatureData':
|
).put(os.path.join('temp', rand))
|
||||||
pass
|
|
||||||
else:
|
formData = request.form.to_dict()
|
||||||
# spilt string
|
formData.pop('signatureData')
|
||||||
id = key.split('^')
|
formData.pop('date')
|
||||||
print(id)
|
formData.pop('period')
|
||||||
db.child("Classes").child(cclass['category']).child("Dates").child(
|
for i in formData:
|
||||||
cDate).child("Absent").child(id[0]).child(id[1]).update({id[2]: 1})
|
i = i.split('^')
|
||||||
return "Success!"
|
db.child("Homerooms").child(i[0]).child(i[1]).child(
|
||||||
|
"Absent").child(date).child(period).update({i[2]: 0})
|
||||||
|
for h in cclass['homerooms']:
|
||||||
|
h = h.split('^')
|
||||||
|
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
||||||
|
"Absent").child(date).child(period).child("signature").update({cclass['class_id']: str(storage.child(os.path.join('signatures', rand)).get_url(None))})
|
||||||
|
os.remove(os.path.join('temp', rand))
|
||||||
|
return redirect('/manage')
|
||||||
|
|
||||||
|
|
||||||
|
@ app.route('/manage/homeroom_abs', methods=['POST'])
|
||||||
|
def homeroom_abs_publish():
|
||||||
|
date = request.form['date']
|
||||||
|
homeroom = request.form['homeroom'].split('^')
|
||||||
|
period = request.form['period']
|
||||||
|
signature = request.form['signatureData']
|
||||||
|
signature = signature.removeprefix('data:image/png;base64,')
|
||||||
|
signature = bytes(signature, 'utf-8')
|
||||||
|
rand = str(randint(100000000000000, 999999999999999))
|
||||||
|
rand += ".png"
|
||||||
|
with open(os.path.join('temp', rand), "wb") as fh:
|
||||||
|
fh.write(base64.decodebytes(signature))
|
||||||
|
storage.child(os.path.join('signatures', rand)
|
||||||
|
).put(os.path.join('temp', rand))
|
||||||
|
formData = request.form.to_dict()
|
||||||
|
formData.pop('signatureData')
|
||||||
|
formData.pop('date')
|
||||||
|
formData.pop('homeroom')
|
||||||
|
formData.pop('period')
|
||||||
|
for i in formData:
|
||||||
|
db.child("Homerooms").child(homeroom[0]).child(
|
||||||
|
homeroom[1]).child("Absent").child(date).child(period).update({i: 0})
|
||||||
|
db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child(
|
||||||
|
"Absent").child(date).child(period).update({'signature': str(storage.child(os.path.join('signatures', rand)).get_url(None))})
|
||||||
|
os.remove(os.path.join('temp', rand))
|
||||||
|
return redirect('/manage')
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/manage/homeroom_confirm', methods=['POST'])
|
||||||
|
def homeroom_confirm():
|
||||||
|
date = request.form['date']
|
||||||
|
homeroom = request.form['homeroom'].split('^')
|
||||||
|
signature = request.form['signatureData']
|
||||||
|
signature = signature.removeprefix('data:image/png;base64,')
|
||||||
|
signature = bytes(signature, 'utf-8')
|
||||||
|
rand = str(randint(100000000000000, 999999999999999))
|
||||||
|
rand += ".png"
|
||||||
|
with open(os.path.join('temp', rand), "wb") as fh:
|
||||||
|
fh.write(base64.decodebytes(signature))
|
||||||
|
storage.child(os.path.join('signatures', rand)
|
||||||
|
).put(os.path.join('temp', rand))
|
||||||
|
db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child("Absent").child(date).update(
|
||||||
|
{"confirm": str(storage.child(os.path.join('signatures', rand)).get_url(None))})
|
||||||
|
return redirect('/manage')
|
||||||
|
|
||||||
|
|
||||||
@ app.route('/upload/homeroom', methods=['GET', 'POST'])
|
@ app.route('/upload/homeroom', methods=['GET', 'POST'])
|
||||||
|
@ -280,6 +334,36 @@ def upload_homeroom():
|
||||||
return "Successfully uploaded " + gradec + "-" + classc
|
return "Successfully uploaded " + gradec + "-" + classc
|
||||||
|
|
||||||
|
|
||||||
|
@ app.route('/upload/gp_classes', methods=['GET', 'POST'])
|
||||||
|
def upload_gp_classes():
|
||||||
|
if request.method == 'GET':
|
||||||
|
return render_template('uploadcsv.html', title="Group Classes", url="/upload/gp_classes")
|
||||||
|
elif request.method == 'POST':
|
||||||
|
try:
|
||||||
|
csv_file = request.files['csv']
|
||||||
|
filepath = os.path.join('./temp', csv_file.filename)
|
||||||
|
csv_file.save(filepath)
|
||||||
|
csv_dict = pd.read_csv(filepath)
|
||||||
|
category_cnt = csv_dict.shape[1] - 1
|
||||||
|
for i in range(category_cnt):
|
||||||
|
tmp_csv = csv_dict[csv_dict.columns[i+1]].tolist()
|
||||||
|
for j in range(len(tmp_csv)):
|
||||||
|
if type(tmp_csv[j]) == float:
|
||||||
|
break
|
||||||
|
if j % 4 == 0:
|
||||||
|
db.child("Classes").child("GP_Class").child(csv_dict.columns[i+1]).child("Class").child(
|
||||||
|
tmp_csv[j]).child("name").set(tmp_csv[j+1])
|
||||||
|
db.child("Classes").child("GP_Class").child(csv_dict.columns[i+1]).child("Class").child(
|
||||||
|
tmp_csv[j]).child("teacher").set(tmp_csv[j+2])
|
||||||
|
db.child("Classes").child("GP_Class").child(csv_dict.columns[i+1]).child("Class").child(
|
||||||
|
tmp_csv[j]).child("classroom").set(tmp_csv[j+3])
|
||||||
|
os.remove(filepath)
|
||||||
|
except Exception as e:
|
||||||
|
os.remove(filepath)
|
||||||
|
return "Error. Please try again\n("+str(e)+")"
|
||||||
|
return "Successfully uploaded"
|
||||||
|
|
||||||
|
|
||||||
@ app.route('/upload/stud_in_group', methods=['GET', 'POST'])
|
@ app.route('/upload/stud_in_group', methods=['GET', 'POST'])
|
||||||
def upload_stud_in_group():
|
def upload_stud_in_group():
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
|
@ -295,13 +379,13 @@ def upload_stud_in_group():
|
||||||
csv_dict = csv.DictReader(file)
|
csv_dict = csv.DictReader(file)
|
||||||
headers = csv_dict.fieldnames
|
headers = csv_dict.fieldnames
|
||||||
headers = headers[1:]
|
headers = headers[1:]
|
||||||
|
for h in headers:
|
||||||
|
db.child("Classes").child("GP_Class").child(
|
||||||
|
h).child("Homerooms").update({gradec+'^'+classc: 0})
|
||||||
for row in csv_dict:
|
for row in csv_dict:
|
||||||
for h in headers:
|
for h in headers:
|
||||||
db.child("Homerooms").child(gradec).child(classc).child(
|
db.child("Homerooms").child(gradec).child(classc).child(
|
||||||
row['number']).child("Classes").child(h).set(row[h])
|
row['number']).child("GP_Class").update({h: row[h]})
|
||||||
db.child("Classes").child(h).child("Class").child(row[h]).child(
|
|
||||||
"Students").child(gradec).child(classc).update({str(row['number']): 0})
|
|
||||||
|
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
|
@ -309,6 +393,76 @@ def upload_stud_in_group():
|
||||||
return "Successfully uploaded " + gradec + "-" + classc
|
return "Successfully uploaded " + gradec + "-" + classc
|
||||||
|
|
||||||
|
|
||||||
|
@ app.route('/upload/period_list', methods=['GET', 'POST'])
|
||||||
|
def upload_period_list():
|
||||||
|
if request.method == 'GET':
|
||||||
|
return render_template('uploadcsv.html', title="Period List", url="/upload/period_list")
|
||||||
|
elif request.method == 'POST':
|
||||||
|
try:
|
||||||
|
# get csv
|
||||||
|
gradec = request.form['gradeCode']
|
||||||
|
classc = request.form['classcode']
|
||||||
|
csv_file = request.files['csv']
|
||||||
|
filepath = os.path.join('./temp', csv_file.filename)
|
||||||
|
csv_file.save(filepath)
|
||||||
|
csv_dict = pd.read_csv(filepath)
|
||||||
|
periodCodes = csv_dict['Period Day'].tolist()
|
||||||
|
for i in range(5):
|
||||||
|
tmp_csv = csv_dict[str(i+1)].tolist()
|
||||||
|
print(tmp_csv)
|
||||||
|
for j in range(len(tmp_csv)):
|
||||||
|
if not (periodCodes[j].endswith('-t')):
|
||||||
|
if type(tmp_csv[j]) == float:
|
||||||
|
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
||||||
|
str(i+1)).child(periodCodes[j]).update({'name': '--'})
|
||||||
|
else:
|
||||||
|
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
||||||
|
str(i+1)).child(periodCodes[j]).update({'name': tmp_csv[j]})
|
||||||
|
if not(periodCodes[j] == 'm' or periodCodes[j] == 'n'):
|
||||||
|
j += 1
|
||||||
|
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
||||||
|
str(i+1)).child(periodCodes[j-1]).update({'teacher': tmp_csv[j]})
|
||||||
|
os.remove(filepath)
|
||||||
|
except Exception as e:
|
||||||
|
os.remove(filepath)
|
||||||
|
return "Error. Please try again\n("+str(e)+")"
|
||||||
|
return "Successfully uploaded " + gradec + "-" + classc
|
||||||
|
|
||||||
|
|
||||||
|
@ app.route('/upload/dates', methods=['GET', 'POST'])
|
||||||
|
def upload_dates():
|
||||||
|
if request.method == 'GET':
|
||||||
|
return render_template('uploadcsv.html', title="School Days", url="/upload/dates")
|
||||||
|
elif request.method == 'POST':
|
||||||
|
try:
|
||||||
|
csv_file = request.files['csv']
|
||||||
|
filepath = os.path.join('./temp', csv_file.filename)
|
||||||
|
csv_file.save(filepath)
|
||||||
|
with open(filepath) as file:
|
||||||
|
csv_dict = csv.DictReader(file)
|
||||||
|
headers = csv_dict.fieldnames
|
||||||
|
temp = db.child("Homerooms").get().val()
|
||||||
|
for row in csv_dict:
|
||||||
|
for h in headers:
|
||||||
|
for t in temp:
|
||||||
|
for i in temp[t]:
|
||||||
|
periodData = db.child("Classes").child(
|
||||||
|
"Homeroom").child(t).child(i).get().val()
|
||||||
|
print(type(t), t)
|
||||||
|
print(type(i), i)
|
||||||
|
db.child("Homerooms").child(t).child(i).child(
|
||||||
|
"Absent").child(h).update({"dow": row[h]})
|
||||||
|
db.child("Homerooms").child(t).child(i).child(
|
||||||
|
"Absent").child(h).update(
|
||||||
|
periodData[int(row[h])]
|
||||||
|
)
|
||||||
|
os.remove(filepath)
|
||||||
|
except Exception as e:
|
||||||
|
os.remove(filepath)
|
||||||
|
return "Error. Please try again\n("+str(e)+")"
|
||||||
|
return "Successfully uploaded dates"
|
||||||
|
|
||||||
|
|
||||||
# @ app.route('/upload/rm_all_data_of_class', methods=['GET', "POST"])
|
# @ app.route('/upload/rm_all_data_of_class', methods=['GET', "POST"])
|
||||||
# def rm_all_data_of_class():
|
# def rm_all_data_of_class():
|
||||||
# if request.method == 'GET':
|
# if request.method == 'GET':
|
||||||
|
@ -322,7 +476,7 @@ def upload_stud_in_group():
|
||||||
# return "Successfully removed " + classc
|
# return "Successfully removed " + classc
|
||||||
|
|
||||||
|
|
||||||
@app.route('/logout', methods=['GET'])
|
@ app.route('/logout', methods=['GET'])
|
||||||
def logout():
|
def logout():
|
||||||
session.clear()
|
session.clear()
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
|
|
|
@ -7,13 +7,13 @@ Flask == 2.0.1
|
||||||
# Attendance/test.py: 1
|
# Attendance/test.py: 1
|
||||||
Pyrebase == 3.0.27
|
Pyrebase == 3.0.27
|
||||||
|
|
||||||
# Attendance/app.py: 9
|
# Attendance/app.py: 7
|
||||||
|
pandas == 1.1.3
|
||||||
|
|
||||||
|
# Attendance/app.py: 10
|
||||||
# Attendance/test.py: 3
|
# Attendance/test.py: 3
|
||||||
python_dotenv == 0.19.0
|
python_dotenv == 0.19.0
|
||||||
|
|
||||||
# Attendance/app.py: 4
|
# Attendance/app.py: 4
|
||||||
pytz == 2020.1
|
pytz == 2020.1
|
||||||
|
|
||||||
# Attendance/app.py: 5,6
|
|
||||||
sendgrid == 6.7.1
|
|
||||||
gunicorn == 20.1.0
|
gunicorn == 20.1.0
|
|
@ -30,6 +30,14 @@ div.forSign canvas {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.margin-bottom {
|
||||||
|
margin-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.signDiv {
|
||||||
|
margin-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
p.highlightAbs {
|
p.highlightAbs {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +50,6 @@ p.highlightAbs.n-2 {
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.classlist {
|
.margin-top {
|
||||||
text-align: left;
|
margin-top: 20px;
|
||||||
}
|
}
|
22
static/homeroom.css
Normal file
22
static/homeroom.css
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
div.container {
|
||||||
|
max-width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn.afterSelButton {
|
||||||
|
padding: .200rem .50rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
body {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewSignatures .col .row .col {
|
||||||
|
border: 1px solid;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
--bs-gutter-x: 0;
|
||||||
|
}
|
|
@ -0,0 +1,221 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Admin_View</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
|
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet" href="/static/allpages.css">
|
||||||
|
<link rel="stylesheet" href="/static/homeroom.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Admin_View</h1>
|
||||||
|
<h2>{{homeroomCode[0]}}: {{homeroomCode[1]}}</h2>
|
||||||
|
<h2>Status: ({{currDate}}, 星期{{absData[currDate]['dow']}})</h2>
|
||||||
|
<a href="/logout"><button class="btn btn-primary">Logout 登出</button></a>
|
||||||
|
<div class="container margin-bottom">
|
||||||
|
<form action="/manage/admin" id="adminSelForm" method="post">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<select name="grade" id="sel-grade" class="form-select" onchange="getHR()" required>
|
||||||
|
<option value="">選擇年級</option>
|
||||||
|
{% for grade in homerooms %}
|
||||||
|
<option value="{{grade}}">{{grade}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<select name="room" id="sel-room" class="form-select" disabled required>
|
||||||
|
<option value="">請先選擇年級</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<select name="date" id="date" class="form-select">
|
||||||
|
{% for date in absData %}
|
||||||
|
{% if date == currDate %}
|
||||||
|
<option value="{{date}}" selected="selected">{{date}}</option>
|
||||||
|
{% else %}
|
||||||
|
<option value="{{date}}">{{date}}</option>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-1">
|
||||||
|
<button class="btn btn-primary" onclick="loadingAnimation()">查詢</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row title">
|
||||||
|
<div class="col">HR</div>
|
||||||
|
<div class="col">Number</div>
|
||||||
|
<div class="col">Name</div>
|
||||||
|
<div class="col">Eng Name</div>
|
||||||
|
<div class="col">Morning</div>
|
||||||
|
<div class="col">1</div>
|
||||||
|
<div class="col">2</div>
|
||||||
|
<div class="col">3</div>
|
||||||
|
<div class="col">4</div>
|
||||||
|
<div class="col">Nap</div>
|
||||||
|
<div class="col">5</div>
|
||||||
|
<div class="col">6</div>
|
||||||
|
<div class="col">7</div>
|
||||||
|
<div class="col">8</div>
|
||||||
|
<div class="col">9</div>
|
||||||
|
</div>
|
||||||
|
<div class="row title">
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
{% for i in periods %}
|
||||||
|
<div class="col">{{absData[currDate][i]['name']}}</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="row title">
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
{% for i in periods %}
|
||||||
|
<div class="col">{{absData[currDate][i]['teacher']}}</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% if data != None %}
|
||||||
|
{% for i in homeroomData %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">{{homeroomCode[0]}}{{homeroomCode[1]}}</div>
|
||||||
|
<div class="col">{{i}}</div>
|
||||||
|
<div class="col">{{ homeroomData[i]['name'] }}</div>
|
||||||
|
<div class="col">{{ homeroomData[i]['eng_name'] }}</div>
|
||||||
|
{% for j in periods %}
|
||||||
|
{% if 'signature' in absData[currDate][j] %}
|
||||||
|
{% if i in absData[currDate][j] %}
|
||||||
|
<div class="col">
|
||||||
|
<p class="highlightAbs n-2">X</p>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
{% if absData[currDate][j]['name'] != 'GP' %}
|
||||||
|
<div class="col">
|
||||||
|
<p class="highlightAbs n-1">V</p>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
{% if (homeroomData[i]['GP_Class'][absData[currDate][j]['teacher']] in
|
||||||
|
absData[currDate][j]['signature'])%}
|
||||||
|
<div class="col">
|
||||||
|
<p class="highlightAbs n-1">V</p>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="col">
|
||||||
|
<p class="highlightAbs n-2"></p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<div class="col">
|
||||||
|
<p class="highlightAbs"></p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% for c in range(periods|length + 1) %}
|
||||||
|
{% if c % 2 == 0 %}
|
||||||
|
<div class="row signatures">
|
||||||
|
{% endif %}
|
||||||
|
<div class="col half">
|
||||||
|
{% if c == 0 %}
|
||||||
|
<div class="row">Homeroom Teacher</div>
|
||||||
|
<div class="row"><img src="{{absData[currDate]['confirm']}}" alt=""></div>
|
||||||
|
{% else %}
|
||||||
|
{% if absData[currDate][periods[c-1]]['name'] == 'GP' %}
|
||||||
|
{% if 'signature' in absData[currDate][periods[c-1]] %}
|
||||||
|
{% for i in absData[currDate][periods[c-1]]['signature'] %}
|
||||||
|
<div class="row">{{periods[c-1]}}: {{absData[currDate][periods[c-1]]['teacher']}}: {{i}}</div>
|
||||||
|
<div class="row"><img src="{{absData[currDate][periods[c-1]]['signature'][i]}}" alt=""></div>
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<div class="row">{{periods[c-1]}}: {{absData[currDate][periods[c-1]]['teacher']}}: No Signature
|
||||||
|
</div>
|
||||||
|
<div class="row"></div>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<div class="row">{{periods[c-1]}}: {{absData[currDate][periods[c-1]]['name']}}:
|
||||||
|
{{absData[currDate][periods[c-1]]['teacher']}}
|
||||||
|
</div>
|
||||||
|
<div class="row"><img src="{{absData[currDate][periods[c-1]]['signature']}}" alt=""></div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% if c % 2 == 1 %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="row margin-top">
|
||||||
|
<div class="col">
|
||||||
|
<h3>此排請勿點選</h3>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<a href="/upload/homeroom"><button class="btn btn-primary">1. Add Homeroom</button></a>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<a href="/upload/gp_classes"><button class="btn btn-primary">2. Add GP Classes</button></a>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<a href="/upload/stud_in_group"><button class="btn btn-primary">3. Add GP Student List</button></a>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<a href="/upload/period_list"><button class="btn btn-primary">4. Period List</button></a>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<a href="/upload/dates"><button class="btn btn-primary">[WEEKLY] Dates</button></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
|
||||||
|
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
||||||
|
style="height:100%;" />
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
var homerooms = {};
|
||||||
|
{% for i in homerooms %}
|
||||||
|
homerooms['{{i}}'] = [];
|
||||||
|
{% for j in homerooms[i] %}
|
||||||
|
homerooms['{{i}}'].push({{ j }});
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
console.log(homerooms)
|
||||||
|
function loadingAnimation() {
|
||||||
|
$('.container').hide();
|
||||||
|
$('#loading').show();
|
||||||
|
}
|
||||||
|
function getHR() {
|
||||||
|
var grade = $('#sel-grade').val();
|
||||||
|
$('#sel-room').html('<option value="">請先選擇年級</option>');
|
||||||
|
if (grade === "") {
|
||||||
|
$('#sel-room').attr('disabled', 'disabled')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
homerooms[grade].forEach(element => {
|
||||||
|
$('#sel-room').append(`<option value="${element}">${element}</option>`)
|
||||||
|
});
|
||||||
|
$('#sel-room').removeAttr('disabled')
|
||||||
|
}
|
||||||
|
function submitQuery() {
|
||||||
|
loadingAnimation();
|
||||||
|
document.getElementById('hrSelForm').submit();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -16,10 +16,11 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Group_Teach_View</h1>
|
<h1>Group_Teach_View</h1>
|
||||||
<h2>{{cclass['category']}}: {{cclass['class_id']}}: {{cclass['name']}}</h2>
|
<h2>{{cclass['category']}}: {{cclass['class_id']}}: {{cclass['name']}}</h2>
|
||||||
<h2>Status: {{status}} ({{currDate}})</h2>
|
<h2>({{currDate}}) ({{dow}})</h2>
|
||||||
|
<a href="/logout"><button class="btn btn-primary">Logout 登出</button></a>
|
||||||
<form action="/manage/date" id="dateSelForm" method="post">
|
<form action="/manage/date" id="dateSelForm" method="post">
|
||||||
<select name="date" id="date" class="form-select" onchange="chgDate(this);">
|
<select name="date" id="date" class="form-select" onchange="chgDate(this);">
|
||||||
{% for date in dates %}
|
{% for date in tmpAbsData %}
|
||||||
{% if date == currDate %}
|
{% if date == currDate %}
|
||||||
<option value="{{date}}" selected="selected">{{date}}</option>
|
<option value="{{date}}" selected="selected">{{date}}</option>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -28,15 +29,12 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</form>
|
</form>
|
||||||
{% if status == 1 %}
|
{% set alr_fill = namespace(found=false) %}
|
||||||
<div class="alert alert-warning" role="alert">
|
{% for i in absData %}
|
||||||
Already Sumitted!
|
<form action="/manage/group_teach_publish" id="attendanceData^{{i}}" method="post">
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% if status == 0 %}
|
|
||||||
<form action="/manage/group_teach_publish" id="attendanceData" method="post">
|
|
||||||
<input type="hidden" name="date" value="{{currDate}}">
|
<input type="hidden" name="date" value="{{currDate}}">
|
||||||
<input type="hidden" name="signatureData" value="">
|
<input type="hidden" name="period" value="{{i}}">
|
||||||
|
<input type="hidden" class="signatureData" name="signatureData" value="">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row title">
|
<div class="row title">
|
||||||
<div class="col">Grade</div>
|
<div class="col">Grade</div>
|
||||||
|
@ -44,35 +42,85 @@
|
||||||
<div class="col">Number</div>
|
<div class="col">Number</div>
|
||||||
<div class="col">Name</div>
|
<div class="col">Name</div>
|
||||||
<div class="col">Eng Name</div>
|
<div class="col">Eng Name</div>
|
||||||
<div class="col">Attendance (Check Absent)</div>
|
<div class="col">Period {{i}}</div>
|
||||||
</div>
|
</div>
|
||||||
{% if data != None %}
|
{% if data != None %}
|
||||||
{% for grade in all_stud_list %}
|
{% for grade in absData[i] %}
|
||||||
{% for homeroom in all_stud_list[grade] %}
|
{% for homeroom in absData[i][grade] %}
|
||||||
{% for student in all_stud_list[grade][homeroom] %}
|
{% for student in absData[i][grade][homeroom] %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">{{grade}}</div>
|
<div class="col">{{grade}}</div>
|
||||||
<div class="col">{{homeroom}}</div>
|
<div class="col">{{homeroom}}</div>
|
||||||
<div class="col">{{ student }}</div>
|
<div class="col">{{ student }}</div>
|
||||||
<div class="col">{{ all_stud_list[grade][homeroom][student]['name'] }}</div>
|
<div class="col">{{ absData[i][grade][homeroom][student]['name'] }}</div>
|
||||||
<div class="col">{{ all_stud_list[grade][homeroom][student]['eng_name'] }}</div>
|
<div class="col">{{ absData[i][grade][homeroom][student]['eng_name'] }}</div>
|
||||||
<div class="col"><input type="checkbox" name="{{grade}}^{{homeroom}}^{{student}}"></div>
|
{% if absData[i][grade][homeroom][student]['alr_fill'] %}
|
||||||
|
{% set alr_fill.found = true %}
|
||||||
|
{% if absData[i][grade][homeroom][student]['absent'] %}
|
||||||
|
<div class="col">
|
||||||
|
<p class="highlightAbs n-2">X</p>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="col">
|
||||||
|
<p class="highlightAbs n-1">V</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<div class="col">
|
||||||
|
{% if 'confirm' in absData[i][grade][homeroom] %}
|
||||||
|
<p class="highlightAbs">--</p>
|
||||||
|
{% else %}
|
||||||
|
<input type="checkbox" class="{{grade}}^{{homeroom}}^{{student}}">
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if alr_fill.found %}
|
||||||
|
<button class="btn btn-primary margin-bottom viewSignatureBtn" type="button"
|
||||||
|
onclick="viewSignature('{{i}}')" disabled="disabled">
|
||||||
|
Already Submitted</button>
|
||||||
|
{% else %}
|
||||||
|
<button class="btn btn-primary margin-bottom viewSignatureBtn" type="button"
|
||||||
|
onclick="viewSignature('{{i}}')">
|
||||||
|
↑ Confirmed, Sign (Period {{i}}) ↑</button>
|
||||||
|
{% endif %}
|
||||||
|
<div class="signDiv" id="sign^{{i}}" hidden="hidden">
|
||||||
<h3>Please Sign Below</h3>
|
<h3>Please Sign Below</h3>
|
||||||
<div class="forSign"><canvas id="signature_pad"></canvas></div>
|
<div class="forSign"><canvas id="signature_pad^{{i}}"></canvas></div>
|
||||||
<button class="btn btn-secondary" type="button" onclick="signaturePad.clear()">Clear Signature</button>
|
<button class="btn btn-secondary" type="button" onclick="signaturePad.clear()">Clear
|
||||||
<button class="btn btn-primary" type="button" onclick="submitForm()">Submit</button>
|
Signature</button><button class="btn btn-primary" type="button"
|
||||||
|
onclick="submitForm()">Submit</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/signature_pad@2.3.2/dist/signature_pad.min.js"></script>
|
<script src=" https://cdn.jsdelivr.net/npm/signature_pad@2.3.2/dist/signature_pad.min.js"></script>
|
||||||
|
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
var canvas = document.getElementById("signature_pad");
|
var signaturePad, selPeriod;
|
||||||
var signaturePad = new SignaturePad(canvas);
|
function submitForm() {
|
||||||
|
if (!signaturePad.isEmpty()) {
|
||||||
|
signaturePad.off();
|
||||||
|
var data = signaturePad.toDataURL('image/png');
|
||||||
|
document.getElementById("attendanceData^" + selPeriod).getElementsByClassName("signatureData")[0].value = data;
|
||||||
|
document.getElementById("attendanceData^" + selPeriod).submit();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert("Please sign first");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function viewSignature(period) {
|
||||||
|
selPeriod = period
|
||||||
|
$('.viewSignatureBtn').attr({ 'disabled': 'disabled' });
|
||||||
|
$('.viewSignatureBtn').removeClass('margin-bottom');
|
||||||
|
document.getElementById('sign^' + period).removeAttribute('hidden');
|
||||||
|
var canvas = document.getElementById("signature_pad^" + period);
|
||||||
|
signaturePad = new SignaturePad(canvas);
|
||||||
function resizeCanvas() {
|
function resizeCanvas() {
|
||||||
var ratio = Math.max(window.devicePixelRatio || 1, 1);
|
var ratio = Math.max(window.devicePixelRatio || 1, 1);
|
||||||
canvas.width = canvas.offsetWidth * ratio;
|
canvas.width = canvas.offsetWidth * ratio;
|
||||||
|
@ -82,20 +130,8 @@
|
||||||
}
|
}
|
||||||
window.addEventListener("resize", resizeCanvas);
|
window.addEventListener("resize", resizeCanvas);
|
||||||
resizeCanvas();
|
resizeCanvas();
|
||||||
function submitForm() {
|
|
||||||
if (!signaturePad.isEmpty()) {
|
|
||||||
signaturePad.off();
|
|
||||||
var data = signaturePad.toDataURL('image/png');
|
|
||||||
document.getElementsByName('signatureData')[0].value = data;
|
|
||||||
document.getElementById('attendanceData').submit();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alert("Please sign first");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
|
||||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
|
|
||||||
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
||||||
style="height:100%;" />
|
style="height:100%;" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,17 +9,18 @@
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
|
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="/static/allpages.css">
|
<link rel="stylesheet" href="/static/allpages.css">
|
||||||
<link rel="stylesheet" href="/static/login.css">
|
<link rel="stylesheet" href="/static/homeroom.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Homeroom_View</h1>
|
<h1>Homeroom_View</h1>
|
||||||
<h2>{{homeroomCode[0]}}: {{homeroomCode[1]}}</h2>
|
<h2>{{homeroomCode[0]}}: {{homeroomCode[1]}}</h2>
|
||||||
<h2>Status: ({{currDate}})</h2>
|
<h2>Status: ({{currDate}}, 星期{{absData[currDate]['dow']}})</h2>
|
||||||
|
<a href="/logout"><button class="btn btn-primary">Logout 登出</button></a>
|
||||||
<form action="/manage/date" id="dateSelForm" method="post">
|
<form action="/manage/date" id="dateSelForm" method="post">
|
||||||
<select name="date" id="date" class="form-select" onchange="chgDate();">
|
<select name="date" id="date" class="form-select" onchange="chgDate();">
|
||||||
{% for date in dates %}
|
{% for date in absData %}
|
||||||
{% if date == currDate %}
|
{% if date == currDate %}
|
||||||
<option value="{{date}}" selected="selected">{{date}}</option>
|
<option value="{{date}}" selected="selected">{{date}}</option>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -30,87 +31,201 @@
|
||||||
</form>
|
</form>
|
||||||
<form action="/manage/homeroom_confirm" id="homeroom_confirm" method="post">
|
<form action="/manage/homeroom_confirm" id="homeroom_confirm" method="post">
|
||||||
<input type="hidden" name="date" value="{{currDate}}">
|
<input type="hidden" name="date" value="{{currDate}}">
|
||||||
<input type="hidden" name="category" value="{{currCategory}}">
|
<input type="hidden" name="homeroom" value="{{homeroomCode[0]}}^{{homeroomCode[1]}}">
|
||||||
<input type="hidden" name="signatureData" value="">
|
<input type="hidden" id="hrCfrm-sign" name="signatureData" value="">
|
||||||
</form>
|
</form>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row title">
|
<div class="row title">
|
||||||
<div class="col">Homeroom</div>
|
<div class="col">HR</div>
|
||||||
<div class="col">Number</div>
|
<div class="col">Number</div>
|
||||||
<div class="col">Name</div>
|
<div class="col">Name</div>
|
||||||
<div class="col">Eng Name</div>
|
<div class="col">Eng Name</div>
|
||||||
<div class="col">GP_Class</div>
|
<div class="col">Morning</div>
|
||||||
<div class="col">Attendance (Here=V, Abs=X)</div>
|
<div class="col">1</div>
|
||||||
|
<div class="col">2</div>
|
||||||
|
<div class="col">3</div>
|
||||||
|
<div class="col">4</div>
|
||||||
|
<div class="col">Nap</div>
|
||||||
|
<div class="col">5</div>
|
||||||
|
<div class="col">6</div>
|
||||||
|
<div class="col">7</div>
|
||||||
|
<div class="col">8</div>
|
||||||
|
<div class="col">9</div>
|
||||||
|
</div>
|
||||||
|
<div class="row title">
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
{% for i in periods %}
|
||||||
|
<div class="col">{{absData[currDate][i]['name']}}</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="row title">
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
{% for i in periods %}
|
||||||
|
<div class="col">{{absData[currDate][i]['teacher']}}</div>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% if data != None %}
|
{% if data != None %}
|
||||||
{% for i in all_stud_list %}
|
{% for i in homeroomData %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">{{homeroomCode[0]}}{{homeroomCode[1]}}</div>
|
<div class="col">{{homeroomCode[0]}}{{homeroomCode[1]}}</div>
|
||||||
<div class="col">{{i}}</div>
|
<div class="col">{{i}}</div>
|
||||||
<div class="col">{{ all_stud_list[i]['name'] }}</div>
|
<div class="col">{{ homeroomData[i]['name'] }}</div>
|
||||||
<div class="col">{{ all_stud_list[i]['eng_name'] }}</div>
|
<div class="col">{{ homeroomData[i]['eng_name'] }}</div>
|
||||||
<div class="col">{{ all_stud_list[i]['gpClass'] }}:
|
{% for j in periods %}
|
||||||
{{gpClasses['Class'][all_stud_list[i]['gpClass']]['name']}}</div>
|
{% if 'signature' in absData[currDate][j] %}
|
||||||
|
{% if i in absData[currDate][j] %}
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<p class="highlightAbs n-{{all_stud_list[i]['status']}}">
|
<p class="highlightAbs n-2">X</p>
|
||||||
{% if all_stud_list[i]['status'] == 1 %}
|
|
||||||
V
|
|
||||||
{% elif all_stud_list[i]['status'] == 2 %}
|
|
||||||
X
|
|
||||||
{% endif %}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
{% else %}
|
||||||
|
{% if absData[currDate][j]['name'] != 'GP' %}
|
||||||
|
<div class="col">
|
||||||
|
<p class="highlightAbs n-1">V</p>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
{% if (homeroomData[i]['GP_Class'][absData[currDate][j]['teacher']] in
|
||||||
|
absData[currDate][j]['signature'])%}
|
||||||
|
<div class="col">
|
||||||
|
<p class="highlightAbs n-1">V</p>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="col">
|
||||||
|
<p class="highlightAbs n-2"></p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% elif absData[currDate][j]['name'] == 'GP' %}
|
||||||
|
<div class="col">
|
||||||
|
<p class="highlightAbs"></p>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="col">
|
||||||
|
{% if 'confirm' in absData[currDate] %}
|
||||||
|
<p class="highlightAbs"></p>
|
||||||
|
{% else %}
|
||||||
|
<input type="checkbox" class="tobeform {{j}}^{{i}}">
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
{% for i in periods %}
|
||||||
|
<div class="col">
|
||||||
|
{% if ('signature' in absData[currDate][i] or absData[currDate][i]['name'] == 'GP' or
|
||||||
|
'confirm' in absData[currDate]) %}
|
||||||
|
<button class="btn btn-primary afterSelButton" disabled="disabled"
|
||||||
|
onclick="afterSelAbs('{{i|string}}')">Confirm</button>
|
||||||
|
{% else %}
|
||||||
|
<button class="btn btn-primary afterSelButton"
|
||||||
|
onclick="afterSelAbs('{{i|string}}')">Confirm</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<!-- show signature of confirmed classes -->
|
</div>
|
||||||
{% for c in range(confirmedClasses|length) %}
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<form action="/manage/homeroom_abs" id="postHomeroomAbs" hidden="hidden" method="post">
|
||||||
|
<input type="text" id="HR-date" name="date" value="{{currDate}}">
|
||||||
|
<input type="text" id="HR-period" name="period" value="">
|
||||||
|
<input type="text" id="HR-signatureData" name="signatureData" value="">
|
||||||
|
<input type="text" id="HR-homeroom" name="homeroom" value="{{homeroomCode[0]}}^{{homeroomCode[1]}}">
|
||||||
|
</form>
|
||||||
|
{% if 'confirm' in absData[currDate] %}
|
||||||
|
<button class="btn btn-primary margin-top afterSelButton" onclick="homeroomCfrm()" disabled="disabled">
|
||||||
|
Already Confirmed</button>
|
||||||
|
{% else %}
|
||||||
|
<button class="btn btn-primary margin-top afterSelButton" onclick="homeroomCfrm()">Homeroom
|
||||||
|
Teacher Confirm</button>
|
||||||
|
{% endif %}
|
||||||
|
<div id="finalCheck" hidden="hidden">
|
||||||
|
<h3>Please Sign Below</h3>
|
||||||
|
<div class="forSign"><canvas id="signature_pad"></canvas></div>
|
||||||
|
<button class="btn btn-secondary" type="button" onclick="signaturePad.clear()">Clear Signature</button>
|
||||||
|
<button class="btn btn-primary" type="button" onclick="submitForm()">Submit</button>
|
||||||
|
</div>
|
||||||
|
{% for c in range(periods|length + 1) %}
|
||||||
{% if c % 2 == 0 %}
|
{% if c % 2 == 0 %}
|
||||||
<div class="row signatures">
|
<div class="row signatures">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="col half">
|
<div class="col half">
|
||||||
<div class="row">{{confirmedClasses[c]}}: {{gpClasses['Class'][confirmedClasses[c]]['name']}}
|
{% if c == 0 %}
|
||||||
|
<div class="row">Homeroom Teacher</div>
|
||||||
|
<div class="row"><img src="{{absData[currDate]['confirm']}}" alt=""></div>
|
||||||
|
{% else %}
|
||||||
|
{% if absData[currDate][periods[c-1]]['name'] == 'GP' %}
|
||||||
|
{% if 'signature' in absData[currDate][periods[c-1]] %}
|
||||||
|
{% for i in absData[currDate][periods[c-1]]['signature'] %}
|
||||||
|
<div class="row">{{periods[c-1]}}: {{absData[currDate][periods[c-1]]['teacher']}}: {{i}}</div>
|
||||||
|
<div class="row"><img src="{{absData[currDate][periods[c-1]]['signature'][i]}}" alt=""></div>
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<div class="row">{{periods[c-1]}}: {{absData[currDate][periods[c-1]]['teacher']}}: No Signature
|
||||||
</div>
|
</div>
|
||||||
<div class="row"><img src="{{gpClasses['Dates'][currDate][confirmedClasses[c]]}}" alt=""></div>
|
<div class="row"></div>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<div class="row">{{periods[c-1]}}: {{absData[currDate][periods[c-1]]['name']}}:
|
||||||
|
{{absData[currDate][periods[c-1]]['teacher']}}
|
||||||
|
</div>
|
||||||
|
<div class="row"><img src="{{absData[currDate][periods[c-1]]['signature']}}" alt=""></div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if c % 2 == 1 %}
|
{% if c % 2 == 1 %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<!-- Show Class Data -->
|
|
||||||
<div class="classlist">
|
|
||||||
<h2>Classes in {{currCategory}}</h2>
|
|
||||||
<ul>
|
|
||||||
{% for c in gpClasses['Class'] %}
|
|
||||||
<li>
|
|
||||||
<h3>{{c}}: {{gpClasses['Class'][c]['name']}}</h3>
|
|
||||||
</li>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<h4>Classroom: {{ gpClasses['Class'][c]['classroom'] }}</h4>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<h4>Teacher: {{ gpClasses['Class'][c]['teacher'] }}</h4>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{% if status == 1 %}
|
|
||||||
<h3>Please Sign Below</h3>
|
|
||||||
<div class="forSign"><canvas id="signature_pad"></canvas></div>
|
|
||||||
<button class="btn btn-secondary" type="button" onclick="signaturePad.clear()">Clear Signature</button>
|
|
||||||
<button class="btn btn-primary" type="button" onclick="submitForm()">Submit</button>
|
|
||||||
{% else %}
|
|
||||||
<h3>Please wait for all {{currCategory}} teachers to enter data.</h3>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if status == 1 %}
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/signature_pad@2.3.2/dist/signature_pad.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/signature_pad@2.3.2/dist/signature_pad.min.js"></script>
|
||||||
|
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
|
||||||
|
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
||||||
|
style="height:100%;" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
var signaturePad, hrCfrm = false;
|
||||||
|
function loadingAnimation() {
|
||||||
|
$('.container').hide();
|
||||||
|
$('#loading').show();
|
||||||
|
}
|
||||||
|
function chgDate() {
|
||||||
|
loadingAnimation();
|
||||||
|
document.getElementById('dateSelForm').submit();
|
||||||
|
}
|
||||||
|
function submitForm() {
|
||||||
|
if (!signaturePad.isEmpty()) {
|
||||||
|
loadingAnimation()
|
||||||
|
signaturePad.off();
|
||||||
|
var data = signaturePad.toDataURL('image/png');
|
||||||
|
if (hrCfrm) {
|
||||||
|
$('#hrCfrm-sign').val(data);
|
||||||
|
document.getElementById('homeroom_confirm').submit()
|
||||||
|
} else {
|
||||||
|
document.getElementById('HR-signatureData').value = data;
|
||||||
|
document.getElementById('postHomeroomAbs').submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert("Please sign first");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function showSignaturePad() {
|
||||||
|
$('#finalCheck').removeAttr('hidden');
|
||||||
var canvas = document.getElementById("signature_pad");
|
var canvas = document.getElementById("signature_pad");
|
||||||
var signaturePad = new SignaturePad(canvas);
|
signaturePad = new SignaturePad(canvas);
|
||||||
function resizeCanvas() {
|
function resizeCanvas() {
|
||||||
var ratio = Math.max(window.devicePixelRatio || 1, 1);
|
var ratio = Math.max(window.devicePixelRatio || 1, 1);
|
||||||
canvas.width = canvas.offsetWidth * ratio;
|
canvas.width = canvas.offsetWidth * ratio;
|
||||||
|
@ -120,31 +235,25 @@
|
||||||
}
|
}
|
||||||
window.addEventListener("resize", resizeCanvas);
|
window.addEventListener("resize", resizeCanvas);
|
||||||
resizeCanvas();
|
resizeCanvas();
|
||||||
function submitForm() {
|
|
||||||
if (!signaturePad.isEmpty()) {
|
|
||||||
signaturePad.off();
|
|
||||||
var data = signaturePad.toDataURL('image/png');
|
|
||||||
document.getElementsByName('signatureData')[0].value = data;
|
|
||||||
document.getElementsByTagName('form')[0].submit();
|
|
||||||
}
|
}
|
||||||
else {
|
function afterSelAbs(period) {
|
||||||
alert("Please sign first");
|
var tobeformArr = [];
|
||||||
|
$('#postHomeroomAbs #HR-period').val(period);
|
||||||
|
$('.tobeform').attr('disabled', 'disabled');
|
||||||
|
$('.afterSelButton').attr('disabled', 'disabled');
|
||||||
|
$('.tobeform').each(function (i, obj) {
|
||||||
|
if ($(this).attr('class').split(' ')[1].split('^')[0] == period &&
|
||||||
|
$(this).is(":checked")) {
|
||||||
|
$('#postHomeroomAbs').append('<input type="checkbox" name="' + $(this).attr('class').split(' ')[1].split('^')[1]
|
||||||
|
+ '" checked="checked">');
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
// show signature pad
|
||||||
|
showSignaturePad()
|
||||||
}
|
}
|
||||||
</script>
|
function homeroomCfrm() {
|
||||||
{% endif %}
|
hrCfrm = true;
|
||||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
|
showSignaturePad();
|
||||||
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
|
||||||
style="height:100%;" />
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
function loadingAnimation() {
|
|
||||||
$('.container').hide();
|
|
||||||
$('#loading').show();
|
|
||||||
}
|
|
||||||
function chgDate() {
|
|
||||||
loadingAnimation();
|
|
||||||
document.getElementById('dateSelForm').submit();
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -34,11 +34,28 @@
|
||||||
<label for="csv">{{title}}</label>
|
<label for="csv">{{title}}</label>
|
||||||
<input type="file" class="form-control-file" id="csv" name="csv">
|
<input type="file" class="form-control-file" id="csv" name="csv">
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary">Upload</button>
|
<button onclick="loadingAnimation()" type="submit" class="btn btn-primary">Upload</button>
|
||||||
</form>
|
</form>
|
||||||
|
<!-- show danger zone -->
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
<h4 class="alert-heading">Warning! 警告!</h4>
|
||||||
|
<p>If you are not the adminstrator, please do not click "upload" This might make the system
|
||||||
|
unuseable.</p>
|
||||||
|
<p>非管理員請勿點選! 可能會讓系統無法使用!</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
||||||
|
style="height:100%;" />
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
|
||||||
|
<script>
|
||||||
|
function loadingAnimation() {
|
||||||
|
$('.container').hide();
|
||||||
|
$('#loading').show();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<!-- end csv form center -->
|
<!-- end csv form center -->
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue