Ngiler SH3LL 360
Home
Information
Create File
Create Folder
:
/
home
/
tbf
/
tbfguest.tbf.ro
/
src
/
views
/
public
/
positions
/
Information Server
MySQL :
OFF
Perl :
OFF
CURL :
ON
WGET :
OFF
PKEXEC :
OFF
Directive
Local Value
IP Address
89.40.16.97
System
Linux server.atelieruldeit.ro 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64
User
tbf
PHP Version
7.3.33
Software
Apache
Doc root
Writable
close
Edit File :
ActivityCreate.vue
| Size :
21.61
KB
Copy
<template> <!-- Content --> <div class="relative"> <Transition enter-active-class="ease-out duration-500" enter-from-class="opacity-0" enter-to-class="opacity-100" leave-active-class="ease-in duration-200" leave-from-class="opacity-100" leave-to-class="opacity-0"> <div v-if="loaded" class="pb-20 max-w-none mx-auto"> <div class="bg-gray-50 px-16 pt-14 py-10 border-b border-gray-200"> <div class="flex items-center justify-between"> <div class="flex items-center gap-x-3 relative"> <!-- Back button --> <router-link :to="{ name: 'positions' }" class="inset-y-0 -left-10 h-14 flex items-center absolute transition duration-300 hover:-translate-x-1 hover:text-gray-500"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> <path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M7.72 12.53a.75.75 0 010-1.06l7.5-7.5a.75.75 0 111.06 1.06L9.31 12l6.97 6.97a.75.75 0 11-1.06 1.06l-7.5-7.5z" clip-rule="evenodd" /> </svg> </router-link> <!-- Emoji funcție --> <div class="w-14 h-14 rounded-lg bg-white ring-1 ring-inset ring-gray-200 flex items-center justify-center"> {{ position.emoji }} </div> <!-- Titlu funcție --> <div> <h3 class="text-base font-semibold leading-6 text-gray-900">{{ position.name }}</h3> <p class="mt-2 max-w-4xl text-sm text-gray-500"> Activitățile pe care <span class="text-gray-700 font-medium">{{ user.first_name }}</span> le realizează în această funcție din organizație </p> </div> </div> <div class="flex" v-if="user.status !== 'completed'"> <button type="button" class="flex items-center gap-x-2 rounded-md bg-green-500 px-3.5 py-2.5 text-sm font-medium text-white hover:bg-green-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600 disabled:bg-green-400 disabled:cursor-not-allowed" @click="completeDocumentation"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-5 h-5 -ml-0.5"> <path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm13.36-1.814a.75.75 0 10-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 00-1.06 1.06l2.25 2.25a.75.75 0 001.14-.094l3.75-5.25z" clip-rule="evenodd" /> </svg> Finalizează documentarea </button> <div class="relative ml-5"> <button @click="openTutorial" class="p-2 bg-blue-500 hover:bg-blue-400 rounded-full text-white"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" /> </svg> </button> <transition enter-active-class="transition-all ease-out duration-150 origin-top" enter-from-class="opacity-0 scale-75" enter-to-class="opacity-100 scale-105" leave-active-class="transition-all ease-in duration-75 origin-top" leave-from-class="opacity-100 scale-105" leave-to-class="opacity-0 scale-75"> <div v-if="tutorialPopover" class="absolute top-[100%] scal translate-y-3 -right-5 w-[15rem] p-4 rounded-lg text-sm text-center text-white bg-blue-400 shadow-sm transition-all duration-150 z-20"> <div class="relative"> <div class="w-3 h-3 bg-blue-400 absolute -top-5 right-[1.1rem] rotate-45"></div> </div> <div class="p-3 bg-white/20 text-white rounded-full inline-block"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> <path fill-rule="evenodd" d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z" clip-rule="evenodd" /> </svg> </div> <h3 class="mt-2 font-semibold text-base text-center">Atenție</h3> <p class="mt-2 text-center">Urmărește acest video cu instrucțiuni înainte să completezi pagina</p> <button @click="openTutorial" type="button" class="mt-5 mb-0.5 w-full text-center rounded-full px-7 py-2 text-sm font-semibold focus-visible:outline-none bg-white text-blue-500 hover:text-blue-400"> Vezi video </button> </div> </transition> </div> </div> </div> <template v-if="user.status !== 'completed'"> <!-- Adaugă activitate form --> <form @submit.prevent="addTask()" class="pt-5 pb-2"> <div :aria-selected="focused" class="ring-1 ring-inset h-16 w-full rounded-lg flex items-center gap-2 bg-white pr-3 pl-3 py-7 transition duration-300 aria-selected:ring-blue-500 aria-selected:ring-2" :class="[v$.newTask.$errors.length ? 'ring-red-300' : 'ring-gray-200']"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="w-6 h-6 mt-0.5" :class="[v$.newTask.$errors.length ? 'text-red-400' : 'text-gray-400']"> <path stroke-width="1.2" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25" /> </svg> <input @blur="inputFocused('blur')" @focus="inputFocused('focus')" v-model="newTask" class="border-none focus:ring-0 bg-transparent text-sm py-5 pl-0 flex-grow" :class="[v$.newTask.$errors.length ? 'placeholder:text-red-400' : 'placeholder:text-gray-400']" type="text" placeholder="Descrie activitate..." /> <!-- Generează cu AI --> <button v-if="false" @click="getExamplesAi" type="button" class="flex items-center gap-1 rounded-md bg-transparent px-3 py-2.5 text-sm font-medium text-gray-700 hover:text-blue-400 disabled:text-gray-500 disabled:hover:text-gray-500 disabled:cursor-not-allowed" :disabled="loadedGenerateAi"> <LoaderTbf color="text-gray-500" class="inline-block ml-2" v-if="loadedGenerateAi" /> <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512" class="inline-block ml-2" v-else> <path fill="currentColor" d="M327.5 85.2c-4.5 1.7-7.5 6-7.5 10.8s3 9.1 7.5 10.8L384 128l21.2 56.5c1.7 4.5 6 7.5 10.8 7.5s9.1-3 10.8-7.5L448 128l56.5-21.2c4.5-1.7 7.5-6 7.5-10.8s-3-9.1-7.5-10.8L448 64 426.8 7.5C425.1 3 420.8 0 416 0s-9.1 3-10.8 7.5L384 64 327.5 85.2zM205.1 73.3c-2.6-5.7-8.3-9.3-14.5-9.3s-11.9 3.6-14.5 9.3L123.3 187.3 9.3 240C3.6 242.6 0 248.3 0 254.6s3.6 11.9 9.3 14.5l114.1 52.7L176 435.8c2.6 5.7 8.3 9.3 14.5 9.3s11.9-3.6 14.5-9.3l52.7-114.1 114.1-52.7c5.7-2.6 9.3-8.3 9.3-14.5s-3.6-11.9-9.3-14.5L257.8 187.4 205.1 73.3zM384 384l-56.5 21.2c-4.5 1.7-7.5 6-7.5 10.8s3 9.1 7.5 10.8L384 448l21.2 56.5c1.7 4.5 6 7.5 10.8 7.5s9.1-3 10.8-7.5L448 448l56.5-21.2c4.5-1.7 7.5-6 7.5-10.8s-3-9.1-7.5-10.8L448 384l-21.2-56.5c-1.7-4.5-6-7.5-10.8-7.5s-9.1 3-10.8 7.5L384 384z" /> </svg> Generează cu AI </button> <!-- Adaugă --> <button type="submit" :disabled="loadedSubmit" class="rounded-md bg-blue-500 px-3 py-2 text-sm font-medium text-white hover:bg-blue-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"> Adaugă activitate </button> </div> </form> <div class="pt-0"> <ul class="mt-3 grid grid-flow-row-dense grid-cols-1 gap-5 sm:grid-cols-2 sm:gap-6 lg:grid-cols-5"> <li v-for="(task, index) in tasksExamples" :key="task.id" class="relative rounded-lg border border-gray-200 text-sm p-4 bg-white opacity-70 hover:opacity-100 transition duration-300 hover:shadow-xl hover:shadow-gray-400/5 hover:scale-105"> <p class="text-gray-600 select-none cursor-default">{{ task.description }}</p> <div class="absolute top-0 left-0 w-full rounded-lg h-full flex items-center justify-center bg-white/20 z-50 backdrop-blur-sm" v-if="loadedGenerateAi"> <LoaderTbf color="text-blue-500" /> </div> </li> </ul> </div> </template> </div> <div class="pt-12 px-16"> <div class="flex items-center justify-between"> <h2 class="text-sm font-medium text-gray-500">Activități ({{ tasks.length }})</h2> </div> <TransitionGroup tag="ul" role="list" enter-from-class="opacity-0 -translate-y-10" enter-active-class="transition-all duration-1000 transform" enter-to-class="opacity-100 translate-y-0" leave-from-class="opacity-100 translate-y-0" leave-active-class="transition-all duration-1000 transform absolute" leave-to-class="opacity-0 translate-y-10" class="mt-3 grid grid-flow-row-dense grid-cols-1 gap-5 sm:grid-cols-2 sm:gap-6 lg:grid-cols-5"> <li v-for="(task, index) in tasks" :key="task.uniqueId" class="transition-all duration-1000 rounded-lg border border-gray-200 text-sm p-4 overflow-hidden" :class="[{ 'bg-gray-50': task.is_temporary }]"> <template v-if="task.is_temporary"> <div class="w-full h-full flex items-center justify-center"> <LoaderTbf color="text-blue-500" /> </div> </template> <template v-else> <div class="py-2 flex justify-between"> <div class="text-lg">{{ task.emoji }}</div> <a @click="removeTask(task.id)" class="text-gray-400 cursor-pointer hover:text-gray-700" v-if="user.status !== 'completed'"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-5 h-5"> <path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M5.47 5.47a.75.75 0 011.06 0L12 10.94l5.47-5.47a.75.75 0 111.06 1.06L13.06 12l5.47 5.47a.75.75 0 11-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 01-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 010-1.06z" clip-rule="evenodd" /> </svg> </a> </div> <div class="mt-2 font-semibold text-gray-900 hover:text-gray-600 text-md"> {{ task.title }} </div> <p class="mt-2 text-gray-500">{{ task.description }}</p> </template> </li> </TransitionGroup> </div> </div> </Transition> <Transition enter-active-class="ease-out duration-500" enter-from-class="opacity-0" enter-to-class="opacity-100" leave-active-class="ease-in duration-200" leave-from-class="opacity-100" leave-to-class="opacity-0"> <div v-if="!loaded" class="absolute inset-0 pb-20 max-w-none mx-auto"> <div class="animate-pulse"> <div class="bg-gray-50 px-16 pt-14 py-10 border-b border-gray-200"> <div class="flex items-center"> <div class="flex items-center gap-x-3 relative"> <!-- Emoji funcție --> <div class="h-14 w-14 flex items-center justify-center rounded-lg bg-white object-cover ring-1 ring-gray-900/10"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 text-gray-200"> <path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M1.5 6a2.25 2.25 0 012.25-2.25h16.5A2.25 2.25 0 0122.5 6v12a2.25 2.25 0 01-2.25 2.25H3.75A2.25 2.25 0 011.5 18V6zM3 16.06V18c0 .414.336.75.75.75h16.5A.75.75 0 0021 18v-1.94l-2.69-2.689a1.5 1.5 0 00-2.12 0l-.88.879.97.97a.75.75 0 11-1.06 1.06l-5.16-5.159a1.5 1.5 0 00-2.12 0L3 16.061zm10.125-7.81a1.125 1.125 0 112.25 0 1.125 1.125 0 01-2.25 0z" clip-rule="evenodd" /> </svg> </div> <!-- Titlu funcție --> <div> <div class="h-5 bg-gray-200 rounded-md w-40"></div> <div class="mt-3 h-5 bg-gray-100 rounded-md w-[35rem]"></div> </div> </div> </div> <template v-if="!($route.query.is_completed && $route.query.is_completed == 'true')"> <!-- Adaugă activitate form --> <div class="pt-5 pb-2"> <div class="ring-1 ring-inset ring-gray-200 h-16 w-full rounded-lg flex items-center gap-2 bg-white pr-3 pl-3 py-7"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="w-6 h-6 text-gray-400 mt-0.5"> <path stroke-width="1.2" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25" /> </svg> <div class="h-10 flex-grow"></div> <div class="h-5 w-40 bg-gray-100 rounded-md"></div> <div class="h-9 w-[9rem] bg-gray-200 rounded-md"></div> </div> </div> <div class="pt-0"> <ul class="mt-3 grid grid-flow-row-dense grid-cols-1 gap-5 sm:grid-cols-2 sm:gap-6 lg:grid-cols-5"> <li v-for="task in 5" class="relative rounded-lg border border-gray-200 p-4 bg-white opacity-70"> <div class="mt-0.5 h-4 rounded-md bg-gray-100"></div> <div class="mt-1 h-4 rounded-md bg-gray-100"></div> <div class="mt-1 mb-0.5 h-4 rounded-md bg-gray-100" :class="[Math.random() < 0.5 ? 'w-20' : 'w-32']"></div> </li> </ul> </div> </template> </div> <div class="pt-12 px-16"> <div class="flex items-center justify-between"> <div class="bg-gray-100 h-5 w-28 rounded-md"></div> </div> <ul class="mt-3 grid grid-flow-row-dense grid-cols-1 gap-5 sm:grid-cols-2 sm:gap-6 lg:grid-cols-5"> <li v-for="task in 40" class="transition-all duration-1000 rounded-lg border border-gray-200 text-sm p-4 overflow-hidden"> <div class="py-2 flex justify-between"> <div class="h-6 w-6 flex items-center justify-center rounded-full bg-gray-200"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-4 h-4 text-white"> <path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M1.5 6a2.25 2.25 0 012.25-2.25h16.5A2.25 2.25 0 0122.5 6v12a2.25 2.25 0 01-2.25 2.25H3.75A2.25 2.25 0 011.5 18V6zM3 16.06V18c0 .414.336.75.75.75h16.5A.75.75 0 0021 18v-1.94l-2.69-2.689a1.5 1.5 0 00-2.12 0l-.88.879.97.97a.75.75 0 11-1.06 1.06l-5.16-5.159a1.5 1.5 0 00-2.12 0L3 16.061zm10.125-7.81a1.125 1.125 0 112.25 0 1.125 1.125 0 01-2.25 0z" clip-rule="evenodd" /> </svg> </div> <div class="text-gray-200 cursor-pointer hover:text-gray-700"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-5 h-5"> <path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M5.47 5.47a.75.75 0 011.06 0L12 10.94l5.47-5.47a.75.75 0 111.06 1.06L13.06 12l5.47 5.47a.75.75 0 11-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 01-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 010-1.06z" clip-rule="evenodd" /> </svg> </div> </div> <div class="mt-3 font-semibold text-gray-900 hover:text-gray-600 text-md"> <div class="h-5 bg-gray-200 rounded-md"></div> <div class="mt-1.5 h-5 bg-gray-200 rounded-md" :class="[Math.random() < 0.5 ? 'w-10' : 'w-20']"></div> </div> <div class="mt-1.5 h-4 bg-gray-100 rounded-md"></div> <div class="mt-1 h-4 bg-gray-100 rounded-md"></div> <div class="mt-1 h-4 bg-gray-100 rounded-md" :class="[Math.random() < 0.5 ? 'w-16' : 'w-20']"></div> </li> </ul> </div> </div> </div> </Transition> </div> </template> <script> // Import the required components import LoaderTbf from "@/components/public/LoadingTbf.vue"; import { useVuelidate } from "@vuelidate/core"; import { required } from "@vuelidate/validators"; import { userNotificationsStore } from "@/stores/notifications.js"; import { useModalsStore } from "@/stores/modals.js"; import { useCookies } from "vue3-cookies"; export default { setup() { const v$ = useVuelidate(); const { cookies } = useCookies(); return { v$, cookies }; }, components: { LoaderTbf, }, data() { return { loaded: false, loadedGenerateAi: false, loadedSubmit: false, loadedFinished: false, focused: false, newTask: "", tasksExamples: [], tasks: [], user: {}, position: {}, realTimeNotifications: userNotificationsStore(), realTimeModals: useModalsStore(), temporaryKey: 0, tutorialPopover: false, }; }, validations() { return { newTask: { required }, }; }, async mounted() { await this.getActivities(); var cookieModalVimeoData = this.cookies.get("modal_vimeo"); if (!(cookieModalVimeoData && JSON.parse(cookieModalVimeoData).includes("activity_create"))) { setTimeout(() => { this.tutorialPopover = true; }, 1000); } }, computed: {}, methods: { async getExamplesAi() { this.loadedGenerateAi = true; await axios .post("/generate/activity-suggestions", { position_id: this.$route.params.positionId }) .then(({ data }) => { this.tasksExamples = data.content.data; }) .catch((error) => { var responseError = error.response.data; this.realTimeNotifications.addNotification({ type: "error", title: "TBF ERROR", description: `"${responseError.message}"<br>Vă rugăm să ne contactați și să ne transmiteți eroare. În interesul remedierii acestei probleme cât mai curând posibil.`, }); }) .finally(() => { this.loadedGenerateAi = false; }); }, async addTask() { this.loadedSubmit = true; var descriptionActivitiy = this.newTask; const isFormCorrect = await this.v$.$validate(); if (!isFormCorrect) { this.loadedSubmit = false; this.realTimeNotifications.addNotification({ type: "error", title: "Verifica formularul.", description: "Descrierea activitatii este obligatorie.", }); return; } this.newTask = ""; this.v$.$reset(); this.temporaryKey++; var temporaryTask = { uniqueId: `temporary${this.temporaryKey}`, is_temporary: 1 }; this.tasks.unshift(temporaryTask); axios .post(`positions/${this.$route.params.positionId}/users/${this.$route.params.userId}/activities`, { description: descriptionActivitiy, }) .then(({ data }) => { var indexNewItem = this.tasks.findIndex((el) => el.uniqueId == `temporary${this.temporaryKey}`); this.tasks[indexNewItem] = { ...data.data, uniqueId: `temporary${this.temporaryKey}` }; }) .catch((error) => { var responseError = error.response.data; this.realTimeNotifications.addNotification({ type: "error", title: "TBF ERROR", description: `"${responseError.message}"<br>Vă rugăm să ne contactați și să ne transmiteți eroare. În interesul remedierii acestei probleme cât mai curând posibil.`, }); }) .finally(() => { this.loadedSubmit = false; }); }, inputFocused(type) { if (type === "focus") { this.focused = true; } else { this.focused = false; } }, removeTask(taskId) { axios.delete(`positions/${this.$route.params.positionId}/users/${this.$route.params.userId}/activities/${taskId}`).then(() => { this.tasks.splice( this.tasks.findIndex((el) => el.id == taskId), 1 ); }); }, async getActivities() { await axios .get(`positions/${this.$route.params.positionId}/users/${this.$route.params.userId}/activities`) .then(({ data }) => { this.tasks = data.data.map((el) => { return { ...el, uniqueId: el.id }; }); this.user = data.user; this.position = data.position; this.tasksExamples = data.position.activity_suggestions; }) .catch((error) => { var responseError = error.response.data; this.realTimeNotifications.addNotification({ type: "error", title: "TBF ERROR", description: `"${responseError.message}"<br>Vă rugăm să ne contactați și să ne transmiteți eroare. În interesul remedierii acestei probleme cât mai curând posibil.`, }); }) .finally(() => { this.loaded = true; }); }, completeDocumentation() { if (this.tasks.length <= 4) { this.realTimeModals.toggleShowModal("modal_error_finalize_activities"); return; } this.realTimeModals.toggleShowModal("modal_confirm_documentation", { positionId: this.$route.params.positionId, userId: this.$route.params.userId, }); }, openTutorial() { var arrayPages = this.cookies.get("modal_vimeo") ? JSON.parse(this.cookies.get("modal_vimeo")) : []; if (!arrayPages.includes("activity_create")) { arrayPages.push("activity_create"); this.cookies.set("modal_vimeo", JSON.stringify(arrayPages), "30d"); } this.tutorialPopover = false; this.realTimeModals.toggleShowModal("modal_video_vimeo", { videoId: "870595411" }); }, }, }; </script>
Back