| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- <template>
- <div>
- <input
- ref="fileInputRef"
- type="file"
- accept="image/*,video/*,.pdf"
- style="display: none"
- @change="onFileSelected"
- />
- <DefaultTable
- v-model:rows="rows"
- title="Contratos"
- :columns
- descricao="contratos"
- :feminino="false"
- no-api-call
- add-item
- :show-search-field="false"
- @on-add-item="handleAdd"
- >
- <template #body-cell-period="{ row }">
- <q-td>{{ row.signature_date }} — {{ row.end_date }}</q-td>
- </template>
- <template #body-cell-status="{ row }">
- <q-td align="center">
- <q-badge
- :color="statusColor(row.status)"
- :label="statusLabel(row.status)"
- />
- </q-td>
- </template>
- <template #body-cell-actions="{ row }">
- <q-td align="center">
- <q-item-section class="no-wrap" style="flex-direction: row; gap: 4px">
- <q-btn
- outline
- icon="mdi-pencil-outline"
- style="width: 36px"
- @click.prevent.stop="handleEdit(row)"
- />
- <q-btn
- outline
- icon="mdi-paperclip"
- style="width: 36px"
- :loading="uploadingId === row.id"
- @click.prevent.stop="triggerFileInput(row)"
- />
- <q-btn
- outline
- icon="mdi-dots-vertical"
- style="width: 36px"
- @click.prevent.stop
- >
- <q-menu>
- <q-list style="min-width: 170px">
- <q-item
- v-close-popup
- clickable
- :disable="!row.file_url"
- @click="openFile(row.file_url)"
- >
- <q-item-section>Visualizar arquivo</q-item-section>
- </q-item>
- <template v-if="row.status === 'frozen' || row.status === 'cancelled'">
- <q-item
- v-close-popup
- clickable
- @click="handleReactivate(row)"
- >
- <q-item-section>Reativar Contrato</q-item-section>
- </q-item>
- </template>
- <template v-else>
- <q-item
- v-close-popup
- clickable
- @click="handleFreeze(row)"
- >
- <q-item-section>Congelar Contrato</q-item-section>
- </q-item>
- <q-item
- v-close-popup
- clickable
- @click="handleCancel(row)"
- >
- <q-item-section>Cancelar Contrato</q-item-section>
- </q-item>
- </template>
- </q-list>
- </q-menu>
- </q-btn>
- </q-item-section>
- </q-td>
- </template>
- </DefaultTable>
- </div>
- </template>
- <script setup>
- import { ref, onMounted } from "vue";
- import { useQuasar } from "quasar";
- import DefaultTable from "src/components/defaults/DefaultTable.vue";
- import AddEditContractDialog from "src/pages/students/components/AddEditContractDialog.vue";
- import ContractActionConfirmDialog from "src/pages/students/components/ContractActionConfirmDialog.vue";
- import {
- getStudentContracts,
- attachContractFile,
- freezeContract,
- cancelContract,
- reactivateContract,
- } from "src/api/studentContract";
- const props = defineProps({
- student: {
- type: Object,
- required: true,
- },
- });
- const $q = useQuasar();
- const rows = ref([]);
- const fileInputRef = ref(null);
- const uploadingId = ref(null);
- let pendingContractId = null;
- async function loadContracts() {
- rows.value = await getStudentContracts(props.student.id);
- }
- onMounted(loadContracts);
- function openDialog(contract = null) {
- $q.dialog({
- component: AddEditContractDialog,
- componentProps: { student: props.student, contract },
- }).onOk(loadContracts);
- }
- function handleAdd() {
- openDialog();
- }
- function handleEdit(contract) {
- openDialog(contract);
- }
- function triggerFileInput(row) {
- pendingContractId = row.id;
- fileInputRef.value.value = "";
- fileInputRef.value.click();
- }
- async function onFileSelected(event) {
- const file = event.target.files?.[0];
- if (!file || !pendingContractId) return;
- uploadingId.value = pendingContractId;
- try {
- const formData = new FormData();
- formData.append("file", file);
- const updated = await attachContractFile(pendingContractId, formData);
- const idx = rows.value.findIndex((r) => r.id === pendingContractId);
- if (idx !== -1) rows.value[idx] = updated;
- } catch (e) {
- console.error(e);
- $q.notify({ type: "negative", message: "Erro ao anexar arquivo." });
- } finally {
- uploadingId.value = null;
- pendingContractId = null;
- }
- }
- function openFile(url) {
- window.open(url, "_blank");
- }
- function confirmAction(title, message, apiFn, contract) {
- $q.dialog({
- component: ContractActionConfirmDialog,
- componentProps: { title, message },
- }).onOk(async () => {
- try {
- const updated = await apiFn(contract.id);
- const idx = rows.value.findIndex((r) => r.id === contract.id);
- if (idx !== -1) rows.value[idx] = updated;
- } catch (e) {
- console.error(e);
- $q.notify({ type: "negative", message: "Erro ao atualizar status do contrato." });
- }
- });
- }
- function handleFreeze(contract) {
- confirmAction(
- "Congelar Contrato",
- "Você tem certeza que deseja CONGELAR este contrato? Isso irá gerar multas e cancelamento da cobrança recorrente.",
- freezeContract,
- contract,
- );
- }
- function handleCancel(contract) {
- confirmAction(
- "Cancelar Contrato",
- "Você tem certeza que deseja CANCELAR este contrato? Isso irá gerar multas e cancelamento da cobrança recorrente.",
- cancelContract,
- contract,
- );
- }
- function handleReactivate(contract) {
- confirmAction(
- "Reativar Contrato",
- "Você tem certeza que deseja REATIVAR este contrato?",
- reactivateContract,
- contract,
- );
- }
- function statusColor(status) {
- if (status === "active") return "positive";
- if (status === "frozen") return "info";
- if (status === "cancelled") return "negative";
- return "warning";
- }
- function statusLabel(status) {
- if (status === "active") return "Ativo";
- if (status === "frozen") return "Congelado";
- if (status === "cancelled") return "Cancelado";
- return "Inativo";
- }
- const columns = ref([
- { name: "contract", label: "Contrato", field: "protocol", align: "left" },
- {
- name: "period",
- label: "Data Assinatura - Encerramento",
- field: null,
- align: "left",
- },
- { name: "status", label: "Status", field: "status", align: "center" },
- { name: "actions", label: "Ações", field: null, align: "center" },
- ]);
- </script>
|