Bladeren bron

feat: ✨ feat (pedidos e solicitacoes) adicionada listagem de solicitacoes do cliente na aba pedidos

foi adicionada a listagem de solicitacoes do cliente e as propostas recebidas dos prestadores na aba pedidos. Tambem foi feita correcao gerao das datas nos cards de agendamentos

fase:dev | origin:escopo
Gustavo Zanatta 2 dagen geleden
bovenliggende
commit
4ce464d153

+ 13 - 2
package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "diarista-prestador-app",
-  "version": "0.0.1",
+  "version": "2.2",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "diarista-prestador-app",
-      "version": "0.0.1",
+      "version": "2.2",
       "dependencies": {
         "@bufbuild/protobuf": "^2.5.1",
         "@capacitor/browser": "^7.0.5",
@@ -16,6 +16,7 @@
         "@capacitor/geolocation": "^7.1.8",
         "@capacitor/google-maps": "^7.2.2",
         "@capacitor/push-notifications": "^7.0.7",
+        "@ionic/pwa-elements": "^3.4.0",
         "@quasar/cli": "^2.5.0",
         "@quasar/extras": "^1.17.0",
         "axios": "^1.9.0",
@@ -1556,6 +1557,16 @@
         "node": ">=16.0.0"
       }
     },
+    "node_modules/@ionic/pwa-elements": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/@ionic/pwa-elements/-/pwa-elements-3.4.0.tgz",
+      "integrity": "sha512-WmL7An4NOsvJvct4V/A8hudr+yXgLBHYmxzqWGsetZmzN7C6suLRS/KIh2P1t8cSYCYL7HRrbv8NrIChPkh6Ow==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=16.0.0",
+        "npm": ">=8.0.0"
+      }
+    },
     "node_modules/@ionic/utils-array": {
       "version": "2.1.6",
       "resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.6.tgz",

+ 1 - 0
package.json

@@ -30,6 +30,7 @@
     "@capacitor/geolocation": "^7.1.8",
     "@capacitor/google-maps": "^7.2.2",
     "@capacitor/push-notifications": "^7.0.7",
+    "@ionic/pwa-elements": "^3.4.0",
     "@quasar/cli": "^2.5.0",
     "@quasar/extras": "^1.17.0",
     "axios": "^1.9.0",

+ 1 - 0
quasar.config.js

@@ -89,6 +89,7 @@ export default defineConfig((ctx) => {
       "i18n",
       "defaultPropsComponents",
       "push-notifications",
+      "pwa-elements",
       // "socket.io",
     ],
 

+ 11 - 0
src/boot/pwa-elements.js

@@ -0,0 +1,11 @@
+import { defineBoot } from "#q-app/wrappers";
+import { Capacitor } from "@capacitor/core";
+import { defineCustomElements } from "@ionic/pwa-elements/loader";
+
+export default defineBoot(() => {
+  if (Capacitor.isNativePlatform()) {
+    return;
+  }
+
+  defineCustomElements(window);
+});

+ 1 - 22
src/components/dashboard/DashboardNextSchedules.vue

@@ -176,6 +176,7 @@
 <script setup>
 import { avatarColors, formatAddress, formatCurrency, getFirstName } from "src/helpers/utils";
 import { labelsPeriodTypes } from "src/helpers/labelsPeriodTypes.js";
+import { formatDayMonth, formatWeekday } from "src/helpers/scheduleDate";
 import { useI18n } from "vue-i18n";
 import { useQuasar } from "quasar";
 
@@ -207,28 +208,6 @@ const copyAddress = (address) => {
   });
 };
 
-const formatDayMonth = (iso) => {
-  if (!iso) {
-    return "";
-  }
-
-  return new Date(iso).toLocaleDateString("pt-BR", {
-    day: "2-digit",
-    month: "2-digit",
-  });
-};
-
-const formatWeekday = (iso) => {
-  if (!iso) {
-    return "";
-  }
-
-  const date = new Date(iso);
-
-  const weekday = date.toLocaleDateString("pt-BR", { weekday: "long" });
-
-  return weekday.charAt(0).toUpperCase() + weekday.slice(1);
-};
 </script>
 
 <style scoped lang="scss">

+ 1 - 22
src/components/dashboard/DashboardOpportunities.vue

@@ -173,6 +173,7 @@
 <script setup>
 import { avatarColors, formatCurrency, getFirstName } from "src/helpers/utils";
 import { labelsPeriodTypes } from "src/helpers/labelsPeriodTypes.js";
+import { formatDayMonth, formatWeekday } from "src/helpers/scheduleDate";
 import { useQuasar } from "quasar";
 import { useRouter } from "vue-router";
 
@@ -191,28 +192,6 @@ const router = useRouter();
 
 
 
-const formatDayMonth = (iso) => {
-  if (!iso) {
-    return "";
-  }
-
-  return new Date(iso).toLocaleDateString("pt-BR", {
-    day: "2-digit",
-    month: "2-digit",
-  });
-};
-
-const formatWeekday = (iso) => {
-  if (!iso) {
-    return "";
-  }
-
-  const date = new Date(iso);
-
-  const weekday = date.toLocaleDateString("pt-BR", { weekday: "long" });
-
-  return weekday.charAt(0).toUpperCase() + weekday.slice(1);
-};
 
 const openAllOpportunities = () => {
   router.push({

+ 1 - 22
src/components/dashboard/DashboardPendingConfirmation.vue

@@ -176,6 +176,7 @@
 <script setup>
 import { avatarColors, formatAddress, formatCurrency, getFirstName } from "src/helpers/utils";
 import { labelsPeriodTypes } from "src/helpers/labelsPeriodTypes.js";
+import { formatDayMonth, formatWeekday } from "src/helpers/scheduleDate";
 import { useI18n } from "vue-i18n";
 import { useQuasar } from "quasar";
 
@@ -207,28 +208,6 @@ const copyAddress = (address) => {
   });
 };
 
-const formatDayMonth = (iso) => {
-  if (!iso) {
-    return "";
-  }
-
-  return new Date(iso).toLocaleDateString("pt-BR", {
-    day: "2-digit",
-    month: "2-digit",
-  });
-};
-
-const formatWeekday = (iso) => {
-  if (!iso) {
-    return "";
-  }
-
-  const date = new Date(iso);
-
-  const weekday = date.toLocaleDateString("pt-BR", { weekday: "long" });
-
-  return weekday.charAt(0).toUpperCase() + weekday.slice(1);
-};
 </script>
 
 <style scoped lang="scss">

+ 24 - 0
src/helpers/scheduleDate.js

@@ -0,0 +1,24 @@
+const parseLocalDate = (dateStr) => {
+  if (!dateStr) return null;
+
+  const iso = dateStr.match(/^(\d{4})-(\d{2})-(\d{2})/);
+  if (iso) return new Date(+iso[1], +iso[2] - 1, +iso[3]);
+  const dmy = dateStr.match(/^(\d{2})\/(\d{2})\/(\d{4})/);
+  if (dmy) return new Date(+dmy[3], +dmy[2] - 1, +dmy[1]);
+  return null;
+};
+
+const formatWeekday = (dateStr) => {
+  const d = parseLocalDate(dateStr);
+  if (!d) return "";
+  const w = d.toLocaleDateString("pt-BR", { weekday: "long" });
+  return w.charAt(0).toUpperCase() + w.slice(1);
+};
+
+const formatDayMonth = (dateStr) => {
+  const d = parseLocalDate(dateStr);
+  if (!d) return "";
+  return d.toLocaleDateString("pt-BR", { day: "2-digit", month: "2-digit" });
+};
+
+export { parseLocalDate, formatWeekday, formatDayMonth };

+ 4 - 0
src/i18n/locales/en.json

@@ -531,6 +531,10 @@
     "placeholder_phone": "Enter your phone",
     "notifications": "Notifications",
     "push_notifications": "Receive notifications",
+    "language": "Language",
+    "lang_pt": "PT-br",
+    "lang_en": "EN-us",
+    "lang_es": "ES-es",
     "bank_data": {
       "title": "Bank data",
       "description": "Accounts to receive your payments",

+ 4 - 0
src/i18n/locales/es.json

@@ -531,6 +531,10 @@
     "placeholder_phone": "Escriba su teléfono",
     "notifications": "Notificaciones",
     "push_notifications": "Recibir notificaciones",
+    "language": "Idioma",
+    "lang_pt": "PT-br",
+    "lang_en": "EN-us",
+    "lang_es": "ES-es",
     "bank_data": {
       "title": "Datos bancarios",
       "description": "Cuentas para recibir tus pagos",

+ 4 - 0
src/i18n/locales/pt.json

@@ -534,6 +534,10 @@
     "placeholder_phone": "Digite seu telefone",
     "notifications": "Notificações",
     "push_notifications": "Receber notificações",
+    "language": "Idioma",
+    "lang_pt": "PT-br",
+    "lang_en": "EN-us",
+    "lang_es": "ES-es",
     "bank_data": {
       "title": "Dados bancários",
       "description": "Contas para receber seus pagamentos",

+ 62 - 1
src/pages/profile/ProfileEditDialog.vue

@@ -135,6 +135,44 @@
               />
             </div>
 
+            <div>
+              <div class="font12 fontbold q-mb-sm text-grey-8">
+                {{ $t("profile.language") }}
+              </div>
+
+              <div class="row">
+                <q-radio
+                  v-model="selectedLocale"
+                  class="text-text col-4 font10 fontmedium"
+                  color="primary"
+                  keep-color
+                  val="pt"
+                  :label="$t('profile.lang_pt')"
+                  @update:model-value="onLocaleChange"
+                />
+
+                <q-radio
+                  v-model="selectedLocale"
+                  class="text-text col-4 font10 fontmedium"
+                  color="primary"
+                  keep-color
+                  val="en"
+                  :label="$t('profile.lang_en')"
+                  @update:model-value="onLocaleChange"
+                />
+
+                <q-radio
+                  v-model="selectedLocale"
+                  class="text-text col-4 font10 fontmedium"
+                  color="primary"
+                  keep-color
+                  val="es"
+                  :label="$t('profile.lang_es')"
+                  @update:model-value="onLocaleChange"
+                />
+              </div>
+            </div>
+
             <!-- NOVA SEÇÃO -->
             <div>
               <div class="font12 fontbold q-mb-sm text-grey-8">
@@ -184,11 +222,12 @@ import {
   CameraSource,
 } from "@capacitor/camera";
 
+import { Cookies, useDialogPluginComponent, useQuasar } from "quasar";
 import { computed, onMounted, ref } from "vue";
 import { genderOptions } from "src/helpers/genderOptions";
 import { getUser, updateUser } from "src/api/user";
+import { i18n } from "src/boot/i18n";
 import { updateProviderWithFiles } from "src/api/provider";
-import { useDialogPluginComponent, useQuasar } from "quasar";
 import { useFormUpdateTracker } from "src/composables/useFormUpdateTracker";
 import { useI18n } from "vue-i18n";
 
@@ -223,6 +262,22 @@ const selfieFile     = ref(null);
 const submitting     = ref(false);
 const userId         = ref(null);
 
+const normalizeLocale = (loc) => {
+  if (!loc) return "pt";
+
+  const l = String(loc).toLowerCase();
+
+  if (l.startsWith("pt")) return "pt";
+  if (l.startsWith("en")) return "en";
+  if (l.startsWith("es")) return "es";
+
+  return "pt";
+};
+
+const selectedLocale = ref(
+  normalizeLocale(i18n.global.locale.value ?? i18n.global.locale),
+);
+
 const hasChanges = computed(
   () => hasUpdatedFields.value || !!selfieFile.value,
 );
@@ -300,6 +355,12 @@ const takeSelfie = async () => {
   }
 };
 
+const onLocaleChange = (val) => {
+  i18n.global.locale.value = val;
+
+  Cookies.set("locale", val, { expires: 365, path: "/" });
+};
+
 const submitUpdate = async () => {
   if (!hasChanges.value) return;