├── .gitignore ├── App ├── absen.html ├── css │ ├── bootstrap-style.css │ ├── bootstrap.min.css │ ├── darkmode.css │ ├── left.css │ ├── login.css │ ├── right.css │ ├── style.css │ └── sweetalert.css ├── dist │ └── index.dev.js ├── img │ ├── bg-01.jpg │ ├── chandrika.jpg │ ├── wavesOpacity 2.svg │ ├── wavesOpacity 3.svg │ └── wavesOpacity.svg ├── index.html ├── index.js └── js │ ├── darkmode.js │ ├── login.js │ ├── main.js │ ├── saveDataSiswa.js │ ├── sidebar.js │ ├── sweetAlertConfiguration.js │ └── sweetalert2.all.min.js ├── Dist ├── absen.html ├── bundle.js ├── bundle.js.LICENSE.txt ├── index.html └── webpack.common.dev.js ├── Screenshot ├── 1.png ├── 2.png └── 3.png ├── debug.log ├── package-lock.json ├── package.json ├── readme.md ├── webpack.common.js ├── webpack.dev.js └── webpack.prod.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /App/absen.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Absen Siswa 8 | 9 | 10 | 11 |
12 | 39 |
40 |
41 |
42 |
43 | 44 | 45 | 46 |
47 |
48 | foto-guru 49 |
50 |

Guru BK

51 |

Sman 3 Mataram

52 |
53 |
54 |
55 |
56 |

ABSENSI SISWA

57 |

Sman 3 Mataram

58 |
59 |
60 |

61 |
62 |
63 |
64 |
65 | 68 |
69 |
70 |
71 |
72 |
ABSEN SISWA
73 |
74 |
75 |
76 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /App/css/bootstrap-style.css: -------------------------------------------------------------------------------- 1 | .modal .modal-header { 2 | background: var(--blue-gradient); 3 | } 4 | .modal .modal-body { 5 | display: flex; 6 | flex-direction: column; 7 | } 8 | 9 | .modal .modal-body label { 10 | width: 30%; 11 | } 12 | .modal .modal-body div { 13 | font-size: 14px; 14 | } 15 | 16 | .modal .modal-body input { 17 | width: 70%; 18 | } 19 | .modal .modal-footer button#btn-tambah { 20 | background: var(--blue-gradient); 21 | } 22 | -------------------------------------------------------------------------------- /App/css/darkmode.css: -------------------------------------------------------------------------------- 1 | .onDarkMode { 2 | background-color: #0b1d27 !important; 3 | } 4 | 5 | .onDarkMode .container-fluid { 6 | background-color: #0b1d27 !important; 7 | box-shadow: 2px 1px 10px #0a5ebe; 8 | } 9 | 10 | .onDarkMode .left { 11 | background-color: #0b1d27 !important; 12 | } 13 | 14 | .onDarkMode .siswa-pada-kelas { 15 | background-color: #0b1d27 !important; 16 | color: white; 17 | } 18 | 19 | .onDarkMode button.siswa { 20 | background-color: #0b1d27; 21 | color: white; 22 | } 23 | 24 | .onDarkMode button.siswa.active { 25 | background-color: #162636ef !important; 26 | } 27 | 28 | .onDarkMode .right button input { 29 | color: white; 30 | } 31 | 32 | .onDarkMode button span.absen { 33 | background-color: #192c3b !important; 34 | } 35 | 36 | .onDarkMode .burger span { 37 | background-color: #0b1d27 !important; 38 | } 39 | 40 | .onDarkMode .blue-btn { 41 | box-shadow: 1px 1px 5px #0a5ebecb; 42 | } 43 | 44 | .onDarkMode .blue-btn:hover { 45 | transform: scale(0.98); 46 | } 47 | .onDarkMode button.kelas-siswa:active { 48 | transform: scale(0.99); 49 | border: 2px solid #0a5ebe; 50 | } 51 | .onDarkMode button.kelas-siswa.active { 52 | transform: scale(0.99); 53 | border: 2px solid #0a5ebe; 54 | } 55 | -------------------------------------------------------------------------------- /App/css/left.css: -------------------------------------------------------------------------------- 1 | .left { 2 | position: relative; 3 | width: 70%; 4 | background-color: white; 5 | transition: 0.2s ease-in; 6 | display: flex; 7 | flex-direction: column; 8 | } 9 | 10 | .left .top-section { 11 | display: grid !important; 12 | place-items: center; 13 | grid-template-columns: repeat(3, 1fr); 14 | grid-template-areas: "ket-guru judul-program tanggal"; 15 | width: 100%; 16 | background: var(--blue-gradient-reverse); 17 | } 18 | 19 | .left .main-section button i { 20 | font-size: 17px; 21 | font-weight: 600; 22 | color: white; 23 | } 24 | 25 | .left .ket-guru { 26 | grid-area: ket-guru; 27 | } 28 | .left .col:nth-child(2) { 29 | grid-area: judul-program; 30 | } 31 | .left .col:nth-child(3) { 32 | grid-area: tanggal; 33 | } 34 | 35 | .left img { 36 | width: 50px; 37 | height: 50px; 38 | border-radius: 50%; 39 | margin-right: 10px; 40 | filter: drop-shadow(1px 1px 5px #7070707c); 41 | } 42 | 43 | .left .ket-guru p { 44 | font-size: 13px; 45 | } 46 | 47 | .left .top-section p.date { 48 | font-size: 13px; 49 | } 50 | 51 | .left .top-section h1 { 52 | font-weight: 600; 53 | font-size: 24px; 54 | } 55 | -------------------------------------------------------------------------------- /App/css/login.css: -------------------------------------------------------------------------------- 1 | @import "./style.css"; 2 | 3 | a { 4 | text-decoration: none; 5 | } 6 | 7 | input:focus, 8 | button:focus { 9 | outline: none !important; 10 | border: none !important; 11 | } 12 | 13 | header h4::selection { 14 | background: none; 15 | } 16 | 17 | body, 18 | .container { 19 | display: flex; 20 | justify-content: center; 21 | height: 100vh !important; 22 | padding: 0 !important; 23 | margin: 0 !important; 24 | } 25 | 26 | body { 27 | position: relative; 28 | font-family: "Poppins", sans-serif; 29 | } 30 | 31 | .wave { 32 | position: absolute; 33 | left: 0; 34 | width: 100%; 35 | z-index: -99; 36 | } 37 | 38 | #waves-top { 39 | bottom: unset; 40 | top: 0; 41 | height: 20%; 42 | } 43 | 44 | #waves-bottom { 45 | top: unset; 46 | bottom: 0; 47 | height: 40%; 48 | transform: rotate(180deg); 49 | } 50 | 51 | .login-section { 52 | margin: auto; 53 | width: 350px; 54 | background-color: white; 55 | flex-direction: column; 56 | border-radius: 5px; 57 | overflow: hidden; 58 | box-shadow: 3px 5px 15px #83828259; 59 | } 60 | 61 | header { 62 | background: var(--blue-gradient); 63 | padding: 30px 40px; 64 | } 65 | header img { 66 | margin-right: 10px; 67 | width: 50px; 68 | height: 50px; 69 | border-radius: 50%; 70 | filter: drop-shadow(1px 1px 5px #7070707c); 71 | } 72 | 73 | header h6 { 74 | color: white; 75 | letter-spacing: 2px; 76 | font-weight: 700; 77 | text-shadow: 1px 2px 2px var(--default-black-color); 78 | } 79 | 80 | header p { 81 | letter-spacing: 2px; 82 | color: #e9e9e9; 83 | font-size: 12px; 84 | margin-top: -5px; 85 | font-weight: 500; 86 | } 87 | 88 | form { 89 | position: relative; 90 | padding: 20px 40px 80px 40px; 91 | } 92 | 93 | .login { 94 | height: 40px; 95 | margin: 20px 0; 96 | border-bottom: 1px solid #b4b4b4b4; 97 | transition: 0.3s ease-in-out; 98 | position: relative; 99 | } 100 | 101 | .login i { 102 | width: 10%; 103 | font-size: 16px; 104 | text-align: center; 105 | } 106 | 107 | .login span { 108 | position: absolute; 109 | display: inline-block; 110 | top: 10px; 111 | transform: translateX(5px); 112 | font-size: 13px; 113 | cursor: none; 114 | pointer-events: none; 115 | transition: 0.3s ease-out; 116 | } 117 | 118 | .login span.focus { 119 | top: -8px; 120 | font-size: 11px; 121 | } 122 | 123 | .login input { 124 | border: none; 125 | padding: 5px; 126 | height: 100%; 127 | width: 90%; 128 | font-size: 14px; 129 | } 130 | 131 | .login i, 132 | .login span, 133 | .button a { 134 | color: #646464; 135 | } 136 | 137 | .button { 138 | display: flex; 139 | align-items: center; 140 | justify-content: space-between; 141 | margin-top: 40px; 142 | } 143 | 144 | .button a { 145 | font-size: 12px; 146 | } 147 | 148 | .button button { 149 | position: relative; 150 | padding: 10px 25px; 151 | font-size: 13px; 152 | color: white; 153 | border: none; 154 | background: var(--blue-gradient); 155 | border-radius: 2px; 156 | cursor: pointer; 157 | transition: 0.2s ease-in; 158 | overflow: hidden; 159 | } 160 | .button button:hover { 161 | transform: scale(0.97); 162 | } 163 | 164 | .button i { 165 | position: absolute; 166 | right: 2%; 167 | transition: 0.3s right ease-in-out; 168 | transition-delay: 0.2s; 169 | color: #ffffff; 170 | cursor: none; 171 | pointer-events: none; 172 | opacity: 0; 173 | } 174 | 175 | p#alert { 176 | display: flex; 177 | position: absolute; 178 | top: -11%; 179 | left: 50%; 180 | padding: 15px 20px; 181 | width: 350px; 182 | transform: translateX(-50%); 183 | background-color: #eb3b5a; 184 | color: white; 185 | font-size: 13px; 186 | border-radius: 3px; 187 | opacity: 0; 188 | transition: 0.2s ease-in-out; 189 | } 190 | 191 | p#alert i { 192 | margin-right: 5px; 193 | padding-top: 3px; 194 | } 195 | 196 | @media (max-width: 480px) { 197 | .login-section { 198 | width: 310px; 199 | } 200 | header { 201 | padding: 20px 30px; 202 | } 203 | form { 204 | position: relative; 205 | padding: 20px 30px 80px 30px; 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /App/css/right.css: -------------------------------------------------------------------------------- 1 | .right { 2 | width: 30%; 3 | background: var(--blue-gradient); 4 | padding: 20px; 5 | transition: 0.2s ease-in; 6 | overflow: auto; 7 | } 8 | 9 | .right .siswa-pada-kelas { 10 | background-color: white; 11 | height: 45px; 12 | display: flex; 13 | justify-content: center; 14 | align-items: center; 15 | margin-bottom: 30px; 16 | font-weight: 600; 17 | border-radius: 7px; 18 | box-shadow: 1px 1px 5px #3b3b3b7c; 19 | text-transform: uppercase; 20 | transition: 0.2s ease-in-out; 21 | } 22 | .right .siswa-pada-kelas span { 23 | margin-left: 5px; 24 | } 25 | 26 | .right button span { 27 | position: absolute; 28 | display: grid; 29 | place-content: center; 30 | color: white; 31 | } 32 | .right button span.absen { 33 | top: 0; 34 | left: 0; 35 | width: 40px; 36 | height: 100%; 37 | background-color: #383838; 38 | font-weight: 500; 39 | border-radius: 7px; 40 | } 41 | 42 | .right button input { 43 | display: none; 44 | border: none; 45 | outline: none; 46 | font-weight: 500; 47 | color: var(--default-black-color); 48 | width: 100%; 49 | transform: translateX(-2px); 50 | letter-spacing: 1px; 51 | background-color: transparent; 52 | } 53 | 54 | .right button input.active { 55 | display: unset; 56 | } 57 | 58 | .right button span.method { 59 | width: 25px; 60 | height: 25px; 61 | border-radius: 50%; 62 | font-size: 13px; 63 | font-weight: 700; 64 | transform: translate(-50%, 150%); 65 | box-shadow: 1px 1px 5px #3b3b3b7c; 66 | transition: 0.2s ease-in-out; 67 | color: #222222; 68 | } 69 | 70 | .right button span.method.active { 71 | transform: translate(-50%, 0); 72 | } 73 | 74 | .right button span.fitur { 75 | width: 25px; 76 | height: 25px; 77 | border-radius: 50%; 78 | font-size: 13px; 79 | font-weight: 700; 80 | transform: translate(-50%, 150%); 81 | box-shadow: 1px 1px 5px #3b3b3b7c; 82 | transition: 0.2s ease-in-out; 83 | color: #222222; 84 | } 85 | 86 | .right button span.fitur.active { 87 | transform: translate(-50%, 0); 88 | } 89 | 90 | .right button span.siswa-hapus { 91 | background-color: #fa4f4f; 92 | left: 45%; 93 | } 94 | 95 | .right button span.siswa-rename { 96 | background-color: orange; 97 | left: 55%; 98 | } 99 | 100 | .right button span.method.sakit { 101 | background-color: #fce566; 102 | left: 50%; 103 | transition-delay: 0.1s; 104 | } 105 | .right button span.method.izin { 106 | background-color: #469e2f; 107 | left: 40%; 108 | transition-delay: 0.05s; 109 | } 110 | .right button span.method.bolos { 111 | background-color: #fa4f4f; 112 | left: 60%; 113 | transition-delay: 0.15s; 114 | } 115 | 116 | .right button.siswa { 117 | position: relative; 118 | width: 100%; 119 | height: 40px; 120 | border: none; 121 | margin-bottom: 6px; 122 | padding: 2px; 123 | font-weight: 500; 124 | background-color: white; 125 | color: var(--default-black-color); 126 | letter-spacing: 1px; 127 | border-radius: 7px; 128 | overflow: hidden; 129 | text-transform: uppercase; 130 | box-shadow: 1px 1px 5px #3b3b3b7c; 131 | text-align: left; 132 | padding-left: 50px; 133 | overflow: hidden; 134 | transition: 0.2s ease-in-out; 135 | } 136 | .right button.siswa.active { 137 | background-color: #464646c0 !important; 138 | } 139 | .right button.siswa.siswa-izin { 140 | background-color: #459e2fab; 141 | } 142 | .right button.siswa.siswa-sakit { 143 | background-color: #fce566b9; 144 | } 145 | .right button.siswa.siswa-bolos { 146 | background-color: #fa4f4fb9; 147 | } 148 | -------------------------------------------------------------------------------- /App/css/style.css: -------------------------------------------------------------------------------- 1 | @import "./left.css"; 2 | @import "./right.css"; 3 | @import "./darkmode.css"; 4 | @import "./sweetalert.css"; 5 | @import "./bootstrap-style.css"; 6 | 7 | html body { 8 | font-family: "Poppins", sans-serif; 9 | height: 100vh; 10 | user-select: none; 11 | } 12 | 13 | :root { 14 | --default-black-color: #222222; 15 | --default-blue-color: #0a5ebe; 16 | --blue-gradient: linear-gradient(to bottom right, #42abf1, #0a5ebe); 17 | --blue-gradient-reverse: linear-gradient(to right, #2097e6, #42abf1); 18 | } 19 | 20 | button:focus { 21 | outline: none; 22 | border: none; 23 | } 24 | input { 25 | border: 1px solid #858585; 26 | } 27 | input:focus { 28 | outline: none; 29 | border: 1px solid #363636; 30 | } 31 | 32 | .container-fluid { 33 | height: 100vh; 34 | display: flex; 35 | position: relative; 36 | box-shadow: 3px 3px 15px #cccccc; 37 | transition: 0.2s ease-in; 38 | } 39 | 40 | .side-bar { 41 | position: absolute; 42 | top: 0; 43 | left: 0; 44 | width: 300px; 45 | height: 100%; 46 | background: var(--blue-gradient); 47 | z-index: 99; 48 | padding: 30px; 49 | filter: drop-shadow(2px 1px 5px #3f3f3f7c); 50 | transition: 0.2s ease-in-out; 51 | transform: translateX(-110%); 52 | } 53 | 54 | .side-bar.active { 55 | transform: translateX(0); 56 | } 57 | 58 | .side-bar img { 59 | width: 50px; 60 | position: absolute; 61 | top: 15px; 62 | right: 15px; 63 | height: 50px; 64 | border-radius: 50%; 65 | margin-right: 10px; 66 | filter: drop-shadow(1px 1px 5px #7070707c); 67 | } 68 | 69 | .side-bar ul:last-child { 70 | position: absolute; 71 | bottom: 0; 72 | left: 50%; 73 | transform: translateX(-50%); 74 | display: flex; 75 | justify-content: space-around; 76 | width: 70%; 77 | } 78 | 79 | .side-bar ul li { 80 | list-style-type: none; 81 | font-size: 14px; 82 | font-weight: 500; 83 | margin-bottom: 5px; 84 | padding: 3px; 85 | cursor: pointer; 86 | } 87 | 88 | .side-bar ul li.darkmode { 89 | position: relative; 90 | margin-bottom: 20px; 91 | } 92 | 93 | .side-bar ul li.darkmode::before { 94 | content: "Switch To Darkmode"; 95 | position: absolute; 96 | top: 0; 97 | left: 3px; 98 | width: 100%; 99 | height: 100%; 100 | } 101 | 102 | .side-bar ul li.darkmode.active::before { 103 | content: "Switch To Lightmode"; 104 | } 105 | .side-bar ul li a { 106 | color: white; 107 | } 108 | 109 | .burger { 110 | display: flex; 111 | flex-direction: column; 112 | justify-content: space-between; 113 | width: 25px; 114 | height: 16px; 115 | cursor: pointer; 116 | } 117 | 118 | .burger span { 119 | width: 100%; 120 | height: 3px; 121 | background-color: white; 122 | border-radius: 10px; 123 | } 124 | 125 | .side-bar .burger span:first-child, 126 | .side-bar .burger span:last-child { 127 | transform-origin: left; 128 | } 129 | 130 | .side-bar .burger span:first-child { 131 | transform: rotate(45deg) translate(0px, -3px); 132 | } 133 | 134 | .side-bar .burger span:last-child { 135 | transform: rotate(-45deg) translate(0px, 3px); 136 | } 137 | 138 | .blue-btn { 139 | background: var(--blue-gradient); 140 | width: 120px; 141 | height: 120px; 142 | margin: 10px; 143 | border-radius: 10px; 144 | font-size: 14px; 145 | font-weight: 600; 146 | color: whitesmoke; 147 | border: none; 148 | text-transform: uppercase; 149 | border: none; 150 | box-shadow: 1px 1px 5px #3b3b3b7c; 151 | transition: 0.1s ease-in; 152 | } 153 | 154 | .blue-btn:hover { 155 | transform: scale(0.98); 156 | } 157 | button.kelas-siswa:active { 158 | transform: scale(0.99); 159 | border: 2px solid whitesmoke; 160 | } 161 | button.kelas-siswa.active { 162 | transform: scale(0.99); 163 | border: 2px solid whitesmoke; 164 | } 165 | 166 | /*? BREAKPOINT */ 167 | 168 | @media screen and (max-width: 1100px) { 169 | .left .top-section h1 { 170 | font-size: 18px; 171 | } 172 | .right { 173 | width: 40% !important; 174 | } 175 | } 176 | @media screen and (max-width: 897px) { 177 | .left .top-section { 178 | grid-template-columns: 1fr; 179 | grid-template-areas: 180 | "judul-program judul-program" 181 | "ket-guru tanggal"; 182 | } 183 | .left .col:nth-child(2) { 184 | grid-area: judul-program; 185 | margin-bottom: 10px; 186 | } 187 | 188 | .blue-btn { 189 | width: 100px; 190 | height: 100px; 191 | margin: 8px; 192 | } 193 | .right { 194 | width: 50% !important; 195 | } 196 | .right button span { 197 | font-size: 14px; 198 | } 199 | 200 | .right button.siswa { 201 | font-size: 14px; 202 | } 203 | } 204 | @media screen and (max-width: 810px) { 205 | .container-fluid { 206 | flex-direction: column; 207 | } 208 | .left, 209 | .right { 210 | width: 100% !important; 211 | } 212 | .right { 213 | height: 100%; 214 | } 215 | .right button span { 216 | font-size: 16px; 217 | } 218 | 219 | .right button.siswa { 220 | font-size: 16px; 221 | } 222 | } 223 | 224 | @media screen and (max-width: 576px) { 225 | .left .top-section { 226 | display: flex !important; 227 | align-items: center !important; 228 | } 229 | .judul { 230 | display: none; 231 | } 232 | .left { 233 | height: 100%; 234 | } 235 | .left .ket-guru p { 236 | font-size: 13px; 237 | display: none; 238 | visibility: hidden; 239 | } 240 | } 241 | 242 | @media screen and (max-width: 480px) { 243 | .blue-btn { 244 | width: 95px; 245 | height: 95px; 246 | margin: 7px; 247 | font-size: 13px; 248 | } 249 | } 250 | -------------------------------------------------------------------------------- /App/css/sweetalert.css: -------------------------------------------------------------------------------- 1 | .swal2-modal { 2 | width: 430px !important; 3 | height: 330px !important; 4 | } 5 | 6 | .swal2-title { 7 | font-size: 22px; 8 | } 9 | .swal2-content { 10 | font-size: 16px; 11 | } 12 | 13 | .swal2-icon { 14 | margin: 0 0 20px 0 !important; 15 | } 16 | 17 | .mark-line-left { 18 | height: 10px !important; 19 | } 20 | -------------------------------------------------------------------------------- /App/dist/index.dev.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require("jquery"); 4 | 5 | require("popper.js"); 6 | 7 | require("./css/bootstrap.min.css"); 8 | 9 | require("./css/style.css"); 10 | 11 | var _main = _interopRequireDefault(require("./js/main")); 12 | 13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 14 | 15 | global.jQuery = require("jquery"); 16 | 17 | require("bootstrap"); 18 | 19 | document.addEventListener("DOMContentLoaded", _main["default"]); -------------------------------------------------------------------------------- /App/img/bg-01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azrilardian/Absen-Siswa/5ac28163414c4cf3739562dda6cd9716c91a16e1/App/img/bg-01.jpg -------------------------------------------------------------------------------- /App/img/chandrika.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azrilardian/Absen-Siswa/5ac28163414c4cf3739562dda6cd9716c91a16e1/App/img/chandrika.jpg -------------------------------------------------------------------------------- /App/img/wavesOpacity 2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /App/img/wavesOpacity 3.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /App/img/wavesOpacity.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /App/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Sman 3 Mataram - Login 9 | 10 | 11 | 12 |
13 |
14 |
15 | user-avatar 16 |
17 |
SELAMAT DATANG,
18 |

Ibu / Bapak Guru

19 |
20 |
21 | 22 |
23 | 24 | 25 |
26 | Forgot Your Password ? 27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /App/index.js: -------------------------------------------------------------------------------- 1 | import "jquery"; 2 | global.jQuery = require("jquery"); 3 | require("bootstrap"); 4 | import "popper.js"; 5 | import "./css/bootstrap.min.css"; 6 | import "./css/style.css"; 7 | import main from "./js/main"; 8 | document.addEventListener("DOMContentLoaded", main); 9 | -------------------------------------------------------------------------------- /App/js/darkmode.js: -------------------------------------------------------------------------------- 1 | const darkMode = () => { 2 | const switchToDark = document.querySelector("ul li.darkmode"); 3 | let isDark = localStorage.getItem("isDark") ? localStorage.getItem("isDark") : "false"; 4 | 5 | switchToDark.addEventListener("click", function () { 6 | if (isDark == "true") { 7 | switchToDark.classList.remove("active"); 8 | localStorage.removeItem("mode"); 9 | document.body.classList.remove("onDarkMode"); 10 | isDark = "false"; 11 | } else { 12 | switchToDark.classList.add("active"); 13 | localStorage.setItem("mode", "darkmode"); 14 | document.body.classList.add("onDarkMode"); 15 | isDark = "true"; 16 | } 17 | localStorage.setItem("isDark", isDark); 18 | }); 19 | 20 | if (localStorage.getItem("mode") == "darkmode") { 21 | document.body.classList.add("onDarkMode"); 22 | switchToDark.classList.add("active"); 23 | } else { 24 | switchToDark.classList.remove("active"); 25 | } 26 | }; 27 | 28 | export default darkMode; 29 | -------------------------------------------------------------------------------- /App/js/login.js: -------------------------------------------------------------------------------- 1 | const swalSett = (title, text, icon, confirmButtonText) => { 2 | Swal.fire({ 3 | title: title, 4 | text: text, 5 | icon: icon, 6 | confirmButtonText: confirmButtonText, 7 | position: "top", 8 | }); 9 | }; 10 | 11 | // import swalSett from "./sweetAlertConfiguration"; 12 | 13 | //? Allneed 14 | let username = document.getElementById("username"); 15 | let password = document.getElementById("password"); 16 | let input = document.querySelectorAll("input"); 17 | // const alert = document.getElementById("alert"); 18 | const button = document.getElementById("submit"); 19 | const form = document.getElementById("login-form"); 20 | const dataLogin = []; 21 | 22 | input.forEach((e) => { 23 | e.addEventListener("focusin", function () { 24 | e.parentElement.style.borderBottomColor = "#165794"; 25 | e.previousElementSibling.classList.add("focus"); 26 | }); 27 | e.addEventListener("focusout", function () { 28 | if (e.value != "") return; 29 | e.previousElementSibling.classList.remove("focus"); 30 | e.parentElement.style.borderBottomColor = "#b4b4b4b4"; 31 | }); 32 | }); 33 | 34 | //? Data User 35 | const User = function (nama, password) { 36 | this.nama = nama; 37 | this.password = password; 38 | }; 39 | 40 | User.prototype.push = function () { 41 | return dataLogin.push(this); 42 | }; 43 | let sandhikaGlih = new User("Sandhika Galih", "wpunpas2020").push(); 44 | let azrilArdian = new User("Azril ardian", "12345678").push(); 45 | 46 | const cekUsername = (nama) => { 47 | const allUserName = dataLogin.find((e) => e.nama == nama); 48 | return allUserName; 49 | }; 50 | 51 | const cekPassword = (password) => { 52 | const allPassword = dataLogin.find((e) => e.password == password); 53 | return allPassword; 54 | }; 55 | 56 | //? Form Validation 57 | button.addEventListener("click", function () { 58 | if (username.value == "" || password.value == "") { 59 | if (username.value != "") { 60 | swalSett("ERROR", "Tidak dapat login. Password Kosong.", "error", "OK"); 61 | } else if (password.value != "") { 62 | swalSett("ERROR", "Tidak dapat login. Username Kosong.", "error", "OK"); 63 | } else { 64 | swalSett("ERROR", "Tidak dapat login. Username dan Password Kosong.", "error", "OK"); 65 | } 66 | } else if (username.value != "" || password.value != "") { 67 | if (cekUsername(username.value) == undefined && cekPassword(password.value) == undefined) { 68 | swalSett("ERROR", "Tidak dapat login. Guru tidak terdaftar.", "error", "OK"); 69 | } else if (cekUsername(username.value) == undefined) { 70 | swalSett("ERROR", "Tidak dapat login. Anda bukan guru Sman 3 Mataram.", "error", "OK"); 71 | } else if (cekPassword(password.value) == undefined) { 72 | swalSett("ERROR", "Tidak dapat login. Password tidak terdaftar.", "error", "OK"); 73 | } else { 74 | swalSett("SUCCESS", "Berhasil Login", "success", "OK"); 75 | form.setAttribute("onsubmit", "return true"); 76 | } 77 | } 78 | }); 79 | -------------------------------------------------------------------------------- /App/js/main.js: -------------------------------------------------------------------------------- 1 | import darkMode from "./darkmode"; 2 | import swalSett from "./sweetAlertConfiguration"; 3 | import { STORAGE_KELAS, STORAGE_SISWA, syncWithLocalStorageKelas, syncWithLocalStorageSiswa } from "./saveDataSiswa"; 4 | 5 | const main = () => { 6 | // Inisialisasi Variabel 7 | const container = document.querySelector(".container-fluid"); 8 | const kelasContainer = document.querySelector(".nama-kelas"); 9 | const siswaContainer = document.querySelector(".right .isi-siswa"); 10 | const spanNamaKelas = document.getElementById("nama-kelas-siswa"); 11 | const nama = document.getElementById("nama"); 12 | const kelas = document.getElementById("kelas"); 13 | const jurusan = document.getElementById("jurusan"); 14 | const btnTambah = document.querySelector("#btn-tambah"); 15 | let semuaSiswa = []; 16 | let semuaKelas = []; 17 | 18 | // Darkmode 19 | darkMode(); 20 | 21 | // Event pada saat tombol tambah di klik 22 | btnTambah.addEventListener("click", () => { 23 | cekNamaSiswa(tambahDataSiswa); 24 | spanNamaKelas.textContent = kelas.value; 25 | tampilkanSiswaPadaKelas(); 26 | darkMode(); 27 | 28 | nama.value = ""; 29 | kelas.value = ""; 30 | jurusan.value = ""; 31 | }); 32 | 33 | /* 34 | ====================================================================================================== 35 | ============= STATEMENT - STATEMENT YANG BERHUBUNGAN KETIKA NAMA KELAS DI KLIK ===================== 36 | ====================================================================================================== 37 | */ 38 | 39 | const siswaPadaKelas = (namaKelas) => semuaSiswa.filter((e) => e.kelas == namaKelas); 40 | 41 | const buatButtonSemuaSiswa = (semuaSiswa) => { 42 | // Render Html Siswa 43 | const btnSiswa = (e, i) => { 44 | return ``; 53 | }; 54 | 55 | semuaSiswa.map((e, i) => { 56 | const button = btnSiswa(e, i); 57 | siswaContainer.insertAdjacentHTML("beforeend", button); 58 | }); 59 | }; 60 | 61 | const tampilkanSiswaPadaKelas = () => { 62 | // Ambil nama kelas siswa 63 | let namaKelas; 64 | spanNamaKelas.textContent.length > 1 ? (namaKelas = spanNamaKelas.textContent) : (namaKelas = kelas.value); 65 | 66 | // Filter siswa pada kelas apa yang akan ditampilkan 67 | const isiSiswa = siswaPadaKelas(namaKelas); 68 | 69 | // Urutkan object siswa 70 | const urutkanSiswaBerdasarkanAbsen = isiSiswa.sort((a, b) => { 71 | const x = a.nama; 72 | const y = b.nama; 73 | return x < y ? -1 : x > y ? 1 : 0; 74 | }); 75 | 76 | // Parsing object siswa sekaligus buat buttonnya 77 | siswaContainer.innerHTML = ""; // Hapus semua data sebelum data ditambah 78 | buatButtonSemuaSiswa(urutkanSiswaBerdasarkanAbsen); 79 | }; 80 | 81 | const kelasSiswaAktif = (target) => { 82 | const kelasSiswa = document.querySelectorAll(".kelas-siswa"); 83 | kelasSiswa.forEach((e) => e.classList.remove("active")); 84 | target.classList.add("active"); 85 | }; 86 | 87 | // Event pada saat tiap - tiap kelas di klik 88 | const namaKelasClick = () => { 89 | kelasContainer.addEventListener("click", (e) => { 90 | const target = e.target; 91 | if (target.classList.contains("kelas-siswa")) { 92 | kelasSiswaAktif(target); // Style ketika kelas di click 93 | spanNamaKelas.textContent = target.textContent; // Nama kelas siswa 94 | tampilkanSiswaPadaKelas(); // tampilkan siswa 95 | } 96 | }); 97 | }; 98 | namaKelasClick(); 99 | 100 | /* 101 | ====================================================================================================== 102 | ============= AKHIR ===================== 103 | ====================================================================================================== 104 | */ 105 | 106 | /* 107 | ====================================================================================================== 108 | ============= STATEMENT - STATEMENT YANG BERHUBUNGAN KETIKA SISWA DITAMBAH ===================== 109 | ====================================================================================================== 110 | */ 111 | 112 | // Ambil Data Siswa 113 | function Siswa(nama, kelas, jurusan, kehadiran = "hadir") { 114 | this.nama = nama; 115 | this.kelas = kelas; 116 | this.jurusan = jurusan; 117 | this.kehadiran = kehadiran; 118 | } 119 | 120 | // Ambil Data Kelas 121 | function Kelas(kelas) { 122 | this.kelas = kelas; 123 | } 124 | 125 | const buatButtonSemuaKelas = (semuaKelas) => { 126 | semuaKelas.map((e) => { 127 | const BuatBtnKelas = ``; 128 | kelasContainer.insertAdjacentHTML("beforeend", BuatBtnKelas); 129 | }); 130 | }; 131 | 132 | const tambahKelas = () => { 133 | // Hapus semua kelas 134 | const kelasSiswa = document.querySelectorAll(".kelas-siswa"); 135 | kelasSiswa.forEach((e) => e.remove()); 136 | 137 | // Urutkan object semua kelas 138 | const urutkanKelasBerdasarkanNama = semuaKelas.map((e) => e.kelas).sort(); 139 | 140 | // Parsing kelas sekaligus buat buttonya 141 | buatButtonSemuaKelas(urutkanKelasBerdasarkanNama); 142 | }; 143 | 144 | const tambahDataSiswa = (nama, kelas, jurusan, kehadiran) => { 145 | // Cek apakah kelas sudah terdaftar atau tidak 146 | const cekDuplikasiNamaKelas = semuaKelas.find((e) => e.kelas == kelas); 147 | 148 | // Ketika ada, jangan buat button kelas lagi 149 | if (cekDuplikasiNamaKelas) { 150 | semuaSiswa.push(new Siswa(nama, kelas, jurusan)); 151 | syncWithLocalStorageSiswa("ADD", nama, kelas, jurusan, kehadiran); 152 | closeBootstrapModal(); 153 | showAlert(".alert-success", nama, kelas); 154 | return; 155 | } 156 | 157 | // Ketika belum ada, buat button kelas 158 | semuaSiswa.push(new Siswa(nama, kelas, jurusan)); 159 | semuaKelas.push(new Kelas(kelas)); 160 | tambahKelas(); 161 | syncWithLocalStorageSiswa("ADD", nama, kelas, jurusan); 162 | syncWithLocalStorageKelas("ADD", kelas); 163 | closeBootstrapModal(); 164 | }; 165 | 166 | const cekNamaSiswa = (tambahData) => { 167 | // Cek apakah siswa sudah terdaftar atau tidak 168 | const cekDuplikasiNamaSiswa = semuaSiswa.find((e) => e.nama == nama.value.toUpperCase()); 169 | 170 | // Cek apakah semua data diisi atau tidak 171 | if (nama.value == "" || kelas.value == "" || jurusan.value == "") { 172 | closeBootstrapModal(); 173 | showAlert(".alert-warning"); 174 | // Ketika siswa sudah terdaftar 175 | } else if (cekDuplikasiNamaSiswa) { 176 | closeBootstrapModal(); 177 | showAlert(".alert-warning", nama.value); 178 | // Ketika siswa belum terdaftar 179 | } else { 180 | tambahData(nama.value.toUpperCase(), kelas.value, jurusan.value); // Callback 181 | } 182 | }; 183 | 184 | /* 185 | ====================================================================================================== 186 | ============= AKHIR ===================== 187 | ====================================================================================================== 188 | */ 189 | 190 | /* 191 | ====================================================================================================== 192 | ============= STATEMENT - STATEMENT YANG BERHUBUNGAN DENGAN METODE PADA SISWA ===================== 193 | ====================================================================================================== 194 | */ 195 | 196 | const metodePadaSiswa = () => { 197 | const nonActiveSiswaMethodDanFitur = () => { 198 | const allSpanMethod = document.querySelectorAll("span.method"); 199 | const allSpanFitur = document.querySelectorAll("span.fitur"); 200 | const allSiswa = document.querySelectorAll("button.siswa"); 201 | const fiturAndMethod = [allSpanMethod, allSpanFitur, allSiswa]; 202 | fiturAndMethod.map((object) => object.forEach((e) => e.classList.remove("active"))); 203 | }; 204 | 205 | const statusSiswa = (target, statusSiswa) => { 206 | const siswa = target.parentElement; 207 | const status = siswa.classList.toggle(statusSiswa); 208 | const kehadiran = status ? statusSiswa : "hadir"; 209 | kehadiranSiswa(target, kehadiran); 210 | nonActiveSiswaMethodDanFitur(); 211 | }; 212 | 213 | const kehadiranSiswa = (target, kehadiranSiswa) => { 214 | const namaSiswa = target.parentElement.lastChild.textContent.trim(); 215 | const ketSiswaDipilih = semuaSiswa.find((siswa) => siswa.nama == namaSiswa); 216 | const { nama, kelas, jurusan } = ketSiswaDipilih; // Destructuring siswa apa yang di pilih 217 | 218 | // Cari siswa dalam object semuaSiswa lalu ubah kehadirannya 219 | semuaSiswa.find((siswa) => { 220 | if (siswa.nama == namaSiswa) siswa.kehadiran = kehadiranSiswa; 221 | }); 222 | 223 | // Update Kehadiran siswa pada local storage 224 | syncWithLocalStorageSiswa("UPDATE", nama, kelas, jurusan, kehadiranSiswa); 225 | }; 226 | 227 | container.addEventListener("click", (e) => { 228 | let btnSiswa; 229 | if (e.target.classList.contains("siswa")) { 230 | const siswa = e.target; 231 | // munculkan semua metode pada siswa 232 | const spanMethod = [siswa.children[1], siswa.children[2], siswa.children[3]]; 233 | const fiturSiswa = [siswa.children[4], siswa.children[5]]; 234 | 235 | // Hapus fitur siswa ketika metode pada siswa aktif 236 | fiturSiswa.map((e) => e.classList.remove("active")); 237 | spanMethod.map((e) => e.classList.toggle("active")); 238 | 239 | // Tetap tambah class active pada siswa ketika metode pada siswa aktif 240 | spanMethod[0].classList.contains("active") ? siswa.classList.add("active") : siswa.classList.remove("active"); 241 | } else if (e.target.classList.contains("izin")) { 242 | btnSiswa = e.target.parentElement; 243 | btnSiswa.classList.remove("siswa-sakit", "siswa-bolos", "hadir"); // agar siswa tidak mempunyai status ganda 244 | statusSiswa(e.target, "siswa-izin"); 245 | } else if (e.target.classList.contains("sakit")) { 246 | btnSiswa = e.target.parentElement; 247 | btnSiswa.classList.remove("siswa-izin", "siswa-bolos", "hadir"); 248 | statusSiswa(e.target, "siswa-sakit"); 249 | } else if (e.target.classList.contains("bolos")) { 250 | btnSiswa = e.target.parentElement; 251 | btnSiswa.classList.remove("siswa-izin", "siswa-sakit", "hadir"); 252 | statusSiswa(e.target, "siswa-bolos"); 253 | } else { 254 | nonActiveSiswaMethodDanFitur(); 255 | } 256 | }); 257 | }; 258 | metodePadaSiswa(); 259 | 260 | /* 261 | ====================================================================================================== 262 | ============= AKHIR ===================== 263 | ====================================================================================================== 264 | */ 265 | 266 | /* 267 | ====================================================================================================== 268 | ============= STATEMENT - STATEMENT YANG BERHUBUNGAN DENGAN FITUR PADA SISWA ===================== 269 | ====================================================================================================== 270 | */ 271 | 272 | const fiturPadaSiswa = () => { 273 | const hapusSiswa = (namaSiswa) => { 274 | let siswaUpdate = []; 275 | // Buang siswa yang dihapus pada object semuaSiswa 276 | semuaSiswa.filter((siswa) => (siswa.nama != namaSiswa ? siswaUpdate.push(siswa) : (siswaUpdate = siswaUpdate))); 277 | semuaSiswa = siswaUpdate; // Reassgin ulang semuaSiswa 278 | syncWithLocalStorageSiswa("DELETE", namaSiswa); 279 | }; 280 | 281 | const hapusKelasSiswa = (namaKelas) => { 282 | const cekKelas = semuaSiswa.filter((siswa) => siswa.kelas == namaKelas); 283 | let kelasUpdate = []; 284 | if (cekKelas.length == 0) { 285 | // Buang kelas yang dihapus pada object semuaKelas 286 | semuaKelas.filter((kelasSiswa) => (kelasSiswa.kelas != namaKelas ? kelasUpdate.push(kelasSiswa) : (kelasUpdate = kelasUpdate))); 287 | semuaKelas = kelasUpdate; // Reassing ulang semuaKelas 288 | syncWithLocalStorageKelas("DELETE", namaKelas); 289 | } 290 | if (semuaKelas.length == 0) spanNamaKelas.textContent = ""; 291 | }; 292 | 293 | const renameSiswa = (namaSiswaSebelum, namaSiswaSesudah, target) => { 294 | semuaSiswa.find((siswa) => { 295 | // Cari siswa yang ingin diubah namanya 296 | if (siswa.nama == namaSiswaSebelum) { 297 | // Lalu ubah nama siswa 298 | siswa.nama = namaSiswaSesudah; 299 | target.parentElement.lastChild.textContent = namaSiswaSesudah; 300 | const { kelas, jurusan, kehadiran } = siswa; 301 | 302 | // Hapus dulu data siswa yang lama pada local storage, setelah itu tambah siswa yang telah direname 303 | syncWithLocalStorageSiswa("DELETE", namaSiswaSebelum); 304 | syncWithLocalStorageSiswa("UPDATE", namaSiswaSesudah, kelas, jurusan, kehadiran); 305 | } 306 | }); 307 | }; 308 | 309 | container.addEventListener("dblclick", (e) => { 310 | if (e.target.classList.contains("siswa")) { 311 | const siswa = e.target; 312 | const spanMethod = [siswa.children[1], siswa.children[2], siswa.children[3]]; 313 | const fiturSiswa = [siswa.children[4], siswa.children[5]]; 314 | 315 | // Hapus metode siswa ketika fitur pada siswa aktif 316 | spanMethod.map((e) => e.classList.remove("active")); 317 | fiturSiswa.map((e) => e.classList.toggle("active")); 318 | 319 | // Tetap tambah class active pada siswa ketika fitur pada siswa aktif 320 | fiturSiswa[0].classList.contains("active") ? siswa.classList.add("active") : siswa.classList.remove("active"); 321 | } 322 | }); 323 | 324 | container.addEventListener("click", (e) => { 325 | if (e.target.classList.contains("siswa-hapus")) { 326 | const kelasSiswa = document.getElementById("nama-kelas-siswa").textContent.trim(); 327 | const namaSiswa = e.target.parentElement.lastChild.textContent.trim(); 328 | hapusSiswa(namaSiswa); 329 | hapusKelasSiswa(kelasSiswa); 330 | tambahKelas(); // Update daftar kelas 331 | tampilkanSiswaPadaKelas(); // Update daftar siswa 332 | } else if (e.target.classList.contains("siswa-rename")) { 333 | const target = e.target; 334 | let namaSiswa = target.parentElement.lastChild.textContent.trim(); 335 | const inputNamaSiswa = target.nextElementSibling; // element input 336 | inputNamaSiswa.classList.add("active"); 337 | inputNamaSiswa.focus(); 338 | inputNamaSiswa.value = namaSiswa; 339 | target.parentElement.lastChild.textContent = ""; // Hapus nama siswa pada btnSiswa 340 | 341 | inputNamaSiswa.addEventListener("keyup", (e) => { 342 | if (e.keyCode === 13) { 343 | renameSiswa(namaSiswa, inputNamaSiswa.value, target); 344 | inputNamaSiswa.classList.remove("active"); 345 | } 346 | }); 347 | } 348 | }); 349 | }; 350 | 351 | fiturPadaSiswa(); 352 | 353 | /* 354 | ====================================================================================================== 355 | ============= AKHIR ===================== 356 | ====================================================================================================== 357 | */ 358 | 359 | // Otomatis memperbesar huruf pada semua inputan 360 | const input = document.querySelectorAll("input"); 361 | input.forEach(function (e) { 362 | e.addEventListener("input", function () { 363 | e.style.textTransform = "uppercase"; 364 | }); 365 | }); 366 | 367 | const closeBootstrapModal = () => { 368 | const modal = document.querySelector(".modal"); 369 | const modalOverlay = document.querySelector(".modal-backdrop"); 370 | document.body.removeAttribute("class"); 371 | modal.classList.toggle("show"); 372 | modal.style.display = "none"; 373 | modal.setAttribute("aria-hidden", "true"); 374 | modal.removeAttribute("aria-modal"); 375 | modal.removeAttribute("role"); 376 | modalOverlay.remove(); 377 | }; 378 | 379 | const showAlert = (selector, namaSiswa, namaKelas) => { 380 | if (selector === ".alert-warning") { 381 | // Cek apakah parameter namaSiswa diisi 382 | if (namaSiswa != undefined) { 383 | swalSett("INFO", `${namaSiswa.toUpperCase()} Sudah Terdaftar`, "info", "OK"); 384 | } else { 385 | swalSett("WARNING", "Semua Data Harus Diisi", "warning", "OK"); 386 | } 387 | } else if (selector === ".alert-success") { 388 | // Cek apakah parameter namaSiswa dan namaKelas diisi 389 | if (namaSiswa != undefined && namaKelas != undefined) { 390 | swalSett("SUCCES", `${namaSiswa.toUpperCase()} Berhasil Ditambah Pada Kelas ${namaKelas}`, "success", "OK"); 391 | } 392 | } 393 | }; 394 | 395 | const tanggal = () => { 396 | const p = document.querySelector("p.date"); 397 | const date = new Date(); 398 | p.textContent = date.toDateString(); 399 | }; 400 | tanggal(); 401 | 402 | /* 403 | ====================================================================================================== 404 | ============= STATEMENT - STATEMENT YANG BERHUBUNGAN DENGAN LOCAL STORAGAE ===================== 405 | ====================================================================================================== 406 | */ 407 | 408 | const dataKelasLocal = localStorage.getItem(STORAGE_KELAS); 409 | const dataSiswaLocal = localStorage.getItem(STORAGE_SISWA); 410 | 411 | if (dataKelasLocal) { 412 | const semuaKelasLocal = JSON.parse(dataKelasLocal); 413 | const semuaKelasLocalArray = []; 414 | let sortKelas = []; 415 | for (let isiKelas in semuaKelasLocal) { 416 | semuaKelasLocalArray.push(isiKelas); 417 | sortKelas = semuaKelasLocalArray.sort(); 418 | } 419 | sortKelas.map((kelas) => { 420 | const BuatBtnKelas = ``; 421 | kelasContainer.insertAdjacentHTML("beforeend", BuatBtnKelas); 422 | semuaKelas.push(new Kelas(kelas)); 423 | syncWithLocalStorageKelas("ADD", kelas); 424 | }); 425 | } 426 | 427 | if (dataSiswaLocal) { 428 | const semuaSiswaLocal = JSON.parse(dataSiswaLocal); 429 | for (let isiSiswa in semuaSiswaLocal) { 430 | // Destructuring value 431 | const [nama, kelas, jurusan, kehadiran] = semuaSiswaLocal[isiSiswa]; 432 | // Eksekusi fungsi tampikanSiswaPadaKelas(); 433 | semuaSiswa.push(new Siswa(nama, kelas, jurusan, kehadiran)); 434 | syncWithLocalStorageSiswa("ADD", nama, kelas, jurusan, kehadiran); 435 | } 436 | // Auto hapus data kehadiran siswa setiap hari 437 | const jam = new Date().getHours(); 438 | if (jam == 24) semuaSiswa.map((siswa) => (siswa.kehadiran = "hadir")); 439 | } 440 | 441 | /* 442 | ====================================================================================================== 443 | ============= AKHIR ===================== 444 | ====================================================================================================== 445 | */ 446 | }; 447 | 448 | export default main; 449 | -------------------------------------------------------------------------------- /App/js/saveDataSiswa.js: -------------------------------------------------------------------------------- 1 | const STORAGE_KELAS = "STORAGE KELAS"; 2 | const STORAGE_SISWA = "STORAGE SISWA"; 3 | let semuaKelas = {}; 4 | let semuaSiswa = {}; 5 | 6 | const syncWithLocalStorageKelas = (status, kelas) => { 7 | switch (status) { 8 | case "ADD": 9 | semuaKelas[kelas] = [kelas]; 10 | break; 11 | case "DELETE": 12 | delete semuaKelas[kelas]; 13 | break; 14 | default: 15 | break; 16 | } 17 | localStorage.setItem(STORAGE_KELAS, JSON.stringify(semuaKelas)); 18 | return; 19 | }; 20 | 21 | const syncWithLocalStorageSiswa = (status, nama, kelas, jurusan, kehadiran = "hadir") => { 22 | switch (status) { 23 | case "ADD": 24 | case "UPDATE": 25 | semuaSiswa[nama] = [nama, kelas, jurusan, kehadiran]; 26 | break; 27 | case "DELETE": 28 | delete semuaSiswa[nama]; 29 | break; 30 | default: 31 | break; 32 | } 33 | localStorage.setItem(STORAGE_SISWA, JSON.stringify(semuaSiswa)); 34 | return; 35 | }; 36 | 37 | export { STORAGE_KELAS, STORAGE_SISWA, syncWithLocalStorageKelas, syncWithLocalStorageSiswa }; 38 | -------------------------------------------------------------------------------- /App/js/sidebar.js: -------------------------------------------------------------------------------- 1 | const sideBarActivation = () => { 2 | const sideBar = document.querySelector(".side-bar"); 3 | document.addEventListener("click", (e) => { 4 | if (e.target.classList.contains("burger-open")) sideBar.classList.add("active"); 5 | else if (e.target.classList.contains("burger-close")) sideBar.classList.remove("active"); 6 | else if (e.target.classList.contains("side-bar")) return; 7 | else { 8 | sideBar.classList.remove("active"); 9 | } 10 | }); 11 | }; 12 | sideBarActivation(); 13 | -------------------------------------------------------------------------------- /App/js/sweetAlertConfiguration.js: -------------------------------------------------------------------------------- 1 | const swalSett = (title, text, icon, confirmButtonText) => { 2 | Swal.fire({ 3 | title: title, 4 | text: text, 5 | icon: icon, 6 | confirmButtonText: confirmButtonText, 7 | position: "top", 8 | }); 9 | }; 10 | 11 | export default swalSett; 12 | -------------------------------------------------------------------------------- /App/js/sweetalert2.all.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sweetalert2=e()}(this,function(){"use strict";function r(t){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){for(var n=0;nt.clientHeight)}function ut(t){var e=window.getComputedStyle(t),t=parseFloat(e.getPropertyValue("animation-duration")||"0"),e=parseFloat(e.getPropertyValue("transition-duration")||"0");return 0\n
\n
    \n
    \n
    \n
    \n
    \n
    \n \n

    \n \n
    \n
    \n
    \n \n \n
    \n \n \n
    \n \n
    \n \n \n
    \n
    \n
    \n
    \n \n \n \n
    \n
    \n
    \n
    \n
    \n \n').replace(/(^|\n)\s*/g,""),Ct=function(t){var e,n,o,i,r,a=!!(i=C())&&(i.parentNode.removeChild(i),vt([document.documentElement,document.body],[$["no-backdrop"],$["toast-shown"],$["has-column"]]),!0);dt()?W("SweetAlert2 requires document to initialize"):((r=document.createElement("div")).className=$.container,a&>(r,$["no-transition"]),U(r,wt),(i="string"==typeof(e=t.target)?document.querySelector(e):e).appendChild(r),a=t,(e=x()).setAttribute("role",a.toast?"alert":"dialog"),e.setAttribute("aria-live",a.toast?"polite":"assertive"),a.toast||e.setAttribute("aria-modal","true"),r=i,"rtl"===window.getComputedStyle(r).direction&>(C(),$.rtl),t=P(),a=yt(t,$.input),e=yt(t,$.file),n=t.querySelector(".".concat($.range," input")),o=t.querySelector(".".concat($.range," output")),i=yt(t,$.select),r=t.querySelector(".".concat($.checkbox," input")),t=yt(t,$.textarea),a.oninput=pt,e.onchange=pt,i.onchange=pt,r.onchange=pt,t.oninput=pt,n.oninput=function(t){pt(t),o.value=n.value},n.onchange=function(t){pt(t),n.nextSibling.value=n.value})},kt=function(t,e){t.jquery?xt(e,t):U(e,t.toString())},xt=function(t,e){if(t.textContent="",0 in e)for(var n=0;n in e;n++)t.appendChild(e[n].cloneNode(!0));else t.appendChild(e.cloneNode(!0))},Bt=function(){if(dt())return!1;var t,e=document.createElement("div"),n={WebkitAnimation:"webkitAnimationEnd",OAnimation:"oAnimationEnd oanimationend",animation:"animationend"};for(t in n)if(Object.prototype.hasOwnProperty.call(n,t)&&void 0!==e.style[t])return n[t];return!1}();function At(t,e,n){var o;st(t,n["show".concat((o=e).charAt(0).toUpperCase()+o.slice(1),"Button")],"inline-block"),U(t,n["".concat(e,"ButtonText")]),t.setAttribute("aria-label",n["".concat(e,"ButtonAriaLabel")]),t.className=$[e],F(t,n,"".concat(e,"Button")),gt(t,n["".concat(e,"ButtonClass")])}function Pt(t,e){var n,o,i=C();i&&(o=i,"string"==typeof(n=e.backdrop)?o.style.background=n:n||gt([document.documentElement,document.body],$["no-backdrop"]),!e.backdrop&&e.allowOutsideClick&&z('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`'),o=i,(n=e.position)in $?gt(o,$[n]):(z('The "position" parameter is not valid, defaulting to "center"'),gt(o,$.center)),n=i,!(o=e.grow)||"string"!=typeof o||(o="grow-".concat(o))in $&>(n,$[o]),F(i,e,"container"),(e=document.body.getAttribute("data-swal2-queue-step"))&&(i.setAttribute("data-queue-step",e),document.body.removeAttribute("data-swal2-queue-step")))}function Et(t,e){t.placeholder&&!e.inputPlaceholder||(t.placeholder=e.inputPlaceholder)}function Ot(t,e,n){var o,i;n.inputLabel&&(t.id=$.input,o=document.createElement("label"),i=$["input-label"],o.setAttribute("for",t.id),o.className=i,o.innerText=n.inputLabel,e.insertAdjacentElement("beforebegin",o))}var St={promise:new WeakMap,innerParams:new WeakMap,domCache:new WeakMap},Tt=["input","file","range","select","radio","checkbox","textarea"],Lt=function(t){if(!jt[t.input])return W('Unexpected type of input! Expected "text", "email", "password", "number", "tel", "select", "radio", "checkbox", "textarea", "file" or "url", got "'.concat(t.input,'"'));var e=qt(t.input),n=jt[t.input](e,t);it(n),setTimeout(function(){et(n)})},Dt=function(t,e){var n=tt(P(),t);if(n)for(var o in!function(t){for(var e=0;e=o.progressSteps.length&&z("Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),o.progressSteps.forEach(function(t,e){var n,t=(n=t,t=document.createElement("li"),gt(t,$["progress-step"]),U(t,n),t);i.appendChild(t),e===r&>(t,$["active-progress-step"]),e!==o.progressSteps.length-1&&(t=o,e=document.createElement("li"),gt(e,$["progress-step-line"]),t.progressStepsDistance&&(e.style.width=t.progressStepsDistance),e=e,i.appendChild(e))})}function Rt(t,e){var n=j();F(n,e,"header"),Ht(0,e),function(t,e){t=St.innerParams.get(t);t&&e.icon===t.icon&&B()?Ft(B(),e):(_t(),e.icon&&(-1!==Object.keys(J).indexOf(e.icon)?(t=k(".".concat($.icon,".").concat(J[e.icon])),it(t),Wt(t,e),Ft(t,e),gt(t,e.showClass.icon)):W('Unknown icon! Expected "success", "error", "warning", "info" or "question", got "'.concat(e.icon,'"'))))}(t,e),function(t){var e=E();if(!t.imageUrl)return rt(e);it(e,""),e.setAttribute("src",t.imageUrl),e.setAttribute("alt",t.imageAlt),ot(e,"width",t.imageWidth),ot(e,"height",t.imageHeight),e.className=$.image,F(e,t,"image")}(e),n=e,t=A(),st(t,n.title||n.titleText),n.title&&ft(n.title,t),n.titleText&&(t.innerText=n.titleText),F(t,n,"title"),n=e,e=H(),U(e,n.closeButtonHtml),F(e,n,"closeButton"),st(e,n.showCloseButton),e.setAttribute("aria-label",n.closeButtonAriaLabel)}function Nt(t,e){var n,o;o=e,n=x(),ot(n,"width",o.width),ot(n,"padding",o.padding),o.background&&(n.style.background=o.background),Qt(n,o),Pt(0,e),Rt(t,e),Mt(t,e),mt(0,e),o=e,t=M(),st(t,o.footer),o.footer&&ft(o.footer,t),F(t,o,"footer"),"function"==typeof e.didRender?e.didRender(x()):"function"==typeof e.onRender&&e.onRender(x())}function Ut(){return T()&&T().click()}var _t=function(){for(var t=n(),e=0;e\n \n
    \n
    \n '):"error"===e.icon?U(t,'\n \n \n \n \n '):U(t,Yt({question:"?",warning:"!",info:"i"}[e.icon]))},Kt=function(t,e){if(e.iconColor){t.style.color=e.iconColor,t.style.borderColor=e.iconColor;for(var n=0,o=[".swal2-success-line-tip",".swal2-success-line-long",".swal2-x-mark-line-left",".swal2-x-mark-line-right"];n').concat(t,"")},Zt=[],Qt=function(t,e){t.className="".concat($.popup," ").concat(bt(t)?e.showClass.popup:""),e.toast?(gt([document.documentElement,document.body],$["toast-shown"]),gt(t,$.toast)):gt(t,$.modal),F(t,e,"popup"),"string"==typeof e.customClass&>(t,e.customClass),e.icon&>(t,$["icon-".concat(e.icon)])};function $t(t){var e=x();e||kn.fire(),e=x();var n=q(),o=D();!t&&bt(T())&&(t=T()),it(n),t&&(rt(t),o.setAttribute("data-button-to-replace",t.className)),o.parentNode.insertBefore(o,t),gt([e,n],$.loading),it(o),e.setAttribute("data-loading",!0),e.setAttribute("aria-busy",!0),e.focus()}function Jt(){return new Promise(function(t){var e=window.scrollX,n=window.scrollY;oe.restoreFocusTimeout=setTimeout(function(){oe.previousActiveElement&&oe.previousActiveElement.focus?(oe.previousActiveElement.focus(),oe.previousActiveElement=null):document.body&&document.body.focus(),t()},100),void 0!==e&&void 0!==n&&window.scrollTo(e,n)})}function Xt(){if(oe.timeout)return function(){var t=V(),e=parseInt(window.getComputedStyle(t).width);t.style.removeProperty("transition"),t.style.width="100%";var n=parseInt(window.getComputedStyle(t).width),n=parseInt(e/n*100);t.style.removeProperty("transition"),t.style.width="".concat(n,"%")}(),oe.timeout.stop()}function Gt(){if(oe.timeout){var t=oe.timeout.start();return lt(t),t}}function te(t){return Object.prototype.hasOwnProperty.call(ie,t)}function ee(t){return ae[t]}function ne(t){for(var e in t)te(o=e)||z('Unknown parameter "'.concat(o,'"')),t.toast&&(n=e,-1!==se.indexOf(n)&&z('The parameter "'.concat(n,'" is incompatible with toasts'))),ee(n=e)&&g(n,ee(n));var n,o}var oe={},ie={title:"",titleText:"",text:"",html:"",footer:"",icon:void 0,iconColor:void 0,iconHtml:void 0,toast:!1,animation:!0,showClass:{popup:"swal2-show",backdrop:"swal2-backdrop-show",icon:"swal2-icon-show"},hideClass:{popup:"swal2-hide",backdrop:"swal2-backdrop-hide",icon:"swal2-icon-hide"},customClass:void 0,target:"body",backdrop:!0,heightAuto:!0,allowOutsideClick:!0,allowEscapeKey:!0,allowEnterKey:!0,stopKeydownPropagation:!0,keydownListenerCapture:!1,showConfirmButton:!0,showDenyButton:!1,showCancelButton:!1,preConfirm:void 0,preDeny:void 0,confirmButtonText:"OK",confirmButtonAriaLabel:"",confirmButtonColor:void 0,denyButtonText:"No",denyButtonAriaLabel:"",denyButtonColor:void 0,cancelButtonText:"Cancel",cancelButtonAriaLabel:"",cancelButtonColor:void 0,buttonsStyling:!0,reverseButtons:!1,focusConfirm:!0,focusDeny:!1,focusCancel:!1,showCloseButton:!1,closeButtonHtml:"×",closeButtonAriaLabel:"Close this dialog",loaderHtml:"",showLoaderOnConfirm:!1,imageUrl:void 0,imageWidth:void 0,imageHeight:void 0,imageAlt:"",timer:void 0,timerProgressBar:!1,width:void 0,padding:void 0,background:void 0,input:void 0,inputPlaceholder:"",inputLabel:"",inputValue:"",inputOptions:{},inputAutoTrim:!0,inputAttributes:{},inputValidator:void 0,returnInputValueOnDeny:!1,validationMessage:void 0,grow:!1,position:"center",progressSteps:[],currentProgressStep:void 0,progressStepsDistance:void 0,onBeforeOpen:void 0,onOpen:void 0,willOpen:void 0,didOpen:void 0,onRender:void 0,didRender:void 0,onClose:void 0,onAfterClose:void 0,willClose:void 0,didClose:void 0,onDestroy:void 0,didDestroy:void 0,scrollbarPadding:!0},re=["allowEscapeKey","allowOutsideClick","background","buttonsStyling","cancelButtonAriaLabel","cancelButtonColor","cancelButtonText","closeButtonAriaLabel","closeButtonHtml","confirmButtonAriaLabel","confirmButtonColor","confirmButtonText","currentProgressStep","customClass","denyButtonAriaLabel","denyButtonColor","denyButtonText","didClose","didDestroy","footer","hideClass","html","icon","iconColor","imageAlt","imageHeight","imageUrl","imageWidth","onAfterClose","onClose","onDestroy","progressSteps","reverseButtons","showCancelButton","showCloseButton","showConfirmButton","showDenyButton","text","title","titleText","willClose"],ae={animation:'showClass" and "hideClass',onBeforeOpen:"willOpen",onOpen:"didOpen",onRender:"didRender",onClose:"willClose",onAfterClose:"didClose",onDestroy:"didDestroy"},se=["allowOutsideClick","allowEnterKey","backdrop","focusConfirm","focusDeny","focusCancel","heightAuto","keydownListenerCapture"],ce=Object.freeze({isValidParameter:te,isUpdatableParameter:function(t){return-1!==re.indexOf(t)},isDeprecatedParameter:ee,argsToParams:function(n){var o={};return"object"!==r(n[0])||w(n[0])?["title","html","icon"].forEach(function(t,e){e=n[e];"string"==typeof e||w(e)?o[t]=e:void 0!==e&&W("Unexpected type of ".concat(t,'! Expected "string" or "Element", got ').concat(r(e)))}):c(o,n[0]),o},isVisible:function(){return bt(x())},clickConfirm:Ut,clickDeny:function(){return L()&&L().click()},clickCancel:function(){return I()&&I().click()},getContainer:C,getPopup:x,getTitle:A,getContent:P,getHtmlContainer:function(){return t($["html-container"])},getImage:E,getIcon:B,getIcons:n,getInputLabel:function(){return t($["input-label"])},getCloseButton:H,getActions:q,getConfirmButton:T,getDenyButton:L,getCancelButton:I,getLoader:D,getHeader:j,getFooter:M,getTimerProgressBar:V,getFocusableElements:R,getValidationMessage:S,isLoading:function(){return x().hasAttribute("data-loading")},fire:function(){for(var t=arguments.length,e=new Array(t),n=0;nwindow.innerHeight&&(G.previousBodyPadding=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right")),document.body.style.paddingRight="".concat(G.previousBodyPadding+function(){var t=document.createElement("div");t.className=$["scrollbar-measure"],document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e}(),"px"))}function de(){return!!window.MSInputMethodContext&&!!document.documentMode}function pe(){var t=C(),e=x();t.style.removeProperty("align-items"),e.offsetTop<0&&(t.style.alignItems="flex-start")}var fe=function(){navigator.userAgent.match(/(CriOS|FxiOS|EdgiOS|YaBrowser|UCBrowser)/i)||x().scrollHeight>window.innerHeight-44&&(C().style.paddingBottom="".concat(44,"px"))},me=function(){var e,t=C();t.ontouchstart=function(t){e=he(t)},t.ontouchmove=function(t){e&&(t.preventDefault(),t.stopPropagation())}},he=function(t){var e=t.target,n=C();return!ge(t)&&!ve(t)&&(e===n||!(ct(n)||"INPUT"===e.tagName||ct(P())&&P().contains(e)))},ge=function(t){return t.touches&&t.touches.length&&"stylus"===t.touches[0].touchType},ve=function(t){return t.touches&&1")),Ct(t)}function Le(t){var e=C(),n=x();"function"==typeof t.willOpen?t.willOpen(n):"function"==typeof t.onBeforeOpen&&t.onBeforeOpen(n);var o=window.getComputedStyle(document.body).overflowY;He(e,n,t),setTimeout(function(){Me(e,n)},10),N()&&(Ve(e,t.scrollbarPadding,o),h(document.body.children).forEach(function(t){t===C()||function(t,e){if("function"==typeof t.contains)return t.contains(e)}(t,C())||(t.hasAttribute("aria-hidden")&&t.setAttribute("data-previous-aria-hidden",t.getAttribute("aria-hidden")),t.setAttribute("aria-hidden","true"))})),X()||oe.previousActiveElement||(oe.previousActiveElement=document.activeElement),je(n,t),vt(e,$["no-transition"])}function De(t){var e=x();t.target===e&&(t=C(),e.removeEventListener(Bt,De),t.style.overflowY="auto")}function Ie(t,e){t.closePopup({isConfirmed:!0,value:e})}function qe(t,e,n){var o=R(),i=0;if(i:first-child,.swal2-container.swal2-bottom-left>:first-child,.swal2-container.swal2-bottom-right>:first-child,.swal2-container.swal2-bottom-start>:first-child,.swal2-container.swal2-bottom>:first-child{margin-top:auto}.swal2-container.swal2-grow-fullscreen>.swal2-modal{display:flex!important;flex:1;align-self:stretch;justify-content:center}.swal2-container.swal2-grow-row>.swal2-modal{display:flex!important;flex:1;align-content:center;justify-content:center}.swal2-container.swal2-grow-column{flex:1;flex-direction:column}.swal2-container.swal2-grow-column.swal2-bottom,.swal2-container.swal2-grow-column.swal2-center,.swal2-container.swal2-grow-column.swal2-top{align-items:center}.swal2-container.swal2-grow-column.swal2-bottom-left,.swal2-container.swal2-grow-column.swal2-bottom-start,.swal2-container.swal2-grow-column.swal2-center-left,.swal2-container.swal2-grow-column.swal2-center-start,.swal2-container.swal2-grow-column.swal2-top-left,.swal2-container.swal2-grow-column.swal2-top-start{align-items:flex-start}.swal2-container.swal2-grow-column.swal2-bottom-end,.swal2-container.swal2-grow-column.swal2-bottom-right,.swal2-container.swal2-grow-column.swal2-center-end,.swal2-container.swal2-grow-column.swal2-center-right,.swal2-container.swal2-grow-column.swal2-top-end,.swal2-container.swal2-grow-column.swal2-top-right{align-items:flex-end}.swal2-container.swal2-grow-column>.swal2-modal{display:flex!important;flex:1;align-content:center;justify-content:center}.swal2-container.swal2-no-transition{transition:none!important}.swal2-container:not(.swal2-top):not(.swal2-top-start):not(.swal2-top-end):not(.swal2-top-left):not(.swal2-top-right):not(.swal2-center-start):not(.swal2-center-end):not(.swal2-center-left):not(.swal2-center-right):not(.swal2-bottom):not(.swal2-bottom-start):not(.swal2-bottom-end):not(.swal2-bottom-left):not(.swal2-bottom-right):not(.swal2-grow-fullscreen)>.swal2-modal{margin:auto}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-container .swal2-modal{margin:0!important}}.swal2-popup{display:none;position:relative;box-sizing:border-box;flex-direction:column;justify-content:center;width:32em;max-width:100%;padding:1.25em;border:none;border-radius:5px;background:#fff;font-family:inherit;font-size:1rem}.swal2-popup:focus{outline:0}.swal2-popup.swal2-loading{overflow-y:hidden}.swal2-header{display:flex;flex-direction:column;align-items:center;padding:0 1.8em}.swal2-title{position:relative;max-width:100%;margin:0 0 .4em;padding:0;color:#595959;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word}.swal2-actions{display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:100%;margin:1.25em auto 0;padding:0 1.6em}.swal2-actions:not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}.swal2-actions:not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))}.swal2-actions:not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.2))}.swal2-loader{display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 transparent #2778c4 transparent}.swal2-styled{margin:.3125em;padding:.625em 1.1em;box-shadow:none;font-weight:500}.swal2-styled:not([disabled]){cursor:pointer}.swal2-styled.swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:#2778c4;color:#fff;font-size:1.0625em}.swal2-styled.swal2-deny{border:0;border-radius:.25em;background:initial;background-color:#d14529;color:#fff;font-size:1.0625em}.swal2-styled.swal2-cancel{border:0;border-radius:.25em;background:initial;background-color:#757575;color:#fff;font-size:1.0625em}.swal2-styled:focus{outline:0;box-shadow:0 0 0 3px rgba(100,150,200,.5)}.swal2-styled::-moz-focus-inner{border:0}.swal2-footer{justify-content:center;margin:1.25em 0 0;padding:1em 0 0;border-top:1px solid #eee;color:#545454;font-size:1em}.swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;height:.25em;overflow:hidden;border-bottom-right-radius:5px;border-bottom-left-radius:5px}.swal2-timer-progress-bar{width:100%;height:.25em;background:rgba(0,0,0,.2)}.swal2-image{max-width:100%;margin:1.25em auto}.swal2-close{position:absolute;z-index:2;top:0;right:0;align-items:center;justify-content:center;width:1.2em;height:1.2em;padding:0;overflow:hidden;transition:color .1s ease-out;border:none;border-radius:5px;background:0 0;color:#ccc;font-family:serif;font-size:2.5em;line-height:1.2;cursor:pointer}.swal2-close:hover{transform:none;background:0 0;color:#f27474}.swal2-close:focus{outline:0;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}.swal2-close::-moz-focus-inner{border:0}.swal2-content{z-index:1;justify-content:center;margin:0;padding:0 1.6em;color:#545454;font-size:1.125em;font-weight:400;line-height:normal;text-align:center;word-wrap:break-word}.swal2-checkbox,.swal2-file,.swal2-input,.swal2-radio,.swal2-select,.swal2-textarea{margin:1em auto}.swal2-file,.swal2-input,.swal2-textarea{box-sizing:border-box;width:100%;transition:border-color .3s,box-shadow .3s;border:1px solid #d9d9d9;border-radius:.1875em;background:inherit;box-shadow:inset 0 1px 1px rgba(0,0,0,.06);color:inherit;font-size:1.125em}.swal2-file.swal2-inputerror,.swal2-input.swal2-inputerror,.swal2-textarea.swal2-inputerror{border-color:#f27474!important;box-shadow:0 0 2px #f27474!important}.swal2-file:focus,.swal2-input:focus,.swal2-textarea:focus{border:1px solid #b4dbed;outline:0;box-shadow:0 0 0 3px rgba(100,150,200,.5)}.swal2-file::-moz-placeholder,.swal2-input::-moz-placeholder,.swal2-textarea::-moz-placeholder{color:#ccc}.swal2-file:-ms-input-placeholder,.swal2-input:-ms-input-placeholder,.swal2-textarea:-ms-input-placeholder{color:#ccc}.swal2-file::placeholder,.swal2-input::placeholder,.swal2-textarea::placeholder{color:#ccc}.swal2-range{margin:1em auto;background:#fff}.swal2-range input{width:80%}.swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}.swal2-range input,.swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}.swal2-input{height:2.625em;padding:0 .75em}.swal2-input[type=number]{max-width:10em}.swal2-file{background:inherit;font-size:1.125em}.swal2-textarea{height:6.75em;padding:.75em}.swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:inherit;color:inherit;font-size:1.125em}.swal2-checkbox,.swal2-radio{align-items:center;justify-content:center;background:#fff;color:inherit}.swal2-checkbox label,.swal2-radio label{margin:0 .6em;font-size:1.125em}.swal2-checkbox input,.swal2-radio input{margin:0 .4em}.swal2-input-label{display:flex;justify-content:center;margin:1em auto}.swal2-validation-message{display:none;align-items:center;justify-content:center;margin:0 -2.7em;padding:.625em;overflow:hidden;background:#f0f0f0;color:#666;font-size:1em;font-weight:300}.swal2-validation-message::before{content:\"!\";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}.swal2-icon{position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:1.25em auto 1.875em;border:.25em solid transparent;border-radius:50%;font-family:inherit;line-height:5em;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}.swal2-icon.swal2-error{border-color:#f27474;color:#f27474}.swal2-icon.swal2-error .swal2-x-mark{position:relative;flex-grow:1}.swal2-icon.swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}.swal2-icon.swal2-error.swal2-icon-show{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-error.swal2-icon-show .swal2-x-mark{-webkit-animation:swal2-animate-error-x-mark .5s;animation:swal2-animate-error-x-mark .5s}.swal2-icon.swal2-warning{border-color:#facea8;color:#f8bb86}.swal2-icon.swal2-info{border-color:#9de0f6;color:#3fc3ee}.swal2-icon.swal2-question{border-color:#c9dae1;color:#87adbd}.swal2-icon.swal2-success{border-color:#a5dc86;color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;transform:rotate(45deg);border-radius:50%}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}.swal2-icon.swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-.25em;left:-.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}.swal2-icon.swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}.swal2-icon.swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}.swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-tip{-webkit-animation:swal2-animate-success-line-tip .75s;animation:swal2-animate-success-line-tip .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-long{-webkit-animation:swal2-animate-success-line-long .75s;animation:swal2-animate-success-line-long .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-circular-line-right{-webkit-animation:swal2-rotate-success-circular-line 4.25s ease-in;animation:swal2-rotate-success-circular-line 4.25s ease-in}.swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:0 0 1.25em;padding:0;background:inherit;font-weight:600}.swal2-progress-steps li{display:inline-block;position:relative}.swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:#add8e6;color:#fff}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:#add8e6}.swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}[class^=swal2]{-webkit-tap-highlight-color:transparent}.swal2-show{-webkit-animation:swal2-show .3s;animation:swal2-show .3s}.swal2-hide{-webkit-animation:swal2-hide .15s forwards;animation:swal2-hide .15s forwards}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{right:auto;left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}@supports (-ms-accelerator:true){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@-webkit-keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0)}}@keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0)}}@-webkit-keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@-webkit-keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@-webkit-keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}@-webkit-keyframes swal2-show{0%{transform:scale(.7)}45%{transform:scale(1.05)}80%{transform:scale(.95)}100%{transform:scale(1)}}@keyframes swal2-show{0%{transform:scale(.7)}45%{transform:scale(1.05)}80%{transform:scale(.95)}100%{transform:scale(1)}}@-webkit-keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(.5);opacity:0}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(.5);opacity:0}}@-webkit-keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@-webkit-keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@-webkit-keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@-webkit-keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}50%{margin-top:1.625em;transform:scale(.4);opacity:0}80%{margin-top:-.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(.4);opacity:0}50%{margin-top:1.625em;transform:scale(.4);opacity:0}80%{margin-top:-.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@-webkit-keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0);opacity:1}}@-webkit-keyframes swal2-rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes swal2-rotate-loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto!important}body.swal2-no-backdrop .swal2-container{top:auto;right:auto;bottom:auto;left:auto;max-width:calc(100% - .625em * 2);background-color:transparent!important}body.swal2-no-backdrop .swal2-container>.swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}body.swal2-no-backdrop .swal2-container.swal2-top{top:0;left:50%;transform:translateX(-50%)}body.swal2-no-backdrop .swal2-container.swal2-top-left,body.swal2-no-backdrop .swal2-container.swal2-top-start{top:0;left:0}body.swal2-no-backdrop .swal2-container.swal2-top-end,body.swal2-no-backdrop .swal2-container.swal2-top-right{top:0;right:0}body.swal2-no-backdrop .swal2-container.swal2-center{top:50%;left:50%;transform:translate(-50%,-50%)}body.swal2-no-backdrop .swal2-container.swal2-center-left,body.swal2-no-backdrop .swal2-container.swal2-center-start{top:50%;left:0;transform:translateY(-50%)}body.swal2-no-backdrop .swal2-container.swal2-center-end,body.swal2-no-backdrop .swal2-container.swal2-center-right{top:50%;right:0;transform:translateY(-50%)}body.swal2-no-backdrop .swal2-container.swal2-bottom{bottom:0;left:50%;transform:translateX(-50%)}body.swal2-no-backdrop .swal2-container.swal2-bottom-left,body.swal2-no-backdrop .swal2-container.swal2-bottom-start{bottom:0;left:0}body.swal2-no-backdrop .swal2-container.swal2-bottom-end,body.swal2-no-backdrop .swal2-container.swal2-bottom-right{right:0;bottom:0}@media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll!important}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:static!important}}body.swal2-toast-shown .swal2-container{background-color:transparent}body.swal2-toast-shown .swal2-container.swal2-top{top:0;right:auto;bottom:auto;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{top:0;right:0;bottom:auto;left:auto}body.swal2-toast-shown .swal2-container.swal2-top-left,body.swal2-toast-shown .swal2-container.swal2-top-start{top:0;right:auto;bottom:auto;left:0}body.swal2-toast-shown .swal2-container.swal2-center-left,body.swal2-toast-shown .swal2-container.swal2-center-start{top:50%;right:auto;bottom:auto;left:0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{top:50%;right:auto;bottom:auto;left:50%;transform:translate(-50%,-50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{top:50%;right:0;bottom:auto;left:auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-left,body.swal2-toast-shown .swal2-container.swal2-bottom-start{top:auto;right:auto;bottom:0;left:0}body.swal2-toast-shown .swal2-container.swal2-bottom{top:auto;right:auto;bottom:0;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{top:auto;right:0;bottom:0;left:auto}body.swal2-toast-column .swal2-toast{flex-direction:column;align-items:stretch}body.swal2-toast-column .swal2-toast .swal2-actions{flex:1;align-self:stretch;height:2.2em;margin-top:.3125em}body.swal2-toast-column .swal2-toast .swal2-loading{justify-content:center}body.swal2-toast-column .swal2-toast .swal2-input{height:2em;margin:.3125em auto;font-size:1em}body.swal2-toast-column .swal2-toast .swal2-validation-message{font-size:1em}"); -------------------------------------------------------------------------------- /Dist/absen.html: -------------------------------------------------------------------------------- 1 | Absen Siswa
    foto-guru

    Guru BK

    Sman 3 Mataram

    ABSENSI SISWA

    Sman 3 Mataram

    ABSEN SISWA
    -------------------------------------------------------------------------------- /Dist/bundle.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | * Sizzle CSS Selector Engine v2.3.5 3 | * https://sizzlejs.com/ 4 | * 5 | * Copyright JS Foundation and other contributors 6 | * Released under the MIT license 7 | * https://js.foundation/ 8 | * 9 | * Date: 2020-03-14 10 | */ 11 | 12 | /*! 13 | * Bootstrap v4.5.2 (https://getbootstrap.com/) 14 | * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 15 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 16 | */ 17 | 18 | /*! 19 | * jQuery JavaScript Library v3.5.1 20 | * https://jquery.com/ 21 | * 22 | * Includes Sizzle.js 23 | * https://sizzlejs.com/ 24 | * 25 | * Copyright JS Foundation and other contributors 26 | * Released under the MIT license 27 | * https://jquery.org/license 28 | * 29 | * Date: 2020-05-04T22:49Z 30 | */ 31 | 32 | /**! 33 | * @fileOverview Kickass library to create and place poppers near their reference elements. 34 | * @version 1.16.1 35 | * @license 36 | * Copyright (c) 2016 Federico Zivolo and contributors 37 | * 38 | * Permission is hereby granted, free of charge, to any person obtaining a copy 39 | * of this software and associated documentation files (the "Software"), to deal 40 | * in the Software without restriction, including without limitation the rights 41 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 42 | * copies of the Software, and to permit persons to whom the Software is 43 | * furnished to do so, subject to the following conditions: 44 | * 45 | * The above copyright notice and this permission notice shall be included in all 46 | * copies or substantial portions of the Software. 47 | * 48 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 49 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 50 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 51 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 52 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 53 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 54 | * SOFTWARE. 55 | */ 56 | -------------------------------------------------------------------------------- /Dist/index.html: -------------------------------------------------------------------------------- 1 | Sman 3 Mataram - Login
    -------------------------------------------------------------------------------- /Dist/webpack.common.dev.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var htmlWebpackPlugin = require("html-webpack-plugin"); 4 | 5 | var path = require("path"); 6 | 7 | module.exports = { 8 | entry: "./App/index.js", 9 | output: { 10 | path: path.resolve(__dirname, "Dist"), 11 | filename: "bundle.js" 12 | }, 13 | module: { 14 | rules: [{ 15 | test: /\.css$/, 16 | use: [{ 17 | loader: "style-loader" 18 | }, { 19 | loader: "css-loader" 20 | }] 21 | }] 22 | }, 23 | plugins: [new htmlWebpackPlugin({ 24 | template: "./App/index.html", 25 | filename: "index.html" 26 | }), new htmlWebpackPlugin({ 27 | template: "./App/absen.html", 28 | filename: "absen.html" 29 | })] 30 | }; -------------------------------------------------------------------------------- /Screenshot/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azrilardian/Absen-Siswa/5ac28163414c4cf3739562dda6cd9716c91a16e1/Screenshot/1.png -------------------------------------------------------------------------------- /Screenshot/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azrilardian/Absen-Siswa/5ac28163414c4cf3739562dda6cd9716c91a16e1/Screenshot/2.png -------------------------------------------------------------------------------- /Screenshot/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azrilardian/Absen-Siswa/5ac28163414c4cf3739562dda6cd9716c91a16e1/Screenshot/3.png -------------------------------------------------------------------------------- /debug.log: -------------------------------------------------------------------------------- 1 | [1031/223243.321:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 2 | [1101/110903.035:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 3 | [1101/151451.993:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 4 | [1101/170107.766:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 5 | [1102/000037.012:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 6 | [1103/103901.564:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 7 | [1103/143123.389:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 8 | [1103/222927.870:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 9 | [1104/124114.883:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 10 | [1104/130640.711:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 11 | [1105/100914.640:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 12 | [1105/134528.820:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 13 | [1106/110816.030:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 14 | [1106/130541.959:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 15 | [1106/134155.343:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 16 | [1106/170221.600:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 17 | [1106/232555.823:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 18 | [1107/224158.160:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 19 | [1108/010914.299:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 20 | [1108/121944.467:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 21 | [1108/162725.739:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 22 | [1108/182330.938:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 23 | [1108/194716.492:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 24 | [1108/215751.551:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 25 | [1109/005430.181:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 26 | [1109/172524.691:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 27 | [1110/120544.146:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 28 | [1110/192649.048:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 29 | [1111/005601.266:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 30 | [1111/015041.166:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 31 | [1111/083504.671:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 32 | [1111/150415.543:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 33 | [1111/152425.863:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 34 | [1112/143349.806:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 35 | [1112/163315.387:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 36 | [1112/221208.996:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 37 | [1113/004302.725:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 38 | [1113/152657.641:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 39 | [1113/232701.466:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 40 | [1115/020722.144:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 41 | [1115/110640.263:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 42 | [1116/000041.043:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 43 | [1116/120146.952:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 44 | [1119/122009.970:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 45 | [1119/134846.393:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 46 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "absen-siswa", 3 | "version": "1.0.0", 4 | "description": "Program absensi siswa", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "webpack --config webpack.prod.js", 8 | "live": "webpack-dev-server --config webpack.dev.js --open" 9 | }, 10 | "keywords": [ 11 | "absen" 12 | ], 13 | "author": "Azrilardian", 14 | "license": "ISC", 15 | "dependencies": { 16 | "bootstrap": "^4.5.2", 17 | "jquery": "^3.5.1", 18 | "popper.js": "^1.16.1", 19 | "sweetalert2": "^10.10.0" 20 | }, 21 | "devDependencies": { 22 | "@babel/core": "^7.11.6", 23 | "@babel/preset-env": "^7.11.5", 24 | "babel-loader": "^8.1.0", 25 | "clean-webpack-plugin": "^3.0.0", 26 | "css-loader": "^4.3.0", 27 | "html-webpack-plugin": "^4.5.0", 28 | "optimize-css-assets-webpack-plugin": "^5.0.4", 29 | "style-loader": "^1.3.0", 30 | "terser-webpack-plugin": "^4.2.2", 31 | "uglifyjs-webpack-plugin": "^2.2.0", 32 | "webpac": "0.0.1-security", 33 | "webpack": "^4.44.2", 34 | "webpack-cli": "^3.3.12", 35 | "webpack-dev-server": "^3.11.0", 36 | "webpack-merge": "^5.2.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Program Absensi Siswa 2 | 3 | ## Apa dan Tujuan 4 | 5 | _Project_ ini sebenarnya merupakan _project_ yang sudah lama ingin saya buat, namun, saat itu saya merasa sangat susah untuk merealisasikannya, karena ketika itu pengetahuan saya dalam dunia _programming_ terbilang masih terlalu minim, alhasil, _project_ ini saya tinggalkan lalu terbengkalai begitu saja. 6 | 7 | Ketika saya merasa ilmu yang saya miliki sudah cukup baik, terutama pada dasar - dasar bahasa Javascript, saya berkeinginan untuk menyelesaikan _project_ ini. Semua saya bangun kembali dari awal, mulai dari membuat tampilan program, merancang alur program, hingga membangunnya. 8 | 9 | Ini merupakan program absen siswa yang dapat memudahkan guru untuk melakukan absensi, karena kemudahannya yang dapat diakses melalui komputer / ponsel mereka. Bisa dibilang, ini adalah absensi siswa kekinian yang sangat bermanfaat, karena sekolah tidak perlu lagi mencetak lembaran absensi siswa setiap minggunya, atau bahkan bulan, cukup hanya memesan guru untuk membawa laptop pribadi / ponsel mereka pada saat pelajaran berlangsung. 10 | 11 | ## Teknologi yang digunakan 12 | 13 | - Html 14 | - Css 15 | - Bootstrap 16 | - Javascript 17 | - Sweetalert2 18 | - Webpack 19 | 20 | ## Fitur 21 | 22 | - _Login_ ( belum menggunakan _database_ ) 23 | - Kehadiran siswa ( bolos, izin, sakit ) 24 | - Hapus siswa, mengubah nama siswa 25 | - Otomatis mengelompokan siswa berdasarkan kelas 26 | - _Darkmode_ 27 | - Responsif pada semua ukuran _device_ 28 | - Menyimpan data ke _local storage_ 29 | 30 | ## Catatan 31 | 32 | _Project_ ini merupakan versi **2.0**, silahkan cek ke riwayat _commit_ untuk melihat _project_ versi sebelumnya. 33 | 34 | Yang baru di versi **2.0** : 35 | 36 | - Fitur login 37 | - Tampilan lebih simpel 38 | - _Darkmode_ 39 | - _Sidebar_ 40 | - Tampilan _popup_ yang lebih baik 41 | 42 | Akun yang dapat digunakan untuk login : 43 | 44 | 1. **Sandhika Galih** 45 | 46 | - Username : Sandhika Galih 47 | - Password : wpunpas2020 48 | 49 | 2. **Azril ardian** 50 | - Username : Azril ardian 51 | - Password : 12345678 52 | 53 | ## Screenshot ( Versi 2 ) 54 | 55 | ![Screenshot satu](./Screenshot/1.png) 56 | 57 | ![Screenshot satu](./Screenshot/2.png) 58 | 59 | ![Screenshot satu](./Screenshot/3.png) 60 | -------------------------------------------------------------------------------- /webpack.common.js: -------------------------------------------------------------------------------- 1 | const htmlWebpackPlugin = require("html-webpack-plugin"); 2 | const path = require("path"); 3 | 4 | module.exports = { 5 | entry: "./App/index.js", 6 | output: { 7 | path: path.resolve(__dirname, "Dist"), 8 | filename: "bundle.js", 9 | }, 10 | module: { 11 | rules: [ 12 | { 13 | test: /\.css$/, 14 | use: [ 15 | { 16 | loader: "style-loader", 17 | }, 18 | { 19 | loader: "css-loader", 20 | }, 21 | ], 22 | }, 23 | ], 24 | }, 25 | plugins: [ 26 | new htmlWebpackPlugin({ 27 | template: "./App/index.html", 28 | filename: "index.html", 29 | }), 30 | new htmlWebpackPlugin({ 31 | template: "./App/absen.html", 32 | filename: "absen.html", 33 | }), 34 | ], 35 | }; 36 | -------------------------------------------------------------------------------- /webpack.dev.js: -------------------------------------------------------------------------------- 1 | const { merge } = require("webpack-merge"); 2 | const common = require("./webpack.common"); 3 | 4 | module.exports = merge(common, { 5 | mode: "development", 6 | }); 7 | -------------------------------------------------------------------------------- /webpack.prod.js: -------------------------------------------------------------------------------- 1 | const { merge } = require("webpack-merge"); 2 | const common = require("./webpack.common"); 3 | 4 | module.exports = merge(common, { 5 | mode: "production", 6 | module: { 7 | rules: [ 8 | { 9 | test: /\.js$/, 10 | exclude: "/node_modules/", 11 | use: [ 12 | { 13 | loader: "babel-loader", 14 | options: { 15 | presets: ["@babel/preset-env"], 16 | }, 17 | }, 18 | ], 19 | }, 20 | ], 21 | }, 22 | }); 23 | --------------------------------------------------------------------------------