@muflih_kh/profile-ui 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ .colored-toast.swal2-icon-success{background-color:#a5dc86!important}.colored-toast{font-size:.5rem!important;min-width:220px!important;max-width:320px!important;padding:.75rem 1.25rem!important;box-sizing:border-box;right:1.5rem!important;top:1.5rem!important;left:auto!important;bottom:auto!important;position:fixed!important;z-index:9999!important;margin:0!important;pointer-events:auto;transition:all .3s}.colored-toast.swal2-icon-error{background-color:#f27474!important}.colored-toast.swal2-icon-warning{background-color:#f8bb86!important}.colored-toast.swal2-icon-info{background-color:#3fc3ee!important}.colored-toast.swal2-icon-question{background-color:#87adbd!important}.colored-toast .swal2-title,.colored-toast .swal2-close,.colored-toast .swal2-html-container{color:#fff}.label-row[data-v-8b4acac7]{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.template-link a[data-v-8b4acac7]{color:#2d8cf0;text-decoration:none;font-weight:500;font-size:.9em;transition:color .2s}.template-link a[data-v-8b4acac7]:hover{color:#1c6dcf;text-decoration:underline}.error[data-v-8b4acac7]{color:#d9534f;font-size:.875em;margin-top:4px}.preview-container[data-v-8b4acac7]{padding:12px;background-color:#f8f9fa;border-radius:4px;border:1px solid #dee2e6}.preview-image[data-v-8b4acac7]{max-width:200px;max-height:200px;border-radius:4px;box-shadow:0 2px 4px #0000001a;cursor:pointer;transition:transform .2s,box-shadow .2s}.preview-image[data-v-8b4acac7]:hover{transform:scale(1.05);box-shadow:0 4px 8px #00000026}.modal-preview-image[data-v-8b4acac7]{max-width:100%;max-height:70vh;border-radius:4px;box-shadow:0 4px 12px #0003}.modal.show[data-v-aba4943e]{display:block}.mx-icon-left:before,.mx-icon-right:before,.mx-icon-double-left:before,.mx-icon-double-right:before,.mx-icon-double-left:after,.mx-icon-double-right:after{content:"";position:relative;top:-1px;display:inline-block;width:10px;height:10px;vertical-align:middle;border-style:solid;border-color:currentColor;border-width:2px 0 0 2px;border-radius:1px;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate(-45deg) scale(.7);transform:rotate(-45deg) scale(.7)}.mx-icon-double-left:after{left:-4px}.mx-icon-double-right:before{left:4px}.mx-icon-right:before,.mx-icon-double-right:before,.mx-icon-double-right:after{-webkit-transform:rotate(135deg) scale(.7);transform:rotate(135deg) scale(.7)}.mx-btn{-webkit-box-sizing:border-box;box-sizing:border-box;line-height:1;font-size:14px;font-weight:500;padding:7px 15px;margin:0;cursor:pointer;background-color:transparent;outline:none;border:1px solid rgba(0,0,0,.1);border-radius:4px;color:#73879c;white-space:nowrap}.mx-btn:hover{border-color:#1284e7;color:#1284e7}.mx-btn:disabled,.mx-btn.disabled{color:#ccc;cursor:not-allowed}.mx-btn-text{border:0;padding:0 4px;text-align:left;line-height:inherit}.mx-scrollbar{height:100%}.mx-scrollbar:hover .mx-scrollbar-track{opacity:1}.mx-scrollbar-wrap{height:100%;overflow-x:hidden;overflow-y:auto}.mx-scrollbar-track{position:absolute;top:2px;right:2px;bottom:2px;width:6px;z-index:1;border-radius:4px;opacity:0;-webkit-transition:opacity .24s ease-out;transition:opacity .24s ease-out}.mx-scrollbar-track .mx-scrollbar-thumb{position:absolute;width:100%;height:0;cursor:pointer;border-radius:inherit;background-color:#9093994d;-webkit-transition:background-color .3s;transition:background-color .3s}.mx-zoom-in-down-enter-active,.mx-zoom-in-down-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center top;transform-origin:center top}.mx-zoom-in-down-enter,.mx-zoom-in-down-enter-from,.mx-zoom-in-down-leave-to{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.mx-datepicker{position:relative;display:inline-block;width:210px}.mx-datepicker svg{width:1em;height:1em;vertical-align:-.15em;fill:currentColor;overflow:hidden}.mx-datepicker-range{width:320px}.mx-datepicker-inline{width:auto}.mx-input-wrapper{position:relative}.mx-input{display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;height:34px;padding:6px 30px 6px 10px;font-size:14px;line-height:1.4;color:#555;background-color:#fff;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px #00000013}.mx-input:hover,.mx-input:focus{border-color:#409aff}.mx-input:disabled,.mx-input.disabled{color:#ccc;background-color:#f3f3f3;border-color:#ccc;cursor:not-allowed}.mx-input:focus{outline:none}.mx-input::-ms-clear{display:none}.mx-icon-calendar,.mx-icon-clear{position:absolute;top:50%;right:8px;-webkit-transform:translateY(-50%);transform:translateY(-50%);font-size:16px;line-height:1;color:#00000080;vertical-align:middle}.mx-icon-clear{cursor:pointer}.mx-icon-clear:hover{color:#000c}.mx-datepicker-main{font:14px/1.5 Helvetica Neue,Helvetica,Arial,Microsoft Yahei,sans-serif;color:#73879c;background-color:#fff;border:1px solid #e8e8e8}.mx-datepicker-popup{position:absolute;margin-top:1px;margin-bottom:1px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px #0000002d;z-index:2001}.mx-datepicker-sidebar{float:left;-webkit-box-sizing:border-box;box-sizing:border-box;width:100px;padding:6px;overflow:auto}.mx-datepicker-sidebar+.mx-datepicker-content{margin-left:100px;border-left:1px solid #e8e8e8}.mx-datepicker-body{position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mx-btn-shortcut{display:block;padding:0 6px;line-height:24px}.mx-range-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex}@media (max-width: 750px){.mx-range-wrapper{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}}.mx-datepicker-header{padding:6px 8px;border-bottom:1px solid #e8e8e8}.mx-datepicker-footer{padding:6px 8px;text-align:right;border-top:1px solid #e8e8e8}.mx-calendar{-webkit-box-sizing:border-box;box-sizing:border-box;width:248px;padding:6px 12px}.mx-calendar+.mx-calendar{border-left:1px solid #e8e8e8}.mx-calendar-header,.mx-time-header{-webkit-box-sizing:border-box;box-sizing:border-box;height:34px;line-height:34px;text-align:center;overflow:hidden}.mx-btn-icon-left,.mx-btn-icon-double-left{float:left}.mx-btn-icon-right,.mx-btn-icon-double-right{float:right}.mx-calendar-header-label{font-size:14px}.mx-calendar-decade-separator{margin:0 2px}.mx-calendar-decade-separator:after{content:"~"}.mx-calendar-content{position:relative;height:224px;-webkit-box-sizing:border-box;box-sizing:border-box}.mx-calendar-content .cell{cursor:pointer}.mx-calendar-content .cell:hover{color:#73879c;background-color:#f3f9fe}.mx-calendar-content .cell.active{color:#fff;background-color:#1284e7}.mx-calendar-content .cell.in-range,.mx-calendar-content .cell.hover-in-range{color:#73879c;background-color:#dbedfb}.mx-calendar-content .cell.disabled{cursor:not-allowed;color:#ccc;background-color:#f3f3f3}.mx-calendar-week-mode .mx-date-row{cursor:pointer}.mx-calendar-week-mode .mx-date-row:hover{background-color:#f3f9fe}.mx-calendar-week-mode .mx-date-row.mx-active-week{background-color:#dbedfb}.mx-calendar-week-mode .mx-date-row .cell:hover,.mx-calendar-week-mode .mx-date-row .cell.active{color:inherit;background-color:transparent}.mx-week-number{opacity:.5}.mx-table{table-layout:fixed;border-collapse:separate;border-spacing:0;width:100%;height:100%;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center}.mx-table th{padding:0;font-weight:500;vertical-align:middle}.mx-table td{padding:0;vertical-align:middle}.mx-table-date td,.mx-table-date th{height:32px;font-size:12px}.mx-table-date .today{color:#2a90e9}.mx-table-date .cell.not-current-month{color:#ccc;background:none}.mx-time{-webkit-box-flex:1;-ms-flex:1;flex:1;width:224px;background:#fff}.mx-time+.mx-time{border-left:1px solid #e8e8e8}.mx-calendar-time{position:absolute;top:0;left:0;width:100%;height:100%}.mx-time-header{border-bottom:1px solid #e8e8e8}.mx-time-content{height:224px;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden}.mx-time-columns{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;height:100%;overflow:hidden}.mx-time-column{-webkit-box-flex:1;-ms-flex:1;flex:1;position:relative;border-left:1px solid #e8e8e8;text-align:center}.mx-time-column:first-child{border-left:0}.mx-time-column .mx-time-list{margin:0;padding:0;list-style:none}.mx-time-column .mx-time-list:after{content:"";display:block;height:192px}.mx-time-column .mx-time-item{cursor:pointer;font-size:12px;height:32px;line-height:32px}.mx-time-column .mx-time-item:hover{color:#73879c;background-color:#f3f9fe}.mx-time-column .mx-time-item.active{color:#1284e7;background-color:transparent;font-weight:700}.mx-time-column .mx-time-item.disabled{cursor:not-allowed;color:#ccc;background-color:#f3f3f3}.mx-time-option{cursor:pointer;padding:8px 10px;font-size:14px;line-height:20px}.mx-time-option:hover{color:#73879c;background-color:#f3f9fe}.mx-time-option.active{color:#1284e7;background-color:transparent;font-weight:700}.mx-time-option.disabled{cursor:not-allowed;color:#ccc;background-color:#f3f3f3}:host,:root{--vs-colors--lightest:rgba(60,60,60,.26);--vs-colors--light:rgba(60,60,60,.5);--vs-colors--dark:#333;--vs-colors--darkest:rgba(0,0,0,.15);--vs-search-input-color:inherit;--vs-search-input-bg:#fff;--vs-search-input-placeholder-color:inherit;--vs-font-size:1rem;--vs-line-height:1.4;--vs-state-disabled-bg:#f8f8f8;--vs-state-disabled-color:var(--vs-colors--light);--vs-state-disabled-controls-color:var(--vs-colors--light);--vs-state-disabled-cursor:not-allowed;--vs-border-color:var(--vs-colors--lightest);--vs-border-width:1px;--vs-border-style:solid;--vs-border-radius:4px;--vs-actions-padding:4px 6px 0 3px;--vs-controls-color:var(--vs-colors--light);--vs-controls-size:1;--vs-controls--deselect-text-shadow:0 1px 0 #fff;--vs-selected-bg:#f0f0f0;--vs-selected-color:var(--vs-colors--dark);--vs-selected-border-color:var(--vs-border-color);--vs-selected-border-style:var(--vs-border-style);--vs-selected-border-width:var(--vs-border-width);--vs-dropdown-bg:#fff;--vs-dropdown-color:inherit;--vs-dropdown-z-index:1000;--vs-dropdown-min-width:160px;--vs-dropdown-max-height:350px;--vs-dropdown-box-shadow:0px 3px 6px 0px var(--vs-colors--darkest);--vs-dropdown-option-bg:#000;--vs-dropdown-option-color:var(--vs-dropdown-color);--vs-dropdown-option-padding:3px 20px;--vs-dropdown-option--active-bg:#5897fb;--vs-dropdown-option--active-color:#fff;--vs-dropdown-option--deselect-bg:#fb5858;--vs-dropdown-option--deselect-color:#fff;--vs-transition-timing-function:cubic-bezier(1,-.115,.975,.855);--vs-transition-duration:.15s}.v-select{font-family:inherit;position:relative}.v-select,.v-select *{box-sizing:border-box}:root{--vs-transition-timing-function:cubic-bezier(1,.5,.8,1);--vs-transition-duration:.15s}@-webkit-keyframes vSelectSpinner{0%{transform:rotate(0)}to{transform:rotate(1turn)}}@keyframes vSelectSpinner{0%{transform:rotate(0)}to{transform:rotate(1turn)}}.vs__fade-enter-active,.vs__fade-leave-active{pointer-events:none;transition:opacity var(--vs-transition-duration) var(--vs-transition-timing-function)}.vs__fade-enter,.vs__fade-leave-to{opacity:0}:root{--vs-disabled-bg:var(--vs-state-disabled-bg);--vs-disabled-color:var(--vs-state-disabled-color);--vs-disabled-cursor:var(--vs-state-disabled-cursor)}.vs--disabled .vs__clear,.vs--disabled .vs__dropdown-toggle,.vs--disabled .vs__open-indicator,.vs--disabled .vs__search,.vs--disabled .vs__selected{background-color:var(--vs-disabled-bg);cursor:var(--vs-disabled-cursor)}.v-select[dir=rtl] .vs__actions{padding:0 3px 0 6px}.v-select[dir=rtl] .vs__clear{margin-left:6px;margin-right:0}.v-select[dir=rtl] .vs__deselect{margin-left:0;margin-right:2px}.v-select[dir=rtl] .vs__dropdown-menu{text-align:right}.vs__dropdown-toggle{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:var(--vs-search-input-bg);border:var(--vs-border-width) var(--vs-border-style) var(--vs-border-color);border-radius:var(--vs-border-radius);display:flex;padding:0 0 4px;white-space:normal}.vs__selected-options{display:flex;flex-basis:100%;flex-grow:1;flex-wrap:wrap;padding:0 2px;position:relative}.vs__actions{align-items:center;display:flex;padding:var(--vs-actions-padding)}.vs--searchable .vs__dropdown-toggle{cursor:text}.vs--unsearchable .vs__dropdown-toggle{cursor:pointer}.vs--open .vs__dropdown-toggle{border-bottom-color:transparent;border-bottom-left-radius:0;border-bottom-right-radius:0}.vs__open-indicator{fill:var(--vs-controls-color);transform:scale(var(--vs-controls-size));transition:transform var(--vs-transition-duration) var(--vs-transition-timing-function);transition-timing-function:var(--vs-transition-timing-function)}.vs--open .vs__open-indicator{transform:rotate(180deg) scale(var(--vs-controls-size))}.vs--loading .vs__open-indicator{opacity:0}.vs__clear{fill:var(--vs-controls-color);background-color:transparent;border:0;cursor:pointer;margin-right:8px;padding:0}.vs__dropdown-menu{background:var(--vs-dropdown-bg);border:var(--vs-border-width) var(--vs-border-style) var(--vs-border-color);border-radius:0 0 var(--vs-border-radius) var(--vs-border-radius);border-top-style:none;box-shadow:var(--vs-dropdown-box-shadow);box-sizing:border-box;color:var(--vs-dropdown-color);display:block;left:0;list-style:none;margin:0;max-height:var(--vs-dropdown-max-height);min-width:var(--vs-dropdown-min-width);overflow-y:auto;padding:5px 0;position:absolute;text-align:left;top:calc(100% - var(--vs-border-width));width:100%;z-index:var(--vs-dropdown-z-index)}.vs__no-options{text-align:center}.vs__dropdown-option{clear:both;color:var(--vs-dropdown-option-color);cursor:pointer;display:block;line-height:1.42857143;padding:var(--vs-dropdown-option-padding);white-space:nowrap}.vs__dropdown-option--highlight{background:var(--vs-dropdown-option--active-bg);color:var(--vs-dropdown-option--active-color)}.vs__dropdown-option--deselect{background:var(--vs-dropdown-option--deselect-bg);color:var(--vs-dropdown-option--deselect-color)}.vs__dropdown-option--disabled{background:var(--vs-state-disabled-bg);color:var(--vs-state-disabled-color);cursor:var(--vs-state-disabled-cursor)}.vs__selected{align-items:center;background-color:var(--vs-selected-bg);border:var(--vs-selected-border-width) var(--vs-selected-border-style) var(--vs-selected-border-color);border-radius:var(--vs-border-radius);color:var(--vs-selected-color);display:flex;line-height:var(--vs-line-height);margin:4px 2px 0;padding:0 .25em;z-index:0}.vs__deselect{fill:var(--vs-controls-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;cursor:pointer;display:inline-flex;margin-left:4px;padding:0;text-shadow:var(--vs-controls--deselect-text-shadow)}.vs--single .vs__selected{background-color:transparent;border-color:transparent}.vs--single.vs--loading .vs__selected,.vs--single.vs--open .vs__selected{opacity:.4;position:absolute}.vs--single.vs--searching .vs__selected{display:none}.vs__search::-webkit-search-cancel-button{display:none}.vs__search::-ms-clear,.vs__search::-webkit-search-decoration,.vs__search::-webkit-search-results-button,.vs__search::-webkit-search-results-decoration{display:none}.vs__search,.vs__search:focus{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:1px solid transparent;border-left:none;box-shadow:none;color:var(--vs-search-input-color);flex-grow:1;font-size:var(--vs-font-size);line-height:var(--vs-line-height);margin:4px 0 0;max-width:100%;outline:none;padding:0 7px;width:0;z-index:1}.vs__search::-moz-placeholder{color:var(--vs-search-input-placeholder-color)}.vs__search:-ms-input-placeholder{color:var(--vs-search-input-placeholder-color)}.vs__search::placeholder{color:var(--vs-search-input-placeholder-color)}.vs--unsearchable .vs__search{opacity:1}.vs--unsearchable:not(.vs--disabled) .vs__search{cursor:pointer}.vs--single.vs--searching:not(.vs--open):not(.vs--loading) .vs__search{opacity:.2}.vs__spinner{align-self:center;-webkit-animation:vSelectSpinner 1.1s linear infinite;animation:vSelectSpinner 1.1s linear infinite;border:.9em solid hsla(0,0%,39%,.1);border-left-color:#3c3c3c73;font-size:5px;opacity:0;overflow:hidden;text-indent:-9999em;transform:translateZ(0) scale(var(--vs-controls--spinner-size,var(--vs-controls-size)));transition:opacity .1s}.vs__spinner,.vs__spinner:after{border-radius:50%;height:5em;transform:scale(var(--vs-controls--spinner-size,var(--vs-controls-size)));width:5em}.vs--loading .vs__spinner{opacity:1}.modal.show[data-v-64e3f909]{display:block}.v-select[data-v-64e3f909]{width:100%}.v-select .vs__dropdown-toggle[data-v-64e3f909]{padding:.375rem .75rem;border:1px solid #ced4da;border-radius:.25rem}.v-select .vs__search[data-v-64e3f909]{margin:0;padding:0;border:none}.v-select .vs__search[data-v-64e3f909]:focus{outline:none}.v-select .vs__dropdown-menu[data-v-64e3f909]{border:1px solid #ced4da;border-radius:.25rem;box-shadow:0 .125rem .25rem #00000013;max-height:250px;overflow-y:auto}.v-select .vs__dropdown-option[data-v-64e3f909]{padding:.5rem .75rem}.v-select .vs__dropdown-option--highlight[data-v-64e3f909]{background:#0d6efd;color:#fff}.v-select .vs__selected[data-v-64e3f909]{margin:0;padding:0}.v-select .vs__clear[data-v-64e3f909]{margin-right:5px}.link[data-v-ddc3d2fd]{cursor:pointer;color:#0d6efd;text-decoration:none}.link[data-v-ddc3d2fd]:hover{text-decoration:underline}.modal.show[data-v-c9e10ed6],.modal.show[data-v-a05020f4]{display:block}.link[data-v-50d12d5f]{cursor:pointer;color:#0d6efd;text-decoration:none}.link[data-v-50d12d5f]:hover{text-decoration:underline}.modal.show[data-v-263af438],.modal.show[data-v-5bfdc8af]{display:block}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@muflih_kh/profile-ui",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "./dist/profile-ui.umd.js",
6
+ "module": "./dist/profile-ui.es.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/profile-ui.es.js",
11
+ "require": "./dist/profile-ui.umd.js",
12
+ "types": "./dist/index.d.ts"
13
+ },
14
+ "./*.css": "./dist/*.css",
15
+ "./*.vue": "./src/components/*.vue"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "src/components/*.vue"
20
+ ],
21
+ "scripts": {
22
+ "dev": "vite",
23
+ "build": "vite build",
24
+ "preview": "vite preview",
25
+ "prepublishOnly": "npm run build"
26
+ },
27
+ "peerDependencies": {
28
+ "vue": "^3.3.0"
29
+ },
30
+ "devDependencies": {
31
+ "@vitejs/plugin-vue": "^4.5.0",
32
+ "typescript": "^5.9.3",
33
+ "vite": "^4.5.0",
34
+ "vue": "^3.3.0"
35
+ },
36
+ "keywords": [
37
+ "vue",
38
+ "components",
39
+ "ui",
40
+ "profile",
41
+ "admisi",
42
+ "siakad"
43
+ ],
44
+ "author": "Your Name",
45
+ "license": "MIT",
46
+ "dependencies": {
47
+ "axios": "^1.13.2",
48
+ "dotenv": "^17.2.3",
49
+ "sweetalert2": "^11.26.17",
50
+ "vue-select": "^3.20.4",
51
+ "vue2-datepicker": "^3.11.1"
52
+ }
53
+ }
@@ -0,0 +1,126 @@
1
+ <template>
2
+ <div v-if="value" class="modal fade show d-block" tabindex="-1" style="background: rgba(0,0,0,0.5);">
3
+ <div class="modal-dialog modal-dialog-scrollable modal-lg">
4
+ <div class="modal-content">
5
+ <div class="modal-header">
6
+ <h5 class="modal-title">
7
+ {{ isEdit ? 'Edit' : 'Tambah' }} Pendidikan
8
+ </h5>
9
+ <button @click="close" type="button" class="btn-close"></button>
10
+ </div>
11
+ <div class="modal-body">
12
+ <div class="row g-3">
13
+ <div class="col-12">
14
+ <label class="form-label fw-semibold">Nomor Induk (NISN)</label>
15
+ <input v-model="formData.nisn" type="text" class="form-control" placeholder="NISN" />
16
+ </div>
17
+ <div class="col-12">
18
+ <label class="form-label fw-semibold">Asal Sekolah</label>
19
+ <input v-model="formData.previous_school" type="text" class="form-control" placeholder="Asal Sekolah" />
20
+ </div>
21
+ <div class="col-12">
22
+ <label class="form-label fw-semibold">Nilai rata-rata rapot kelas XII Semester I</label>
23
+ <input v-model="formData.score" type="number" class="form-control" :min="0" :max="100"
24
+ placeholder="Nilai Rata-rata rapot kelas XII Semester I" />
25
+ </div>
26
+ <div class="col-12">
27
+ <label class="form-label fw-semibold">Jurusan</label>
28
+ <input v-model="formData.major" type="text" class="form-control" placeholder="Jurusan" />
29
+ </div>
30
+ <div class="col-12">
31
+ <label class="form-label fw-semibold">Tahun Lulus</label>
32
+ <input v-model="formData.year_graduated" type="number" class="form-control" placeholder="Tahun Lulus" />
33
+ </div>
34
+ </div>
35
+ </div>
36
+ <div class="modal-footer">
37
+ <button @click="save" type="button" class="btn btn-primary rounded-pill px-4">
38
+ Simpan
39
+ </button>
40
+ <button @click="close" type="button" class="btn btn-outline-secondary rounded-pill px-4">
41
+ Batal
42
+ </button>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </template>
48
+
49
+ <script>
50
+ import { addEducation } from '../api/profileApi';
51
+ import { showToast } from '../utils/toast';
52
+
53
+ export default {
54
+ name: 'EducationModal',
55
+ props: {
56
+ value: {
57
+ type: Boolean,
58
+ default: false
59
+ },
60
+ education: {
61
+ type: Object,
62
+ default: null
63
+ }
64
+ },
65
+ data() {
66
+ return {
67
+ formData: {
68
+ }
69
+ };
70
+ },
71
+ computed: {
72
+ isEdit() {
73
+ return !!this.education;
74
+ }
75
+ },
76
+ watch: {
77
+ value(newVal) {
78
+ if (newVal) {
79
+ if (this.education) {
80
+ this.formData = { ...this.education };
81
+ } else {
82
+ this.resetForm();
83
+ }
84
+ }
85
+ }
86
+ },
87
+ methods: {
88
+ resetForm() {
89
+ this.formData = {
90
+
91
+ };
92
+ },
93
+ async save() {
94
+ try {
95
+ await addEducation(this.formData);
96
+ showToast({
97
+ icon: 'success',
98
+ title: 'Success',
99
+ text: 'Data pendidikan berhasil disimpan.'
100
+ });
101
+ this.$emit('save');
102
+ this.close();
103
+ if (this.$route.query.r) {
104
+ this.$router.push(this.$route.query.r);
105
+ }
106
+ } catch (error) {
107
+ showToast({
108
+ icon: 'error',
109
+ title: 'Error',
110
+ text: 'Gagal menyimpan data: ' + error.response?.data?.user_message
111
+ });
112
+ }
113
+ },
114
+ close() {
115
+ this.resetForm();
116
+ this.$emit('input', false);
117
+ }
118
+ }
119
+ };
120
+ </script>
121
+
122
+ <style scoped>
123
+ .modal.show {
124
+ display: block;
125
+ }
126
+ </style>
@@ -0,0 +1,70 @@
1
+ <template>
2
+ <div v-if="value" class="modal fade show d-block modal-lg" tabindex="-1" style="background: rgba(0,0,0,0.5);">
3
+ <div class="modal-dialog modal-dialog-centered modal-cropper">
4
+ <div class="modal-content">
5
+ <div class="modal-header">
6
+ <h5 class="modal-title">Foto Profil</h5>
7
+ <button type="button" class="btn-close" @click="close" aria-label="Close"></button>
8
+ </div>
9
+ <div class="modal-body">
10
+ <SgFileUploader v-model="localPhoto" />
11
+ </div>
12
+ <div class="modal-footer">
13
+ <button @click="save" type="button" class="btn btn-primary rounded-pill px-4">
14
+ Simpan
15
+ </button>
16
+ <button @click="close" type="button" class="btn btn-outline-secondary rounded-pill px-4">
17
+ Batal
18
+ </button>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ </template>
24
+
25
+ <script>
26
+ import SgFileUploader from '../components/SgFileUploader.vue';
27
+
28
+ export default {
29
+ name: 'ImageCropModal',
30
+ components: {
31
+ SgFileUploader
32
+ },
33
+ props: {
34
+ value: {
35
+ type: Boolean,
36
+ default: false
37
+ },
38
+ photo: {
39
+ type: Object,
40
+ default: null
41
+ }
42
+ },
43
+ data() {
44
+ return {
45
+ localPhoto: null
46
+ };
47
+ },
48
+ watch: {
49
+ value(newVal) {
50
+ if (newVal) {
51
+ this.localPhoto = this.photo;
52
+ }
53
+ }
54
+ },
55
+ methods: {
56
+ save() {
57
+ this.$emit('save', this.localPhoto);
58
+ },
59
+ close() {
60
+ this.$emit('input', false);
61
+ }
62
+ }
63
+ };
64
+ </script>
65
+
66
+ <style scoped>
67
+ .modal.show {
68
+ display: block;
69
+ }
70
+ </style>
@@ -0,0 +1,166 @@
1
+ <template>
2
+ <div v-if="value" class="modal fade show d-block" tabindex="-1" style="background: rgba(0,0,0,0.5);">
3
+ <div class="modal-dialog modal-dialog-centered">
4
+ <div class="modal-content">
5
+ <div class="modal-header">
6
+ <h5 class="modal-title">
7
+ Verifikasi {{ verificationType === 'email' ? 'Email' : 'Nomor Telepon' }}
8
+ </h5>
9
+ <button @click="close" type="button" class="btn-close"></button>
10
+ </div>
11
+ <div class="modal-body">
12
+ <div class="text-center mb-4">
13
+ <div class="mb-3">
14
+ <i :class="verificationType === 'email' ? 'uil uil-envelope' : 'uil uil-phone'" class="text-primary"
15
+ style="font-size: 64px;"></i>
16
+ </div>
17
+
18
+ <div v-if="verificationType === 'phone'" class="mb-3">
19
+ <label for="phone" class="form-label">Nomor Telepon</label>
20
+ <input type="text" class="form-control" id="phone" :value="formattedPhone" @input="onPhoneInput"
21
+ placeholder="0812 3456 7890" :class="{ 'is-invalid': phoneError }" />
22
+ <div v-if="phoneError" class="invalid-feedback">
23
+ {{ phoneError }}
24
+ </div>
25
+ </div>
26
+
27
+ <p class="text-muted">
28
+ {{ verificationType === 'email'
29
+ ? 'Link verifikasi akan dikirim ke ' + email
30
+ : 'Pesan verifikasi akan dikirim ke ' + phone
31
+ }}
32
+ </p>
33
+ </div>
34
+ <button @click="sendOtp" class="btn btn-primary w-100" :disabled="isButtonDisabled">
35
+ <span v-if="sendingOtp" class="spinner-border spinner-border-sm me-2"></span>
36
+ {{ sendingOtp ? 'Mengirim...' :
37
+ (verificationType === 'email' ? 'Kirim Link Verifikasi' : 'Verifikasi Whatsapp')
38
+ }}
39
+ </button>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </template>
45
+
46
+ <script>
47
+ import { sendEmailOtp, sendPhoneOtp } from '../api/profileApi';
48
+ import { showToast } from '../utils/toast';
49
+ import Swal from 'sweetalert2';
50
+
51
+ export default {
52
+ name: 'OtpModal',
53
+ props: {
54
+ value: {
55
+ type: Boolean,
56
+ default: false
57
+ },
58
+ verificationType: {
59
+ type: String,
60
+ required: true
61
+ },
62
+ email: {
63
+ type: String,
64
+ default: ''
65
+ }
66
+ },
67
+ data() {
68
+ return {
69
+ phone: '',
70
+ phoneError: '',
71
+ sendingOtp: false
72
+ };
73
+ },
74
+ computed: {
75
+ formattedPhone() {
76
+ if (!this.phone) return '';
77
+ // Format: 0812 3456 7890 (pisah tiap 4 digit)
78
+ return this.phone.replace(/(\d{4})(?=\d)/g, '$1 ');
79
+ },
80
+ isButtonDisabled() {
81
+ if (this.verificationType === 'email') {
82
+ return this.sendingOtp;
83
+ }
84
+ // Untuk phone: disabled jika sedang mengirim atau ada error atau nomor kosong
85
+ return this.sendingOtp || !!this.phoneError || !this.phone;
86
+ }
87
+ },
88
+ methods: {
89
+ onPhoneInput(e) {
90
+ // Ambil hanya angka
91
+ let raw = e.target.value.replace(/\D/g, '');
92
+ this.phone = raw;
93
+ this.validatePhone();
94
+ },
95
+ validatePhone() {
96
+ if (!this.phone) {
97
+ this.phoneError = 'Nomor telepon tidak boleh kosong';
98
+ } else if (!this.phone.startsWith('0')) {
99
+ this.phoneError = 'Nomor telepon harus diawali angka 0';
100
+ } else if (this.phone.length < 9) {
101
+ this.phoneError = 'Nomor telepon minimal 9 digit';
102
+ } else {
103
+ this.phoneError = '';
104
+ }
105
+ },
106
+ async sendOtp() {
107
+ this.sendingOtp = true;
108
+
109
+ try {
110
+ let data = {};
111
+ let endpoint = '';
112
+
113
+ if (this.verificationType === 'email') {
114
+ await sendEmailOtp(this.email);
115
+ showToast({
116
+ icon: 'success',
117
+ title: 'Berhasil',
118
+ text: 'Link verifikasi telah dikirim ke email Anda'
119
+ });
120
+ this.$emit('verified');
121
+ this.close();
122
+ } else {
123
+ const result = await Swal.fire({
124
+ text: 'Pastikan nomor yang ditulis sesuai dengan nomor WhatsApp yang aktif: ' + this.phone,
125
+ icon: 'question',
126
+ showCancelButton: true,
127
+ confirmButtonText: 'Kirim',
128
+ cancelButtonText: 'Batal'
129
+ });
130
+
131
+ if (result.isConfirmed) {
132
+ const res = await sendPhoneOtp(this.phone);
133
+ const url = res.data.data.wa_url;
134
+ const newTab = window.open(url, '_blank');
135
+ if (newTab) {
136
+ newTab.opener = window;
137
+ }
138
+ this.$emit('verified');
139
+ this.close();
140
+ }
141
+ }
142
+ } catch (error) {
143
+ const errorMessage = error.response?.data?.user_message || 'Gagal melakukan verifikasi';
144
+ showToast({
145
+ icon: 'error',
146
+ title: 'Error',
147
+ text: errorMessage
148
+ });
149
+ } finally {
150
+ this.sendingOtp = false;
151
+ }
152
+ },
153
+ close() {
154
+ this.phone = '';
155
+ this.phoneError = '';
156
+ this.$emit('input', false);
157
+ }
158
+ }
159
+ };
160
+ </script>
161
+
162
+ <style scoped>
163
+ .modal.show {
164
+ display: block;
165
+ }
166
+ </style>