From 61f93ec4e820d685b290ffe5d711f6193e5c4a4f Mon Sep 17 00:00:00 2001 From: Edwin Eames Date: Sun, 1 Feb 2026 19:04:07 -0500 Subject: [PATCH] Refactor frontend to Composition API and improve UI/UX Major Changes: - Migrate components from Options API to Composition API with + + diff --git a/src/components/EnhancedBadge.vue b/src/components/EnhancedBadge.vue new file mode 100644 index 0000000..2feddfb --- /dev/null +++ b/src/components/EnhancedBadge.vue @@ -0,0 +1,158 @@ + + + + + diff --git a/src/components/EnhancedButton.vue b/src/components/EnhancedButton.vue new file mode 100644 index 0000000..950b154 --- /dev/null +++ b/src/components/EnhancedButton.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/src/components/EnhancedModal.vue b/src/components/EnhancedModal.vue new file mode 100644 index 0000000..623bc04 --- /dev/null +++ b/src/components/EnhancedModal.vue @@ -0,0 +1,174 @@ + + + + + diff --git a/src/components/EnhancedTable.vue b/src/components/EnhancedTable.vue new file mode 100644 index 0000000..32a0d8f --- /dev/null +++ b/src/components/EnhancedTable.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/src/components/FloatingInput.vue b/src/components/FloatingInput.vue new file mode 100644 index 0000000..8f1c943 --- /dev/null +++ b/src/components/FloatingInput.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/src/components/LoadingCard.vue b/src/components/LoadingCard.vue new file mode 100644 index 0000000..fd47ffc --- /dev/null +++ b/src/components/LoadingCard.vue @@ -0,0 +1,22 @@ + + + + + diff --git a/src/components/PageTransition.vue b/src/components/PageTransition.vue new file mode 100644 index 0000000..210272d --- /dev/null +++ b/src/components/PageTransition.vue @@ -0,0 +1,147 @@ + + + + + diff --git a/src/components/StatCard.vue b/src/components/StatCard.vue new file mode 100644 index 0000000..9e36488 --- /dev/null +++ b/src/components/StatCard.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/src/index.css b/src/index.css index b155180..d9f3ae1 100755 --- a/src/index.css +++ b/src/index.css @@ -1,6 +1,61 @@ +/* Import modern font */ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap'); @tailwind base; @tailwind components; @tailwind utilities; +/* Base styles */ +@layer base { + body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } +} + +/* Custom utilities */ +@layer utilities { + /* Shadow system for elevation */ + .shadow-soft { + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + } + + .shadow-medium { + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12); + } + + .shadow-strong { + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16); + } + + /* Hover lift effect */ + .hover-lift { + transition: transform 0.2s ease-out, box-shadow 0.2s ease-out; + } + + .hover-lift:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16); + } + + /* Smooth transitions */ + .transition-smooth { + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + } + + /* Gradient text */ + .gradient-text { + background: linear-gradient(135deg, hsl(var(--p)) 0%, hsl(var(--a)) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + } +} + /* Hide header and sidebar when printing */ +@media print { + header, .drawer-side { + display: none !important; + } +} diff --git a/src/layouts/DefaultLayout.vue b/src/layouts/DefaultLayout.vue index 45b0d27..65aa5d9 100644 --- a/src/layouts/DefaultLayout.vue +++ b/src/layouts/DefaultLayout.vue @@ -4,14 +4,19 @@ -
+
- + + +
+ +
+ @@ -30,8 +35,9 @@ import { useSearchStore } from '../stores/search'; import HeaderAuth from './headers/headerauth.vue'; import SideBar from './sidebar/sidebar.vue'; -// Make sure this path and component name are correct +import Footer from './footers/footer.vue'; import SearchResults from '../components/SearchResults.vue'; +import PageTransition from '../components/PageTransition.vue'; const searchStore = useSearchStore(); diff --git a/src/layouts/footers/footer.vue b/src/layouts/footers/footer.vue index 5a6973f..154f6e9 100755 --- a/src/layouts/footers/footer.vue +++ b/src/layouts/footers/footer.vue @@ -1,5 +1,5 @@ - diff --git a/src/layouts/headers/headerauth.vue b/src/layouts/headers/headerauth.vue index ecf44f8..daf67c0 100755 --- a/src/layouts/headers/headerauth.vue +++ b/src/layouts/headers/headerauth.vue @@ -85,6 +85,15 @@
  • Profile
  • Change Password
  • +
    + +
  • + + + {{ theme.label }} + +
  • +
  • Logout
  • @@ -219,6 +228,7 @@ import axios from 'axios' import authHeader from '../../services/auth.header' import { useSearchStore } from '../../stores/search' // Adjust path if needed import { useAuthStore } from '../../stores/auth' +import { useThemeStore, AVAILABLE_THEMES } from '../../stores/theme' // Define the shape of your data for internal type safety interface User { @@ -253,6 +263,9 @@ const isTestModalVisible = ref(false) const isTestLoading = ref(false) const testResponse = ref(null as any) +// Stores +const themeStore = useThemeStore() + // Computed properties const searchStore = computed(() => useSearchStore()) diff --git a/src/layouts/sidebar/sidebar.vue b/src/layouts/sidebar/sidebar.vue index bc2ef8a..1c6f782 100755 --- a/src/layouts/sidebar/sidebar.vue +++ b/src/layouts/sidebar/sidebar.vue @@ -7,12 +7,24 @@ -
  • Home
  • +
  • + + + + + Home + +
  • - Customer + + + + + Customer +
    • All Customers
    @@ -22,7 +34,12 @@
  • - Delivery + + + + + Delivery +
    • Home
    • @@ -58,7 +75,12 @@
    • - Service + + + + + Service +
      • Service Calendar
      • @@ -82,7 +104,12 @@
      • - Automatics + + + + + Automatics +
        • @@ -97,7 +124,12 @@
        • - Transactions + + + + + Transactions +
          • @@ -109,10 +141,16 @@
        • - +
        • - Admin + + + + + + Admin +
          • Employees
          • Oil Pricing
          • diff --git a/src/main.ts b/src/main.ts index 09fe7c4..4076d7b 100755 --- a/src/main.ts +++ b/src/main.ts @@ -7,9 +7,16 @@ import router from './router'; import Notifications from '@kyvg/vue3-notification'; import Pagination from 'v-pagination-3'; import { createPinia } from 'pinia'; +import { useThemeStore } from './stores/theme'; +const pinia = createPinia() const app = createApp(App) - app.use(createPinia()) + app.use(pinia) app.use(router) .component('pagination', Pagination); - app.use(Notifications).mount('#app') \ No newline at end of file + +// Initialize theme before mounting to prevent flash of default theme +const themeStore = useThemeStore() +themeStore.initTheme() + +app.use(Notifications).mount('#app') \ No newline at end of file diff --git a/src/pages/Index.vue b/src/pages/Index.vue index 26be203..56ea892 100755 --- a/src/pages/Index.vue +++ b/src/pages/Index.vue @@ -13,76 +13,120 @@ -
            +
            - -
            -

            Today's Stats

            + +
            +
            +

            Today's Deliveries

            +
            + + + +
            +
            -
            - Total Deliveries Today: - {{ delivery_count }} +
            + {{ delivery_count }} + total deliveries
            -
            - Completed - {{ delivery_count_delivered }} / {{ delivery_count }} +
            + Completed + {{ delivery_count_delivered }} / {{ delivery_count }}
            - +
            -
            -

            Today's Oil Price

            -
            -
            - Price / Gallon: - ${{ today_oil_price }} +
            +
            +

            Oil Pricing

            +
            + + +
            -
            - Same Day Fee: - ${{ price_same_day }} +
            +
            +
            + Per Gallon + ${{ today_oil_price }}
            -
            - Prime Fee: - ${{ price_prime }} -
            -
            - Emergency Fee: - ${{ price_emergency }} +
            +
            +
            + Same Day + ${{ price_same_day }} +
            +
            + Prime + ${{ price_prime }} +
            +
            + Emergency + ${{ price_emergency }} +
            - -
            -

            Service Price

            -
            -
            - Price / Hour: - $125 + +
            +
            +

            Service Pricing

            +
            + + +
            -
            - Price / Emergency: - $200 +
            +
            +
            + Per Hour + $125 +
            +
            + Emergency + $200
            - -
            -

            Customer Search Keys

            -
            -
            @ - Searches customer last name only
            -
            ! - Searches customer address only
            -
            # - Searches phone number only
            -
            $ - Searches account number only
            + +
            +
            +

            Search Shortcuts

            +
            + + + +
            +
            +
            +
            + @ + Last name +
            +
            + ! + Address +
            +
            + # + Phone number +
            +
            + $ + Account number +
            + -
            +
            @@ -248,7 +248,6 @@ import { serviceService } from '../../../services/serviceService' import { adminService } from '../../../services/adminService' import Header from '../../../layouts/headers/headerauth.vue' import SideBar from '../../../layouts/sidebar/sidebar.vue' -import Footer from '../../../layouts/footers/footer.vue' import { notify } from "@kyvg/vue3-notification"; import "leaflet/dist/leaflet.css"; import L from 'leaflet'; @@ -269,7 +268,7 @@ import CreditCards from './profile/CreditCards.vue'; import CustomerComments from './profile/CustomerComments.vue'; import HistoryTabs from './profile/HistoryTabs.vue'; import TankEstimation from './TankEstimation.vue'; -import {AuthorizeTransaction} from '../../../types/models'; +import { AuthorizeTransaction, PricingData, CustomerDescriptionData, CustomersResponse, CustomerResponse, AxiosResponse, AxiosError } from '../../../types/models'; L.Icon.Default.mergeOptions({ iconUrl: iconUrl, @@ -373,6 +372,15 @@ const isCreateAccountModalVisible = ref(false) const isCreatingAccount = ref(false) const createdProfileId = ref('') const isDuplicateErrorModalVisible = ref(false) // Add for duplicate detection popup +const pricing = ref({ + price_from_supplier: 0, + price_for_customer: 0, + price_for_employee: 0, + price_same_day: 0, + price_prime: 0, + price_emergency: 0, + date: "" +}) // Computed const hasPartsData = computed(() => { @@ -403,7 +411,7 @@ onMounted(() => { }) // Functions -const getPage = (page: any) => { +const getPage = (page: number) => { if (customer.value && customer.value.id) { getCustomerDelivery(customer.value.id, page); } @@ -411,8 +419,14 @@ const getPage = (page: any) => { const getCustomer = (userid: number) => { if (!userid) return; - customerService.getById(userid).then((response: any) => { - customer.value = response.data?.customer || response.data; + customerService.getById(userid).then((response: AxiosResponse) => { + // Correctly handle response structure - backend may return wrapped { customer: ... } or flat + const data = response.data; + customer.value = data.customer || data; + // Handle pricing - it might be missing or nested + if (data.pricing) { + pricing.value = data.pricing; + } // --- DEPENDENT API CALLS --- userStatus(); @@ -436,7 +450,8 @@ const getCustomer = (userid: number) => { getCustomerTransactions(customer.value.id); checkAuthorizeAccount(); - }).catch((error: any) => { + }).catch((err: unknown) => { + const error = err as AxiosError; console.error("CRITICAL: Failed to fetch main customer data. Aborting other calls.", error); }); } @@ -450,7 +465,7 @@ const userStatus = () => { } const userAutomaticStatus = (userid: number) => { - customerService.getAutomaticStatus(userid).then((response: any) => { + customerService.getAutomaticStatus(userid).then((response: AxiosResponse) => { automatic_status.value = response.data.status if (automatic_status.value === 1) { getCustomerAutoDelivery(customer.value.id) @@ -460,55 +475,29 @@ const userAutomaticStatus = (userid: number) => { } const userAutomatic = (userid: number) => { - customerService.assignAutomatic(userid, { status: 0 }).then((response: any) => { // Status is handled by backend toggle? Or do I need to send current? - // The original code was GET /customer/automatic/assign/{userid}. Wait, GET? - // customerService.assignAutomatic is PUT with data. - // Let's check the original code again. - // Original: axios({ method: 'get', url: .../assign/userid }) - // Only GET? That's weird for assignment. - // Let's assume it toggles or something. - // customerService.assignAutomatic uses PUT. - // I should check if backend supports GET for assignment or if I made a mistake in customerService definition. - // If backend expects GET, I should use api.get via a custom call or update the service. - // But assuming I want to migrate standardly... - // Let's check the implementation plan/service again. - // Ideally I'd fix the backend to be PUT/POST. - // But for now, let's look at what `customerService` has. - // `assignAutomatic: (id: number, data: { status: number }) => api.put(...)` - // The original code was GET. - // I'll stick to the existing behavior or use a raw api call if service is wrong. - // Checking `customerService.ts`: `api.put`. - // Checking `profile.vue`: `method: 'get'`. - // mismatch! - // I will use `api.get` directly here if service doesn't match, OR update service. - // I'll use `api.get` for now via `customerService` if I add a method `toggleAutomatic`. - // Or just use `api` imported from service. - // I replaced axios imports, so I don't have axios. - // I should import `api` from usage in services? No, I imported services. - // I'll assume `customerService` should be updated or use `customerService.assignAutomatic` if the backend actually supports PUT too. - // If not, I might break it. - // Let's check `views.py` for `/customer/automatic/assign/`? No time. - // I'll assume the service was written correctly for the *intended* API, maybe the frontend was using GET legacy. - // I will use `customerService.assignAutomatic` but wait, it needs data. - // The original didn't send data. - // This is risky. - // Use `api.get`? I didn't import `api`. - // I'll skip migrating `userAutomatic` for a second and handle it in the next batch or add `toggleAutomatic` to `customerService`. - // Let's skip `userAutomatic` replacement in this chunk and do it later. - // Wait, I am replacing the block containing it. - // I will leave `userAutomatic` using `customerService` but I need to be careful. - // Let's look at `customerService` again. - // I'll modify `customerService` to add `toggleAutomatic`. - // But I can't do that in this tool call. - // I'll leave `userAutomatic` as is (raw axios?) No, axios is gone. - // I'll comment it out or put a placeholder? - // No, I'll use `customerService` and hope `put` works, or I'll fix `customerService` in next step. - // Actually, I can import `api` from `../../services/api`. - // I'll add `import api from '../../../services/api'` to imports. - - // RE-PLAN: Add `import api` to imports. - // Then use `api.get` for `userAutomatic` to replicate exact behavior. - }) + // Toggle status: 1 -> 0, 0 -> 1 + const newStatus = automatic_status.value === 1 ? 0 : 1; + customerService.assignAutomatic(userid, { status: newStatus }).then((response: AxiosResponse) => { + // Update local status from response or the requested value + if (response.data && typeof response.data.status !== 'undefined') { + automatic_status.value = response.data.status; + } else { + automatic_status.value = newStatus; + } + + if (automatic_status.value === 1) { + getCustomerAutoDelivery(customer.value.id); + } + checktotalOil(customer.value.id); + notify({ + title: "Automatic Status Updated", + text: automatic_status.value === 1 ? "Customer set to Automatic" : "Customer set to Will Call", + type: "success" + }); + }).catch((err: unknown) => { + console.error("Failed to update automatic status", err); + notify({ title: "Error", text: "Failed to update status", type: "error" }); + }); } const getNozzleColor = (nozzleString: string): string => { @@ -523,54 +512,53 @@ const getNozzleColor = (nozzleString: string): string => { } const getCustomerLastDelivery = (userid: number) => { - adminService.stats.userLastDelivery(userid).then((response: any) => { + adminService.stats.userLastDelivery(userid).then((response: AxiosResponse) => { customer_last_delivery.value = response.data.date }) } const getCustomerStats = (userid: number) => { - adminService.stats.userStats(userid).then((response: any) => { + adminService.stats.userStats(userid).then((response: AxiosResponse) => { customer_stats.value = response.data }) } const checktotalOil = (userid: number) => { - adminService.stats.customerGallonsTotal(userid) // Just a check? Original didn't do anything with response. + adminService.stats.customerGallonsTotal(userid) // Just a check } const getCustomerDescription = (userid: number) => { - customerService.getDescription(userid).then((response: any) => { - customer_description.value = response.data?.description || response.data || {} + customerService.getDescription(userid).then((response: AxiosResponse) => { + customer_description.value = response.data?.description || (response.data as unknown as CustomerDescriptionData); }) } const getCustomerTank = (userid: number) => { - customerService.getTank(userid).then((response: any) => { + customerService.getTank(userid).then((response: AxiosResponse) => { customer_tank.value = response.data }) } const getCreditCards = (user_id: number) => { - paymentService.getCards(user_id).then((response: any) => { + paymentService.getCards(user_id).then((response: AxiosResponse) => { credit_cards.value = response.data?.cards || [] }) } const getCreditCardsCount = (user_id: number) => { - paymentService.getCardsOnFile(user_id).then((response: any) => { + paymentService.getCardsOnFile(user_id).then((response: AxiosResponse) => { credit_cards_count.value = response.data.cards }) } const getCustomerAutoDelivery = (userid: number) => { - deliveryService.auto.getProfileDeliveries(userid).then((response: any) => { + deliveryService.auto.getProfileDeliveries(userid).then((response: AxiosResponse) => { autodeliveries.value = response.data || [] - console.log(autodeliveries.value) }) } const getCustomerDelivery = (userid: number, delivery_page: number) => { - deliveryService.getByCustomer(userid, delivery_page).then((response: any) => { + deliveryService.getByCustomer(userid, delivery_page).then((response: AxiosResponse) => { deliveries.value = response.data?.deliveries || [] }) } @@ -583,14 +571,14 @@ const removeCard = (card_id: number) => { paymentService.removeCard(card_id).then(() => { credit_cards.value = credit_cards.value.filter(card => card.id !== card_id); credit_cards_count.value--; - notify({ title: "Card Status", text: "Card Removed", type: "Success" }); + notify({ title: "Card Status", text: "Card Removed", type: "success" }); }).catch(() => { notify({ title: "Error", text: "Could not remove card.", type: "error" }); }); } const deleteCall = (delivery_id: number) => { - deliveryService.delete(delivery_id).then((response: any) => { + deliveryService.delete(delivery_id).then((response: AxiosResponse) => { if (response.data.ok) { notify({ title: "Success", text: "deleted delivery", type: "success" }); getPage(1) @@ -601,22 +589,22 @@ const deleteCall = (delivery_id: number) => { } const deleteCustomerSocial = (comment_id: number) => { - adminService.social.deletePost(comment_id).then((response: any) => { + adminService.social.deletePost(comment_id).then((response: AxiosResponse) => { getCustomerSocial(customer.value.id, 1) }) } const getCustomerSocial = (userid: number, delivery_page: number) => { - adminService.social.getPosts(userid, delivery_page).then((response: any) => { + adminService.social.getPosts(userid, delivery_page).then((response: AxiosResponse) => { comments.value = response.data?.posts || [] }) } const CreateSocialComment = (payload: { comment: string; poster_employee_id: number }) => { - adminService.social.createPost(customer.value.id, payload).then((response: any) => { + adminService.social.createPost(customer.value.id, payload).then((response: AxiosResponse) => { if (response.data.ok) { getCustomerSocial(customer.value.id, 1) - } else if (response.data.error) { // Verify error handling logic + } else if (response.data.error) { router.push("/"); } }) @@ -633,7 +621,7 @@ const onSubmitSocial = (commentText: string) => { } const getServiceCalls = (customerId: number) => { - serviceService.getForCustomer(customerId).then((response: any) => { + serviceService.getForCustomer(customerId).then((response: AxiosResponse) => { serviceCalls.value = response.data?.services || []; }).catch((error: any) => { console.error("Failed to get customer service calls:", error); @@ -642,7 +630,7 @@ const getServiceCalls = (customerId: number) => { } const getCustomerTransactions = (customerId: number) => { - paymentService.getCustomerTransactions(customerId, 1).then((response: any) => { + paymentService.getCustomerTransactions(customerId, 1).then((response: AxiosResponse) => { transactions.value = response.data?.transactions || []; }).catch((error: any) => { console.error("Failed to get customer transactions:", error); @@ -685,7 +673,11 @@ const handleDeleteService = async (serviceId: number) => { const fetchCustomerParts = async (customerId: number) => { try { const response = await serviceService.getPartsForCustomer(customerId); - currentParts.value = response.data?.parts || response.data; + if (response.data && 'parts' in response.data && Array.isArray(response.data.parts) && response.data.parts.length > 0) { + currentParts.value = response.data.parts[0]; + } else { + currentParts.value = null; + } } catch (error) { console.error("Failed to fetch customer parts:", error); } diff --git a/src/pages/customer/tank/edit.vue b/src/pages/customer/tank/edit.vue index bbc79b9..45c4940 100644 --- a/src/pages/customer/tank/edit.vue +++ b/src/pages/customer/tank/edit.vue @@ -82,7 +82,7 @@
            -
            + diff --git a/src/pages/delivery/view.vue b/src/pages/delivery/view.vue index 44f4fe7..52057e2 100755 --- a/src/pages/delivery/view.vue +++ b/src/pages/delivery/view.vue @@ -352,7 +352,7 @@
            -
            + diff --git a/src/pages/delivery/viewstatus/cancelled.vue b/src/pages/delivery/viewstatus/cancelled.vue index 778e730..34002e8 100755 --- a/src/pages/delivery/viewstatus/cancelled.vue +++ b/src/pages/delivery/viewstatus/cancelled.vue @@ -123,19 +123,17 @@
            -
            + + \ No newline at end of file diff --git a/src/pages/delivery/viewstatus/todaysdeliveries.vue b/src/pages/delivery/viewstatus/todaysdeliveries.vue index 6829180..1298b7e 100755 --- a/src/pages/delivery/viewstatus/todaysdeliveries.vue +++ b/src/pages/delivery/viewstatus/todaysdeliveries.vue @@ -167,25 +167,27 @@
            -
            + \ No newline at end of file + +// Lifecycle +onMounted(() => { + userStatus(); + loadHolidays(); +}) + + + \ No newline at end of file diff --git a/src/pages/service/ServiceEditModal.vue b/src/pages/service/ServiceEditModal.vue index be21390..3de8b53 100644 --- a/src/pages/service/ServiceEditModal.vue +++ b/src/pages/service/ServiceEditModal.vue @@ -102,8 +102,8 @@ diff --git a/src/pages/service/ServiceHome.vue b/src/pages/service/ServiceHome.vue index df5a664..117c2ce 100644 --- a/src/pages/service/ServiceHome.vue +++ b/src/pages/service/ServiceHome.vue @@ -146,7 +146,7 @@
            -
            + \ No newline at end of file diff --git a/src/pages/service/calender/api.js b/src/pages/service/calender/api.js deleted file mode 100644 index 7e4e57e..0000000 --- a/src/pages/service/calender/api.js +++ /dev/null @@ -1,24 +0,0 @@ -import axios from 'axios'; - -const BASE_URL = import.meta.env.VITE_BASE_URL; - -function authHeader() { - // Return authorization header - return {}; -} - -export function createEvent(payload) { - const path = `${BASE_URL}/service/create`; // Example endpoint - return axios.post(path, payload, { - withCredentials: true, - headers: authHeader(), - }); -} - -export function deleteEventById(eventId) { - const path = `${BASE_URL}/service/delete/${eventId}`; // Example endpoint - return axios.delete(path, { - withCredentials: true, - headers: authHeader(), - }); -} \ No newline at end of file diff --git a/src/pages/ticket/ticketauto.vue b/src/pages/ticket/ticketauto.vue index c710b54..429d6fd 100644 --- a/src/pages/ticket/ticketauto.vue +++ b/src/pages/ticket/ticketauto.vue @@ -107,7 +107,6 @@ import axios from 'axios' import authHeader from '../../services/auth.header' import Header from '../../layouts/headers/headerauth.vue' import SideBar from '../../layouts/sidebar/sidebar.vue' -import Footer from '../../layouts/footers/footer.vue' import { notify } from "@kyvg/vue3-notification" export default defineComponent({ @@ -116,7 +115,6 @@ export default defineComponent({ components: { Header, SideBar, - Footer, }, data() { diff --git a/src/pages/transactions/authorize/index.vue b/src/pages/transactions/authorize/index.vue index 8b09406..f9101fc 100644 --- a/src/pages/transactions/authorize/index.vue +++ b/src/pages/transactions/authorize/index.vue @@ -160,7 +160,7 @@
  • -