add meeting page and add meetPopUp

This commit is contained in:
Diyar Akhgar 2025-05-23 02:42:10 +03:30
parent 19712a3c1c
commit e19ec16eb1
9 changed files with 1879 additions and 15 deletions

View File

@ -13,11 +13,14 @@
"@videojs/themes": "^1.0.1",
"axios": "^1.8.4",
"core-js": "^3.8.3",
"moment-jalaali": "^0.10.4",
"video.js": "^7.21.7",
"vue": "^3.2.13",
"vue-pdf-embed": "^2.1.2",
"vue-persian-datetime-picker": "^2.10.4",
"vue-router": "^4.5.0",
"vue-video-player": "^6.0.0",
"vue3-persian-datetime-picker": "^1.2.2",
"vue3-video-player": "^1.0.0"
},
"devDependencies": {
@ -32,6 +35,8 @@
"postcss": "^8.5.3",
"postcss-loader": "^8.1.1",
"postcss-preset-env": "^10.1.6",
"sass": "^1.89.0",
"sass-loader": "^16.0.5",
"tailwindcss": "^4.1.3"
}
},
@ -3374,6 +3379,316 @@
"node": ">= 8"
}
},
"node_modules/@parcel/watcher": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
"integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"dependencies": {
"detect-libc": "^1.0.3",
"is-glob": "^4.0.3",
"micromatch": "^4.0.5",
"node-addon-api": "^7.0.0"
},
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"optionalDependencies": {
"@parcel/watcher-android-arm64": "2.5.1",
"@parcel/watcher-darwin-arm64": "2.5.1",
"@parcel/watcher-darwin-x64": "2.5.1",
"@parcel/watcher-freebsd-x64": "2.5.1",
"@parcel/watcher-linux-arm-glibc": "2.5.1",
"@parcel/watcher-linux-arm-musl": "2.5.1",
"@parcel/watcher-linux-arm64-glibc": "2.5.1",
"@parcel/watcher-linux-arm64-musl": "2.5.1",
"@parcel/watcher-linux-x64-glibc": "2.5.1",
"@parcel/watcher-linux-x64-musl": "2.5.1",
"@parcel/watcher-win32-arm64": "2.5.1",
"@parcel/watcher-win32-ia32": "2.5.1",
"@parcel/watcher-win32-x64": "2.5.1"
}
},
"node_modules/@parcel/watcher-android-arm64": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
"integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-darwin-arm64": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
"integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-darwin-x64": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
"integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-freebsd-x64": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
"integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm-glibc": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
"integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm-musl": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
"integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm64-glibc": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
"integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm64-musl": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
"integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-x64-glibc": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
"integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-x64-musl": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
"integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-win32-arm64": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
"integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-win32-ia32": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
"integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-win32-x64": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
"integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@polka/url": {
"version": "1.0.0-next.29",
"resolved": "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.29.tgz",
@ -5172,7 +5487,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"license": "MIT"
},
"node_modules/base64-js": {
@ -5308,7 +5622,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@ -5842,7 +6155,6 @@
"version": "0.0.1",
"resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true,
"license": "MIT"
},
"node_modules/connect-history-api-fallback": {
@ -6795,6 +7107,20 @@
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/detect-libc": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
"dev": true,
"license": "Apache-2.0",
"optional": true,
"bin": {
"detect-libc": "bin/detect-libc.js"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/detect-node": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/detect-node/-/detect-node-2.1.0.tgz",
@ -8198,7 +8524,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true,
"license": "ISC"
},
"node_modules/fsevents": {
@ -8307,7 +8632,6 @@
"resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"dev": true,
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
@ -8832,6 +9156,13 @@
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
"license": "MIT"
},
"node_modules/immutable": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.2.tgz",
"integrity": "sha512-qHKXW1q6liAk1Oys6umoaZbDRqjcjgSrbnrifHsfsttza7zcvRAsL7mMV6xWcyhwQy7Xj5v4hhbr6b+iDYwlmQ==",
"dev": true,
"license": "MIT"
},
"node_modules/import-fresh": {
"version": "3.3.1",
"resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz",
@ -8869,7 +9200,6 @@
"resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"dev": true,
"license": "ISC",
"dependencies": {
"once": "^1.3.0",
@ -9118,6 +9448,12 @@
"node": ">=0.10.0"
}
},
"node_modules/jalaali-js": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/jalaali-js/-/jalaali-js-1.2.8.tgz",
"integrity": "sha512-Jl/EwY84JwjW2wsWqeU4pNd22VNQ7EkjI36bDuLw31wH98WQW4fPjD0+mG7cdCK+Y8D6s9R3zLiQ3LaKu6bD8A==",
"license": "MIT"
},
"node_modules/javascript-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz",
@ -9984,7 +10320,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
@ -10030,6 +10365,38 @@
"dev": true,
"license": "MIT"
},
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/moment-jalaali": {
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/moment-jalaali/-/moment-jalaali-0.10.4.tgz",
"integrity": "sha512-/eD0HeyvATznb5iE0G1BHjKRZAFEpJ9ZNUkcHwXhNgt1WJJVVzHD7+uDmqzZWVFLdbGme2gvIXKb3ezDYOXcZA==",
"license": "MIT",
"dependencies": {
"jalaali-js": "^1.2.7",
"moment": "^2.29.4",
"moment-timezone": "^0.5.46"
}
},
"node_modules/moment-timezone": {
"version": "0.5.48",
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz",
"integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==",
"license": "MIT",
"dependencies": {
"moment": "^2.29.4"
},
"engines": {
"node": "*"
}
},
"node_modules/mpd-parser": {
"version": "0.22.1",
"resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz",
@ -10165,6 +10532,14 @@
"tslib": "^2.0.3"
}
},
"node_modules/node-addon-api": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
"dev": true,
"license": "MIT",
"optional": true
},
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz",
@ -10373,7 +10748,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"license": "ISC",
"dependencies": {
"wrappy": "1"
@ -10647,7 +11021,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@ -12938,7 +13311,6 @@
"resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"deprecated": "Rimraf versions prior to v4 are no longer supported",
"dev": true,
"license": "ISC",
"dependencies": {
"glob": "^7.1.3"
@ -13018,6 +13390,98 @@
"dev": true,
"license": "MIT"
},
"node_modules/sass": {
"version": "1.89.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.89.0.tgz",
"integrity": "sha512-ld+kQU8YTdGNjOLfRWBzewJpU5cwEv/h5yyqlSeJcj6Yh8U4TDA9UA5FPicqDz/xgRPWRSYIQNiFks21TbA9KQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"chokidar": "^4.0.0",
"immutable": "^5.0.2",
"source-map-js": ">=0.6.2 <2.0.0"
},
"bin": {
"sass": "sass.js"
},
"engines": {
"node": ">=14.0.0"
},
"optionalDependencies": {
"@parcel/watcher": "^2.4.1"
}
},
"node_modules/sass-loader": {
"version": "16.0.5",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.5.tgz",
"integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==",
"dev": true,
"license": "MIT",
"dependencies": {
"neo-async": "^2.6.2"
},
"engines": {
"node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"@rspack/core": "0.x || 1.x",
"node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
"sass": "^1.3.0",
"sass-embedded": "*",
"webpack": "^5.0.0"
},
"peerDependenciesMeta": {
"@rspack/core": {
"optional": true
},
"node-sass": {
"optional": true
},
"sass": {
"optional": true
},
"sass-embedded": {
"optional": true
},
"webpack": {
"optional": true
}
}
},
"node_modules/sass/node_modules/chokidar": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
"dev": true,
"license": "MIT",
"dependencies": {
"readdirp": "^4.0.1"
},
"engines": {
"node": ">= 14.16.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/sass/node_modules/readdirp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 14.18.0"
},
"funding": {
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/schema-utils": {
"version": "2.7.1",
"resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-2.7.1.tgz",
@ -14500,6 +14964,27 @@
"vue": "^3.3.0"
}
},
"node_modules/vue-persian-datetime-picker": {
"version": "2.10.4",
"resolved": "https://registry.npmjs.org/vue-persian-datetime-picker/-/vue-persian-datetime-picker-2.10.4.tgz",
"integrity": "sha512-q/yyV15iDJE3diE7C+e6aF7EOMplze41V3UAFbvMgMiLzt/wDqD0OomgghKVhK6aJDUO7uW4q76Ihc7qntlorg==",
"license": "MIT",
"dependencies": {
"moment-jalaali": "^0.9.2"
}
},
"node_modules/vue-persian-datetime-picker/node_modules/moment-jalaali": {
"version": "0.9.6",
"resolved": "https://registry.npmjs.org/moment-jalaali/-/moment-jalaali-0.9.6.tgz",
"integrity": "sha512-v8wXjQplvk5ez+sUqgsWIrafwIf1BEXXvzTYwsg1wHcqh27nSgKPCJ6FnZRrCz03MoNyB9N31L0oms+vE8Rq7g==",
"license": "MIT",
"dependencies": {
"jalaali-js": "^1.1.0",
"moment": "^2.22.2",
"moment-timezone": "^0.5.21",
"rimraf": "^3.0.2"
}
},
"node_modules/vue-router": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.0.tgz",
@ -14554,6 +15039,27 @@
"vue": "3.x"
}
},
"node_modules/vue3-persian-datetime-picker": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/vue3-persian-datetime-picker/-/vue3-persian-datetime-picker-1.2.2.tgz",
"integrity": "sha512-d7nkj5vgtUvEXZboSdRmP1uwBfXvXgXqdvsOOMQb34jiMZU/aBDrTYWTEe1N+XKF9pvTTJn8Rws9ttJmyhK/hw==",
"license": "MIT",
"dependencies": {
"moment-jalaali": "^0.9.4"
}
},
"node_modules/vue3-persian-datetime-picker/node_modules/moment-jalaali": {
"version": "0.9.6",
"resolved": "https://registry.npmjs.org/moment-jalaali/-/moment-jalaali-0.9.6.tgz",
"integrity": "sha512-v8wXjQplvk5ez+sUqgsWIrafwIf1BEXXvzTYwsg1wHcqh27nSgKPCJ6FnZRrCz03MoNyB9N31L0oms+vE8Rq7g==",
"license": "MIT",
"dependencies": {
"jalaali-js": "^1.1.0",
"moment": "^2.22.2",
"moment-timezone": "^0.5.21",
"rimraf": "^3.0.2"
}
},
"node_modules/vue3-video-player": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/vue3-video-player/-/vue3-video-player-1.0.0.tgz",
@ -15117,7 +15623,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true,
"license": "ISC"
},
"node_modules/ws": {

View File

@ -13,11 +13,14 @@
"@videojs/themes": "^1.0.1",
"axios": "^1.8.4",
"core-js": "^3.8.3",
"moment-jalaali": "^0.10.4",
"video.js": "^7.21.7",
"vue": "^3.2.13",
"vue-pdf-embed": "^2.1.2",
"vue-persian-datetime-picker": "^2.10.4",
"vue-router": "^4.5.0",
"vue-video-player": "^6.0.0",
"vue3-persian-datetime-picker": "^1.2.2",
"vue3-video-player": "^1.0.0"
},
"devDependencies": {
@ -32,6 +35,8 @@
"postcss": "^8.5.3",
"postcss-loader": "^8.1.1",
"postcss-preset-env": "^10.1.6",
"sass": "^1.89.0",
"sass-loader": "^16.0.5",
"tailwindcss": "^4.1.3"
},
"eslintConfig": {
@ -46,7 +51,9 @@
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {}
"rules": {
"vue/multi-word-component-names": "off"
}
},
"browserslist": [
"> 1%",

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1,900 @@
<template>
<div v-if="isOpen" class="modal-overlay" @click="closeModal">
<div class="modal-content" @click.stop>
<div class="popUp-header">
<h2>ایجاد جلسه جدید</h2>
<button @click="closeModal">
<svg
xmlns="http://www.w3.org/2000/svg"
width="35"
height="35"
viewBox="0 0 32 32"
fill="none"
>
<rect x="0.5" y="0.5" width="31" height="31" rx="7.5" fill="#101010" />
<rect x="0.5" y="0.5" width="31" height="31" rx="7.5" stroke="#E2DEE9" />
<path
d="M21 11L11 21"
stroke="white"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M11 11L21 21"
stroke="white"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</div>
<div class="popUp-title">
<h2>جزئیات جلسه</h2>
<span>برای ایجاد جلسه جدید فرم زیر را تکمیل نمایید.</span>
</div>
<div class="popUp-objects">
<form @submit.prevent="handleSubmit">
<div class="form-group">
<label for="meetingTitle">نام جلسه</label>
<input
type="text"
id="meetingTitle"
v-model="form.title"
required
/>
</div>
<div class="form-group">
<label for="meet-description">شرح جلسه</label>
<textarea
name="meet-description"
id="meet-description"
v-model="form.description"
></textarea>
</div>
<div class="form-group">
<label for="meetingDate">روز</label>
<div class="input-group">
<span style="position: absolute; z-index: 1; top: 10px; right: 32%;">
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 16 16"
fill="none"
>
<g clip-path="url(#clip0_312_7390)">
<path
d="M14.1147 4.54126C14.4671 4.18888 14.6652 3.71091 14.6652 3.2125C14.6653 2.71409 14.4674 2.23607 14.115 1.8836C13.7626 1.53112 13.2846 1.33307 12.7862 1.33301C12.2878 1.33295 11.8098 1.53088 11.4573 1.88326L2.55999 10.7826C2.4052 10.9369 2.29073 11.127 2.22665 11.3359L1.34599 14.2373C1.32876 14.2949 1.32746 14.3562 1.34222 14.4145C1.35699 14.4728 1.38727 14.5261 1.42985 14.5686C1.47244 14.6111 1.52573 14.6413 1.58409 14.656C1.64245 14.6707 1.70369 14.6693 1.76132 14.6519L4.66332 13.7719C4.8721 13.7084 5.0621 13.5947 5.21665 13.4406L14.1147 4.54126Z"
stroke="#3A57E8"
stroke-width="1.25"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M10 3.33337L12.6667 6.00004"
stroke="#3A57E8"
stroke-width="1.25"
stroke-linecap="round"
stroke-linejoin="round"
/>
</g>
<defs>
<clipPath id="clip0_312_7390">
<rect width="16" height="16" fill="white" />
</clipPath>
</defs>
</svg>
</span>
<VuePersianDatetimePicker
v-model="form.date"
type="date"
format="jYYYY/jMM/jDD"
locale="fa"
:auto-submit="true"
input-class="form-control"
id="meetingDate"
required
style="border-radius: 0 8px 8px 0; text-align: center; position: relative;"
/>
</div>
</div>
<div class="form-group">
<label for="meetingTime">ساعت</label>
<div class="input-group">
<div class="time-input-group">
<p style="margin-left: 1rem;">شروع</p>
<div class="input-div">
<button type="button" @click="incrementTime('startMinute')">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 20 20"
fill="none"
>
<path
d="M15 12.5L10 7.5L5 12.5"
stroke="#3A57E8"
stroke-width="2"
stroke-linecap prištede="round"
stroke-linejoin="round"
/>
</svg>
</button>
<input
type="number"
v-model.number="form.startMinute"
min="0"
max="59"
required
/>
<button type="button" @click="decrementTime('startMinute')">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 20 20"
fill="none"
>
<path
d="M5 7.5L10 12.5L15 7.5"
stroke="#3A57E8"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</div>
<span>:</span>
<div class="input-div">
<button type="button" @click="incrementTime('startHour')">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 20 20"
fill="none"
>
<path
d="M15 12.5L10 7.5L5 12.5"
stroke="#3A57E8"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
<input
type="number"
v-model.number="form.startHour"
min="0"
max="24"
required
/>
<button type="button" @click="decrementTime('startHour')">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 20 20"
fill="none"
>
<path
d="M5 7.5L10 12.5L15 7.5"
stroke="#3A57E8"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</div>
<p style="margin-left: 1rem; margin-right: 2.5rem;">پایان</p>
<div class="input-div">
<button type="button" @click="incrementTime('endMinute')">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 20 20"
fill="none"
>
<path
d="M15 12.5L10 7.5L5 12.5"
stroke="#3A57E8"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
<input
type="number"
v-model.number="form.endMinute"
min="0"
max="59"
required
/>
<button type="button" @click="decrementTime('endMinute')">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 20 20"
fill="none"
>
<path
d="M5 7.5L10 12.5L15 7.5"
stroke="#3A57E8"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</div>
<span>:</span>
<div class="input-div">
<button type="button" @click="incrementTime('endHour')">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 20 20"
fill="none"
>
<path
d="M15 12.5L10 7.5L5 12.5"
stroke="#3A57E8"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
<input
type="number"
v-model.number="form.endHour"
min="0"
max="24"
required
/>
<button type="button" @click="decrementTime('endHour')">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 20 20"
fill="none"
>
<path
d="M5 7.5L10 12.5L15 7.5"
stroke="#3A57E8"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</div>
</div>
</div>
</div>
<div class="form-group">
<label style="font-size: 19px;font-weight: 600;">اتاق های جلسات</label>
<div class="rooms-selecter">
<span>0 انتخاب شده</span>
<button type="button" @click="openRoomSelection">انتخاب اتاق جلسه</button>
</div>
</div>
<div class="participants-objects">
<h2>شرکت کنندگان</h2>
<p><span style="color: #101010;font-weight: 600;">کاربران</span> یا <span style="color: #101010;font-weight: 600;">مهمانان تیم</span> را با پر کردن آدرس ایمیل آنها دعوت کنید.</p>
<span class="participants-guide">
میتوانید به مجری اجازه بدهید تا ابزارهایی برای مدیریت این جلسه و همچنین ابزارهایی برای مدیریت مجوزها در طول جلسه به او بدهد.
</span>
</div>
<div class="presenter">
<div style="display: flex;align-items: center;height: 100%;">
<div class="avatar-wrapper">
<img class="user-avatar" :src="profileIcon" />
</div>
<div class="user-info">
<p class="user-name">{{ fullName }}</p>
<span>{{ userEmail || 'ایمیل موجود نیست' }}</span>
</div>
</div>
<p class="presenter-role">{{ userRole }}</p>
</div>
<div class="presenter" v-for="participant in participants" :key="participant.email">
<div style="display: flex;align-items: center;height: 100%;">
<div class="avatar-wrapper">
<img class="user-avatar" :src="participant.profile_img || defaultProfileIcon" />
</div>
<div class="user-info">
<p class="user-name">{{ participant.name || 'کاربر مهمان' }}</p>
<span>{{ participant.email }}</span>
</div>
</div>
<p class="presenter-role">{{ participant.role }}</p>
<button @click="removeParticipant(participant.email)">
<svg xmlns="http://www.w3.org/2000/svg" width="35" height="35" viewBox="0 0 32 32" fill="none">
<rect x="0.5" y="0.5" width="31" height="31" rx="7.5" fill="white"/>
<rect x="0.5" y="0.5" width="31" height="31" rx="7.5" stroke="#E2DEE9"/>
<path d="M20.5 12L12.5 20" stroke="#101010" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12.5 12L20.5 20" stroke="#101010" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
</div>
<div class="form-group">
<label for="participantEmail">اضافه کردن شرکت کننده</label>
<div class="participant-input">
<input
type="email"
id="participantEmail"
v-model="newParticipantEmail"
placeholder="لطفا ایمیل شرکت کننده را وارد کنید ..."
@keyup.enter="addParticipant"
/>
<button type="button" @click="addParticipant">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 16 16" fill="none">
<path d="M3.33203 8H12.6654" stroke="#3A57E8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8 3.33325V12.6666" stroke="#3A57E8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
</div>
</div>
</form>
<span class="last-span">
شرکت کنندگان را اضافه کنید برای شرکت کنندگانی که به این جلسه اضافه شده اند ایمیلی حاوی کد جلسه، عنوان، توضیحات و زمان ارسال می شود.
</span>
</div>
<div class="form-actions">
<button type="button" class="cancel-button" @click="closeModal">بازگشت</button>
<button type="button" class="submit-button" @click="handleSubmit">ایجاد جلسه</button>
</div>
</div>
</div>
</template>
<script>
import VuePersianDatetimePicker from 'vue3-persian-datetime-picker';
import moment from 'moment-jalaali';
export default {
name: 'MeetingModal',
components: {
VuePersianDatetimePicker,
},
props: {
isOpen: {
type: Boolean,
default: false,
},
},
data() {
return {
form: {
title: '',
description: '',
date: moment().format('jYYYY/jMM/jDD'),
startHour: 12,
startMinute: 0,
endHour: 18,
endMinute: 0,
},
participants: [],
newParticipantEmail: '',
defaultProfileIcon: 'https://c.animaapp.com/m9nvumalUMfQbN/img/frame.svg',
error: null,
};
},
computed: {
fullName() {
const user = JSON.parse(localStorage.getItem('user') || '{}');
return user.first_name && user.last_name
? `${user.first_name} ${user.last_name}`
: 'کاربر مهمان';
},
userEmail() {
return 'diyar.akhgar@gmail.com';
},
userRole() {
return 'مجری';
},
profileIcon() {
const customer = JSON.parse(localStorage.getItem('customer') || '{}');
return customer.profile_img || this.defaultProfileIcon;
},
},
methods: {
openRoomSelection() {
this.$emit('open-room-selection');
},
addParticipant() {
if (!this.newParticipantEmail || !this.validateEmail(this.newParticipantEmail)) {
this.error = 'لطفاً ایمیل معتبر وارد کنید';
return;
}
if (this.participants.some(p => p.email === this.newParticipantEmail) || this.newParticipantEmail === this.userEmail) {
this.error = 'این ایمیل قبلاً اضافه شده است';
return;
}
this.participants.push({
email: this.newParticipantEmail,
name: 'کاربر مهمان',
role: 'شرکت‌کننده',
profile_img: this.defaultProfileIcon,
});
this.newParticipantEmail = '';
this.error = null;
},
removeParticipant(email) {
this.participants = this.participants.filter(p => p.email !== email);
},
validateEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
},
closeModal() {
this.$emit('close');
this.resetForm();
},
resetForm() {
this.form = {
title: '',
description: '',
date: moment().format('jYYYY/jMM/jDD'),
startHour: 12,
startMinute: 0,
endHour: 18,
endMinute: 0,
};
this.participants = [];
this.newParticipantEmail = '';
this.error = null;
},
incrementTime(field) {
if (field === 'startHour' && this.form.startHour < 23) {
this.form.startHour++;
} else if (field === 'startMinute' && this.form.startMinute < 59) {
this.form.startMinute++;
} else if (field === 'endHour' && this.form.endHour < 23) {
this.form.endHour++;
} else if (field === 'endMinute' && this.form.endMinute < 59) {
this.form.endMinute++;
}
},
decrementTime(field) {
if (field === 'startHour' && this.form.startHour > 0) {
this.form.startHour--;
} else if (field === 'startMinute' && this.form.startMinute > 0) {
this.form.startMinute--;
} else if (field === 'endHour' && this.form.endHour > 0) {
this.form.endHour--;
} else if (field === 'endMinute' && this.form.endMinute > 0) {
this.form.endMinute--;
}
},
handleSubmit() {
if (!this.form.title || !this.form.date) {
this.error = 'لطفاً نام جلسه و تاریخ را وارد کنید.';
return;
}
const momentDate = moment(this.form.date, 'jYYYY/jMM/jDD');
if (!momentDate.isValid()) {
this.error = 'تاریخ وارد شده معتبر نیست.';
return;
}
const startTimeInMinutes = this.form.startHour * 60 + this.form.startMinute;
const endTimeInMinutes = this.form.endHour * 60 + this.form.endMinute;
if (endTimeInMinutes <= startTimeInMinutes) {
this.error = 'زمان پایان باید بعد از زمان شروع باشد.';
return;
}
const startDateTime = momentDate
.clone()
.set({
hour: this.form.startHour,
minute: this.form.startMinute,
second: 0,
})
.toISOString();
const endDateTime = momentDate
.clone()
.set({
hour: this.form.endHour,
minute: this.form.endMinute,
second: 0,
})
.toISOString();
const meetingData = {
title: this.form.title,
description: this.form.description,
startDateTime,
endDateTime,
participants: [
...(this.userEmail ? [{ email: this.userEmail, role: this.userRole }] : []),
...this.participants.map(p => ({
email: p.email,
role: p.role,
})),
],
};
console.log('داده‌های جلسه:', meetingData);
this.$emit('submit', meetingData);
this.closeModal();
},
},
};
</script>
<style scoped>
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-content {
background: #F7F5FA;
border-radius: 8px;
width: 100%;
max-width: 700px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
direction: rtl;
border-radius: 20px;
padding-bottom: 2rem;
height: 95vh;
overflow-y: auto;
scrollbar-width: none;
-ms-overflow-style: none;
}
.modal-content::-webkit-scrollbar {
display: none;
}
.popUp-header {
display: flex;
align-items: center;
justify-content: space-between;
background-color: #101010;
color: #fff;
width: 100%;
padding: 20px 26px;
margin-bottom: 1.5rem;
border-radius: 20px 20px 0px 0px;
}
.popUp-header h2 {
font-size: 22px;
}
.popUp-header button {
background-color: #101010;
border: none;
cursor: pointer;
}
.popUp-objects {
margin-top: 1rem !important;
padding: 20px;
background-color: #FFFFFF;
border-radius: 16px;
width: 100%;
max-width: 620px;
display: block;
margin: auto;
}
.popUp-title {
display: flex;
flex-direction: column;
align-items: start;
padding: 20px;
padding-right: 50px;
}
.popUp-title h2 {
font-size: 20px;
font-weight: 600;
color: #101010;
}
.popUp-title span {
font-size: 16px;
font-weight: 500;
color: #4F5A69;
margin-top: 1rem;
}
.form-group {
margin-bottom: 3rem;
display: flex;
align-items: center;
justify-content: space-between;
}
.form-group label {
display: block;
font-weight: 500;
width: 50%;
font-size: 16px;
}
.form-group input {
height: 45px;
width: 100%;
padding: 8px;
border: 1px solid #718096;
border-radius: 8px;
font-size: 1rem;
max-width: 25rem
}
.input-group {
position: relative;
width: 100%;
}
.form-group textarea {
height: 140px;
width: 100%;
padding: 8px;
border: 1px solid #718096;
border-radius: 8px;
font-size: 1rem;
max-width: 25rem;
resize: none;
}
.form-group input:focus {
outline: none;
}
.form-group textarea:focus {
outline: none;
}
.time-input-group {
display: flex;
align-items: center;
justify-content: space-around;
}
.time-input-group input {
width: 45px;
height: 45px;
border: 1px solid #718096;
border-radius: 9px;
text-align: center;
color: #101010;
margin-bottom: 0.25rem;
}
.time-input-group input::-webkit-outer-spin-button,
.time-input-group input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.time-input-group input[type=number] {
-moz-appearance:textfield;
}
.time-input-group p {
font-size: 17px;
}
.time-input-group span {
margin: 0 0.5rem;
}
.input-div {
display: flex;
flex-direction: column;
align-items: center;
}
.input-div button {
border: none;
background-color: transparent;
margin: 0;
padding: 0;
}
.form-actions {
display: flex;
justify-content: space-between;
padding: 20px;
padding-bottom: 0;
width: 100%;
max-width: 620px;
margin: auto;
}
.submit-button,
.cancel-button {
text-align: center;
border: none;
border-radius: 8px;
cursor: pointer;
height: 50px;
width: 47%;
}
.submit-button {
background-color: #3A57E8;
color: white;
font-weight: 500;
font-size: 18px;
}
.cancel-button {
background-color: #EBEEFD;
color: #101010;
font-weight: 500;
font-size: 18px;
}
.rooms-selecter {
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
}
.rooms-selecter span {
color: #101010;
font-size: 17px;
}
.rooms-selecter button {
background-color: #3A57E8;
color: #fff;
border-radius: 8px;
border:none ;
font-size: 17px;
height: 50px;
width: 60%;
}
.participants-objects h2 {
font-weight: 600;
font-size: 19px;
color: #101010;
}
.participants-objects p {
font-weight: 500;
font-size: 16px;
color: #5A6678;
margin: 2rem 0 1.5rem 0;
}
.participants-guide {
font-size: 16px;
color: #5A6678;
line-height: 2rem;
width: 89%;
display: block;
max-width: 35rem;
}
.presenter {
margin: 2rem 0 2rem 0;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0px 1px 4px 0px #00000029;
border-radius: 12px;
height: 95px;
padding-left: 1rem;
}
.user-avatar {
width: 80px;
height: 80px;
}
.user-info {
display: flex;
flex-direction: column;
justify-content: space-around;
height: 100%;
max-height: 80px;
font-size: 18px;
}
.user-info p {
font-weight: 600;
}
.user-info span {
color: #667387;
}
.presenter-role {
font-size: 18px;
color: #101010;
font-weight: 600;
}
.presenter button {
background-color: transparent;
border:none;
height: 35px;
cursor: pointer;
}
.last-span {
color: rgb(79, 90, 105);
font-size: 16.5px;
line-height: 190%;
display: block;
margin-top: 4rem;
margin-bottom: 1rem;
}
.participant-input {
position: relative;
width: 100%;
}
.participant-input input {
width: 100%;
}
.participant-input button {
position: absolute;
left: 0;
top: 11px;
background-color: transparent;
border: none;
}
</style>
<style>
.vpd-input-group input {
height: 40px;
width: 100%;
border: 1px solid #718096;
border-radius: 8px;
font-size: 1rem;
max-width: 25rem;
text-align: center;
padding: 0;
}
.vpd-input-group label {
display: none;
}
</style>

View File

@ -98,6 +98,7 @@ export default {
}
}
</script>
<style scoped>
.header-container {
display: flex;

View File

@ -44,12 +44,12 @@
<div class="text-wrapper">فضاها</div>
</router-link>
<router-link to="/meetings" class="nav-button" :class="{ active: isActive('/meetings') }">
<router-link to="/dashboard/meetings" class="nav-button" :class="{ active: isActive('/dashboard/meetings') }">
<img class="img" src="https://c.animaapp.com/m9nvumalUMfQbN/img/menu-icon-1.svg" />
<div class="text-wrapper">جلسات</div>
</router-link>
<router-link to="/dashboard/download" class="nav-button" :class="{ active: isActive('/download') }">
<router-link to="/dashboard/download" class="nav-button" :class="{ active: isActive('/dashboard/download') }">
<img class="img" src="https://c.animaapp.com/m9nvumalUMfQbN/img/property-1-download.svg" />
<div class="text-wrapper">دانلود</div>
</router-link>
@ -132,8 +132,19 @@ export default {
direction: rtl;
display: flex;
flex-direction: column;
overflow-x: hidden;
overflow-y: auto;
/* hidden scrollbar */
scrollbar-width: none;
-ms-overflow-style: none;
}
.sidebar::-webkit-scrollbar {
display: none;
}
.group {
width: 228px;
margin-bottom: 75px;

View File

@ -0,0 +1,433 @@
<template>
<SidebarMenu />
<div class="dashboard-page">
<div class="content">
<!-- Top Header -->
<AppHeader pageTitle="جلسات" />
<!-- Description -->
<div class="section-description">
<div class="section-title">مدیریت جلسات</div>
<p class="title-description">
با استفاده از جلسات، میتوانید همکاران و کاربران خارجی XRoom را به تیم و اتاقهای خصوصی خود دعوت کنید. شرکتکنندگان جلسه شما میتوانند با استفاده از کد جلسه ایجاد شده در زمانهای معین به جلسه بپیوندند.
</p>
</div>
<!-- Meeting Section -->
<div class="meeting-section">
<div class="meeting-filters">
<div class="search-section">
<span style="font-size: 17px; font-weight: 600;">جستجو</span>
<div class="search-wrapper">
<input
type="text"
class="search-input"
placeholder="جستجو جلسه مدنظر ..."
v-model="searchQuery"
@input="filterMeetings"
/>
<button class="search-button">
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 16 16"
fill="none"
>
<path
d="M7.33333 12.6667C10.2789 12.6667 12.6667 10.2789 12.6667 7.33333C12.6667 4.38781 10.2789 2 7.33333 2C4.38781 2 2 4.38781 2 7.33333C2 10.2789 4.38781 12.6667 7.33333 12.6667Z"
stroke="#101010"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M13.9995 14L11.1328 11.1333"
stroke="#101010"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</div>
</div>
<div class="filter-section">
<span style="font-size: 17px; font-weight: 600;">فیلتر</span>
<div class="filter-buttons">
<button
:class="{ 'active-filter': activeFilter === 'future', 'disable-filter': activeFilter !== 'future' }"
@click="setFilter('future')"
>
آینده
</button>
<button
:class="{ 'active-filter': activeFilter === 'all', 'disable-filter': activeFilter !== 'all' }"
@click="setFilter('all')"
>
همه
</button>
</div>
</div>
</div>
<!-- Meet Discover -->
<div :class="filteredMeetings.length === 0 ? 'meet-discover' : 'meetings-container'">
<span class="discover-result" v-if="filteredMeetings.length === 0">
هیچ جلسهای یافت نشد. با کلیک کردن، یک جلسه جدید ایجاد کنید
</span>
<div v-else class="meetings-list">
<div v-for="meeting in filteredMeetings" :key="meeting.id" class="meeting-item">
<img :src="meeting.image" alt="Meeting Image" class="meeting-image" width="120px" height="120px" />
<div class="meeting-details" style="margin-right: 10px;">
<h3 class="meet-title">{{ meeting.title }}</h3>
<p class="meet-capacity">
<span style="margin-left: 4px;">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 16 17" fill="none">
<g clip-path="url(#clip0_622_1334)">
<path d="M3.33203 5.16667C3.33203 5.87391 3.61298 6.55219 4.11308 7.05228C4.61318 7.55238 5.29145 7.83333 5.9987 7.83333C6.70594 7.83333 7.38422 7.55238 7.88432 7.05228C8.38441 6.55219 8.66536 5.87391 8.66536 5.16667C8.66536 4.45942 8.38441 3.78115 7.88432 3.28105C7.38422 2.78095 6.70594 2.5 5.9987 2.5C5.29145 2.5 4.61318 2.78095 4.11308 3.28105C3.61298 3.78115 3.33203 4.45942 3.33203 5.16667Z" stroke="#718096" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2 14.5V13.1667C2 12.4594 2.28095 11.7811 2.78105 11.281C3.28115 10.781 3.95942 10.5 4.66667 10.5H7.33333C8.04058 10.5 8.71885 10.781 9.21895 11.281C9.71905 11.7811 10 12.4594 10 13.1667V14.5" stroke="#718096" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.668 2.58667C11.2416 2.73354 11.75 3.06714 12.1131 3.53488C12.4761 4.00262 12.6732 5.17 12.6732 5.17C12.6732 5.76212 12.4761 6.33739 12.1131 6.80513C11.75 7.27287 11.2416 7.60647 10.668 7.75334" stroke="#718096" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14 14.5V13.1666C13.9966 12.5781 13.7986 12.0072 13.4368 11.5429C13.0751 11.0786 12.5699 10.7471 12 10.6" stroke="#718096" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_622_1334">
<rect width="16" height="16" fill="white" transform="translate(0 0.5)"/>
</clipPath>
</defs>
</svg>
</span>
حداکثر: {{ meeting.maxCapacity }} کاربر
</p>
<p class="meet-type">
<span style="margin-left: 4px;">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 16 17" fill="none">
<path d="M4 15.1667V3.16671C4 2.81309 4.14048 2.47395 4.39052 2.2239C4.64057 1.97385 4.97971 1.83337 5.33333 1.83337H10.6667C11.0203 1.83337 11.3594 1.97385 11.6095 2.2239C11.8595 2.47395 12 2.81309 12 3.16671V15.1667H4Z" stroke="#3A57E8" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.9987 8.5H2.66536C2.31174 8.5 1.9726 8.64048 1.72256 8.89052C1.47251 9.14057 1.33203 9.47971 1.33203 9.83333V13.8333C1.33203 14.187 1.47251 14.5261 1.72256 14.7761C1.9726 15.0262 2.31174 15.1667 2.66536 15.1667H3.9987" stroke="#3A57E8" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 6.5H13.3333C13.687 6.5 14.0261 6.64048 14.2761 6.89052C14.5262 7.14057 14.6667 7.47971 14.6667 7.83333V13.8333C14.6667 14.187 14.5262 14.5261 14.2761 14.7761C14.0261 15.0262 13.687 15.1667 13.3333 15.1667H12" stroke="#3A57E8" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.66797 4.5H9.33464" stroke="#3A57E8" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.66797 7.16663H9.33464" stroke="#3A57E8" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.66797 9.83337H9.33464" stroke="#3A57E8" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.66797 12.5H9.33464" stroke="#3A57E8" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</span>
{{ meeting.type }}
</p>
</div>
</div>
</div>
<button
class="create-meet"
@click="showModal = true"
:style="{ width: filteredMeetings.length === 0 ? 'auto' : '191px', margin: filteredMeetings.length === 0 ? '0' : 'auto'}"
>
+ <span style="margin-right: 0.5rem;">ایجاد جلسه جدید</span>
</button>
</div>
</div>
<!-- Create Meeting Modal -->
<CreateMeetingModal
:is-open="showModal"
@create-meeting="createNewMeeting"
@close="showModal = false"
/>
</div>
</div>
</template>
<script>
import SidebarMenu from '@/components/SidebarMenu.vue';
import AppHeader from '@/components/Header.vue';
import CreateMeetingModal from '@/components/CreateMeetingModal.vue';
export default {
name: 'DashboardPage',
components: {
SidebarMenu,
AppHeader,
CreateMeetingModal,
},
data() {
return {
searchQuery: '',
activeFilter: 'future',
showModal: false,
meetings: [
{
id: 1,
title: 'Interview room',
date: '2025-05-25T10:00:00',
image: require('@/assets/img/img.png'),
type: 'فضا تیم',
maxCapacity: 33,
},
{
id: 2,
title: 'جلسه بررسی پیشرفت',
date: '2025-05-18T14:00:00',
image: require('@/assets/img/img.png'),
type: 'مدیریتی',
maxCapacity: 8,
},
{
id: 3,
title: 'جلسه تیم فنی',
date: '2025-06-01T09:00:00',
image: require('@/assets/img/img.png'),
type: 'فنی',
maxCapacity: 12,
},
],
filteredMeetings: [],
};
},
created() {
this.filterMeetings();
},
methods: {
filterMeetings() {
let filtered = this.meetings;
if (this.searchQuery) {
filtered = filtered.filter(
(meeting) =>
meeting.title.toLowerCase().includes(this.searchQuery.toLowerCase()) ||
meeting.type.toLowerCase().includes(this.searchQuery.toLowerCase())
);
}
if (this.activeFilter === 'future') {
const now = new Date();
filtered = filtered.filter((meeting) => new Date(meeting.date) > now);
}
this.filteredMeetings = filtered;
},
setFilter(filter) {
this.activeFilter = filter;
this.filterMeetings();
},
createNewMeeting(meetingData) {
const newMeeting = {
id: this.meetings.length + 1,
title: meetingData.title,
date: meetingData.date,
image: 'https://via.placeholder.com/150',
type: meetingData.type,
maxCapacity: meetingData.maxCapacity,
};
this.meetings.push(newMeeting);
this.filterMeetings();
this.showModal = false;
},
},
};
</script>
<style scoped>
.dashboard-page {
margin-right: 360px;
padding: 20px;
direction: rtl;
font-family: IRANSansXFaNum, sans-serif;
}
.content {
background-color: #f8f9fa;
border-radius: 20px;
padding: 35px 80px;
display: flex;
flex-direction: column;
gap: 32px;
}
.section-title {
font-size: 17px;
font-weight: 600;
}
.title-description {
font-size: 15px;
font-weight: 500;
margin-top: 1.5rem;
color: #4F5A69;
line-height: 190%;
max-width: 80%;
}
.meeting-section {
margin-top: 1rem;
border-radius: 10px;
}
.meeting-filters {
display: flex;
align-items: center;
margin-bottom: 2.5rem;
padding: 24px 16px;
border-radius: 10px;
background-color: #FFFFFF;
}
.search-section {
max-width: 85%;
width: 100%;
margin-left: 1.5rem;
}
.filter-section {
max-width: 15%;
width: 100%;
}
.search-wrapper {
margin-top: 1rem;
padding: 1.2px;
border-radius: 10px;
background: linear-gradient(to right, #001940, #4364F7);
position: relative;
}
.search-input {
width: 99.9%;
height: 43px;
padding: 10px;
border: none;
border-radius: 8px;
font-size: 16px;
box-sizing: border-box;
background-color: white;
display: block;
margin: 0 auto;
}
.search-input::placeholder {
color: #7F8DA1;
font-size: 14px;
font-weight: 500;
}
.search-input:focus {
outline: none;
}
.search-button {
position: absolute;
top: 50%;
left: 10px;
transform: translateY(-50%);
background: none;
border: none;
cursor: pointer;
font-size: 18px;
color: #555;
height: -webkit-fill-available;
}
.filter-buttons {
margin-top: 1rem;
}
.active-filter {
background-color: #3A57E8;
color: #FFFFFF;
font-size: 15px;
font-weight: 500;
height: 38px;
width: 51px;
border-radius: 8px;
border: none;
padding: 7px 10px;
cursor: pointer;
margin-left: 1rem;
}
.disable-filter {
color: #3A57E8;
background-color: #FFFFFF;
font-size: 15px;
font-weight: 500;
height: 38px;
width: 51px;
border-radius: 8px;
border: none;
padding: 7px 10px;
cursor: pointer;
margin-left: 1rem;
}
.meet-discover {
margin-top: 3rem;
padding-bottom: 10rem;
display: flex;
align-items: center;
justify-content: center;
}
.meetings-container {
display: flex;
flex-direction: column;
}
.discover-result {
font-size: 15px;
font-weight: 500;
color: #101010;
margin-left: 5rem;
}
.create-meet {
width: 191px;
height: 46px;
padding: 12px 24px 12px 24px;
background-color: #3A57E8;
border-radius: 8px;
font-size: 16px;
font-weight: 500;
color: #FFFFFF;
border: none;
cursor: pointer;
}
.meetings-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
margin-bottom: 2rem;
}
.meeting-item {
width: 100%;
display: flex;
align-items: center;
border: 1px solid #B8C0CB;
border-radius: 12px;
padding: 8px;
text-align: right;
}
.meet-title {
font-size: 16px;
font-weight: 500;
color: #101010;
}
.meet-capacity {
font-size: 14px;
font-weight: 500;
color: #718096;
margin: 1.2rem 0;
display: flex;
align-items: center;
}
.meet-type {
font-size: 14px;
font-weight: 500;
color: #3A57E8;
display: flex;
align-items: center;
}
</style>

View File

@ -6,7 +6,8 @@ import SmsVerification from '../pages/SmsVerification.vue'
import DashboardPage from '../pages/dashboard/index.vue'
import FilesPage from '@/pages/dashboard/files.vue';
import TeamsPage from '@/pages/dashboard/team.vue';
import DownloadPage from '@/pages/dashboard/Download.vue';
import DownloadPage from '@/pages/dashboard/Download.vue';
import MeetingPage from '@/pages/dashboard/Meeting.vue';
import axios from '@/axios';
const routes = [
@ -48,6 +49,12 @@ const routes = [
component: DownloadPage,
meta: { requiresAuth: true }
},
{
path: '/dashboard/meetings',
name: 'meetings',
component: MeetingPage,
meta: { requiresAuth: true }
},
{
path: '/dashboard/teams',
name: 'teams',