From b3e2c1f3244a59c84d4487acb9e98f4d846f1ea9 Mon Sep 17 00:00:00 2001 From: poduck Date: Mon, 1 Dec 2025 02:14:17 -0500 Subject: [PATCH] refactor(frontend): Remove '/api' prefix from all API calls to align with backend URL convention - Updated all API endpoint strings in 'frontend/src' (via sed and manual fixes) to remove the '/api/' prefix. - Manually fixed 'Timeline.tsx' absolute URLs to use the 'api' subdomain and correct path. - Manually fixed 'useAuth.ts' logout fetch URLs. - Updated 'HelpApiDocs.tsx' sandbox URL. - This change, combined with the backend URL update, fully transitions the application to use subdomain-based routing (e.g., 'http://api.lvh.me:8000/resource/') instead of path-prefix routing (e.g., 'http://api.lvh.me:8000/api/resource/'). --- frontend/src/App.tsx | 5 +- frontend/src/components/CreateTaskModal.tsx | 6 +-- frontend/src/components/DevQuickLogin.tsx | 4 +- frontend/src/components/EditTaskModal.tsx | 2 +- frontend/src/components/EmailTemplateForm.tsx | 8 +-- .../src/components/EmailTemplateSelector.tsx | 2 +- frontend/src/components/EventAutomations.tsx | 10 ++-- frontend/src/components/Schedule/Timeline.tsx | 4 +- frontend/src/hooks/useAuth.ts | 11 ++-- frontend/src/hooks/useBusiness.ts | 10 ++-- frontend/src/hooks/useStaff.ts | 6 +-- frontend/src/layouts/PlatformLayout.tsx | 52 +++++++++---------- frontend/src/pages/EmailTemplates.tsx | 6 +-- frontend/src/pages/HelpApiDocs.tsx | 4 +- frontend/src/pages/MyPlugins.tsx | 10 ++-- frontend/src/pages/PluginMarketplace.tsx | 8 +-- frontend/src/pages/Tasks.tsx | 16 +++--- frontend/src/pages/VerifyEmail.tsx | 8 ++- .../components/EditPlatformUserModal.tsx | 2 +- 19 files changed, 92 insertions(+), 82 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 81f05fc..e4c9a2a 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -252,9 +252,10 @@ const AppContent: React.FC = () => { const isRootDomainForUnauthUser = currentHostname === baseDomain || currentHostname === 'localhost'; if (!isRootDomainForUnauthUser) { - // Redirect to root domain login + // Redirect to root domain login (preserve port) const protocol = window.location.protocol; - window.location.href = `${protocol}//${baseDomain}/login`; + const port = window.location.port ? `:${window.location.port}` : ''; + window.location.href = `${protocol}//${baseDomain}${port}/login`; return ; } diff --git a/frontend/src/components/CreateTaskModal.tsx b/frontend/src/components/CreateTaskModal.tsx index c961f74..8b50881 100644 --- a/frontend/src/components/CreateTaskModal.tsx +++ b/frontend/src/components/CreateTaskModal.tsx @@ -123,7 +123,7 @@ const CreateTaskModal: React.FC = ({ isOpen, onClose, onSu const { data: plugins = [], isLoading: pluginsLoading } = useQuery({ queryKey: ['plugin-installations'], queryFn: async () => { - const { data } = await axios.get('/api/plugin-installations/'); + const { data } = await axios.get('/plugin-installations/'); // Filter out plugins that already have scheduled tasks return data.filter((p: PluginInstallation) => !p.scheduled_task); }, @@ -209,7 +209,7 @@ const CreateTaskModal: React.FC = ({ isOpen, onClose, onSu apply_to_existing: applyToExisting, }; - await axios.post('/api/global-event-plugins/', payload); + await axios.post('/global-event-plugins/', payload); queryClient.invalidateQueries({ queryKey: ['global-event-plugins'] }); toast.success(applyToExisting ? 'Plugin attached to all events' : 'Plugin will apply to future events'); } else { @@ -240,7 +240,7 @@ const CreateTaskModal: React.FC = ({ isOpen, onClose, onSu } } - await axios.post('/api/scheduled-tasks/', payload); + await axios.post('/scheduled-tasks/', payload); toast.success('Scheduled task created'); } diff --git a/frontend/src/components/DevQuickLogin.tsx b/frontend/src/components/DevQuickLogin.tsx index afb457d..c8fcd7a 100644 --- a/frontend/src/components/DevQuickLogin.tsx +++ b/frontend/src/components/DevQuickLogin.tsx @@ -89,7 +89,7 @@ export function DevQuickLogin({ embedded = false }: DevQuickLoginProps) { setLoading(user.username); try { // Call token auth API - const response = await apiClient.post('/api/auth-token/', { + const response = await apiClient.post('/auth-token/', { username: user.username, password: user.password, }); @@ -98,7 +98,7 @@ export function DevQuickLogin({ embedded = false }: DevQuickLoginProps) { setCookie('access_token', response.data.token, 7); // Fetch user data to determine redirect - const userResponse = await apiClient.get('/api/auth/me/'); + const userResponse = await apiClient.get('/auth/me/'); const userData = userResponse.data; // Determine the correct subdomain based on user role diff --git a/frontend/src/components/EditTaskModal.tsx b/frontend/src/components/EditTaskModal.tsx index 619e779..fa12076 100644 --- a/frontend/src/components/EditTaskModal.tsx +++ b/frontend/src/components/EditTaskModal.tsx @@ -167,7 +167,7 @@ const EditTaskModal: React.FC = ({ task, isOpen, onClose, on } } - await axios.patch(`/api/scheduled-tasks/${task.id}/`, payload); + await axios.patch(`/scheduled-tasks/${task.id}/`, payload); onSuccess(); handleClose(); } catch (err: any) { diff --git a/frontend/src/components/EmailTemplateForm.tsx b/frontend/src/components/EmailTemplateForm.tsx index 47d726f..2bf0f2c 100644 --- a/frontend/src/components/EmailTemplateForm.tsx +++ b/frontend/src/components/EmailTemplateForm.tsx @@ -49,7 +49,7 @@ const EmailTemplateForm: React.FC = ({ const { data: variablesData } = useQuery<{ variables: EmailTemplateVariableGroup[] }>({ queryKey: ['email-template-variables'], queryFn: async () => { - const { data } = await api.get('/api/email-templates/variables/'); + const { data } = await api.get('/email-templates/variables/'); return data; }, }); @@ -57,7 +57,7 @@ const EmailTemplateForm: React.FC = ({ // Preview mutation const previewMutation = useMutation({ mutationFn: async () => { - const { data } = await api.post('/api/email-templates/preview/', { + const { data } = await api.post('/email-templates/preview/', { subject, html_content: htmlContent, text_content: textContent, @@ -80,10 +80,10 @@ const EmailTemplateForm: React.FC = ({ }; if (isEditing && template) { - const { data } = await api.patch(`/api/email-templates/${template.id}/`, payload); + const { data } = await api.patch(`/email-templates/${template.id}/`, payload); return data; } else { - const { data } = await api.post('/api/email-templates/', payload); + const { data } = await api.post('/email-templates/', payload); return data; } }, diff --git a/frontend/src/components/EmailTemplateSelector.tsx b/frontend/src/components/EmailTemplateSelector.tsx index f24414e..a757380 100644 --- a/frontend/src/components/EmailTemplateSelector.tsx +++ b/frontend/src/components/EmailTemplateSelector.tsx @@ -32,7 +32,7 @@ const EmailTemplateSelector: React.FC = ({ queryFn: async () => { const params = new URLSearchParams(); if (category) params.append('category', category); - const { data } = await api.get(`/api/email-templates/?${params.toString()}`); + const { data } = await api.get(`/email-templates/?${params.toString()}`); return data.map((t: any) => ({ id: String(t.id), name: t.name, diff --git a/frontend/src/components/EventAutomations.tsx b/frontend/src/components/EventAutomations.tsx index b1bf976..41c7573 100644 --- a/frontend/src/components/EventAutomations.tsx +++ b/frontend/src/components/EventAutomations.tsx @@ -72,7 +72,7 @@ const EventAutomations: React.FC = ({ eventId, compact = const { data: plugins = [] } = useQuery({ queryKey: ['plugin-installations'], queryFn: async () => { - const { data } = await axios.get('/api/plugin-installations/'); + const { data } = await axios.get('/plugin-installations/'); return data; }, }); @@ -81,7 +81,7 @@ const EventAutomations: React.FC = ({ eventId, compact = const { data: eventPlugins = [], isLoading } = useQuery({ queryKey: ['event-plugins', eventId], queryFn: async () => { - const { data } = await axios.get(`/api/event-plugins/?event_id=${eventId}`); + const { data } = await axios.get(`/event-plugins/?event_id=${eventId}`); return data; }, enabled: !!eventId, @@ -90,7 +90,7 @@ const EventAutomations: React.FC = ({ eventId, compact = // Add plugin mutation const addMutation = useMutation({ mutationFn: async (data: { plugin_installation: string; trigger: string; offset_minutes: number }) => { - return axios.post('/api/event-plugins/', { + return axios.post('/event-plugins/', { event: eventId, ...data, }); @@ -111,7 +111,7 @@ const EventAutomations: React.FC = ({ eventId, compact = // Toggle mutation const toggleMutation = useMutation({ mutationFn: async (pluginId: string) => { - return axios.post(`/api/event-plugins/${pluginId}/toggle/`); + return axios.post(`/event-plugins/${pluginId}/toggle/`); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['event-plugins', eventId] }); @@ -121,7 +121,7 @@ const EventAutomations: React.FC = ({ eventId, compact = // Delete mutation const deleteMutation = useMutation({ mutationFn: async (pluginId: string) => { - return axios.delete(`/api/event-plugins/${pluginId}/`); + return axios.delete(`/event-plugins/${pluginId}/`); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['event-plugins', eventId] }); diff --git a/frontend/src/components/Schedule/Timeline.tsx b/frontend/src/components/Schedule/Timeline.tsx index 9d0c6ec..3aabc5e 100644 --- a/frontend/src/components/Schedule/Timeline.tsx +++ b/frontend/src/components/Schedule/Timeline.tsx @@ -39,7 +39,7 @@ export const Timeline: React.FC = () => { const { data: resources = [] } = useQuery({ queryKey: ['resources'], queryFn: async () => { - const response = await axios.get('http://lvh.me:8000/api/resources/'); + const response = await axios.get('http://api.lvh.me:8000/resources/'); return adaptResources(response.data); } }); @@ -47,7 +47,7 @@ export const Timeline: React.FC = () => { const { data: backendAppointments = [] } = useQuery({ // Renamed to backendAppointments to avoid conflict with localEvents queryKey: ['appointments'], queryFn: async () => { - const response = await axios.get('http://lvh.me:8000/api/appointments/'); + const response = await axios.get('http://api.lvh.me:8000/appointments/'); return response.data; // Still return raw data, adapt in useEffect } }); diff --git a/frontend/src/hooks/useAuth.ts b/frontend/src/hooks/useAuth.ts index 2820551..30c9649 100644 --- a/frontend/src/hooks/useAuth.ts +++ b/frontend/src/hooks/useAuth.ts @@ -95,8 +95,11 @@ export const useLogout = () => { queryClient.removeQueries({ queryKey: ['currentUser'] }); queryClient.clear(); - // Redirect to login page - window.location.href = '/login'; + // Redirect to login page on root domain + const protocol = window.location.protocol; + const baseDomain = getBaseDomain(); + const port = window.location.port ? `:${window.location.port}` : ''; + window.location.href = `${protocol}//${baseDomain}${port}/login`; }, }); }; @@ -150,7 +153,7 @@ export const useMasquerade = () => { // Call logout API to clear HttpOnly sessionid cookie try { const apiUrl = import.meta.env.VITE_API_URL || `${window.location.protocol}//${baseDomain}`; - await fetch(`${apiUrl}/api/auth/logout/`, { + await fetch(`${apiUrl}/auth/logout/`, { method: 'POST', credentials: 'include', }); @@ -222,7 +225,7 @@ export const useStopMasquerade = () => { // CRITICAL: Clear the session cookie BEFORE redirect try { const apiUrl = import.meta.env.VITE_API_URL || `${window.location.protocol}//${baseDomain}`; - await fetch(`${apiUrl}/api/auth/logout/`, { + await fetch(`${apiUrl}/auth/logout/`, { method: 'POST', credentials: 'include', }); diff --git a/frontend/src/hooks/useBusiness.ts b/frontend/src/hooks/useBusiness.ts index 38dd8cb..701c4b7 100644 --- a/frontend/src/hooks/useBusiness.ts +++ b/frontend/src/hooks/useBusiness.ts @@ -23,7 +23,7 @@ export const useCurrentBusiness = () => { return null; // No token, return null instead of making request } - const { data } = await apiClient.get('/api/business/current/'); + const { data } = await apiClient.get('/business/current/'); // Transform backend format to frontend format return { @@ -96,7 +96,7 @@ export const useUpdateBusiness = () => { backendData.customer_dashboard_content = updates.customerDashboardContent; } - const { data } = await apiClient.patch('/api/business/current/update/', backendData); + const { data } = await apiClient.patch('/business/current/update/', backendData); return data; }, onSuccess: () => { @@ -112,7 +112,7 @@ export const useResources = () => { return useQuery({ queryKey: ['resources'], queryFn: async () => { - const { data } = await apiClient.get('/api/resources/'); + const { data } = await apiClient.get('/resources/'); return data; }, staleTime: 5 * 60 * 1000, // 5 minutes @@ -127,7 +127,7 @@ export const useCreateResource = () => { return useMutation({ mutationFn: async (resourceData: { name: string; type: string; user_id?: string }) => { - const { data } = await apiClient.post('/api/resources/', resourceData); + const { data } = await apiClient.post('/resources/', resourceData); return data; }, onSuccess: () => { @@ -143,7 +143,7 @@ export const useBusinessUsers = () => { return useQuery({ queryKey: ['businessUsers'], queryFn: async () => { - const { data } = await apiClient.get('/api/staff/'); + const { data } = await apiClient.get('/staff/'); return data; }, staleTime: 5 * 60 * 1000, // 5 minutes diff --git a/frontend/src/hooks/useStaff.ts b/frontend/src/hooks/useStaff.ts index f74a6bd..172eeda 100644 --- a/frontend/src/hooks/useStaff.ts +++ b/frontend/src/hooks/useStaff.ts @@ -36,7 +36,7 @@ export const useStaff = (filters?: StaffFilters) => { if (filters?.search) params.append('search', filters.search); params.append('show_inactive', 'true'); // Always fetch inactive staff too - const { data } = await apiClient.get(`/api/staff/?${params}`); + const { data } = await apiClient.get(`/staff/?${params}`); // Transform backend format to frontend format return data.map((s: any) => ({ @@ -68,7 +68,7 @@ export const useUpdateStaff = () => { id: string; updates: { is_active?: boolean; permissions?: StaffPermissions }; }) => { - const { data } = await apiClient.patch(`/api/staff/${id}/`, updates); + const { data } = await apiClient.patch(`/staff/${id}/`, updates); return data; }, onSuccess: () => { @@ -86,7 +86,7 @@ export const useToggleStaffActive = () => { return useMutation({ mutationFn: async (id: string) => { - const { data } = await apiClient.post(`/api/staff/${id}/toggle_active/`); + const { data } = await apiClient.post(`/staff/${id}/toggle_active/`); return data; }, onSuccess: () => { diff --git a/frontend/src/layouts/PlatformLayout.tsx b/frontend/src/layouts/PlatformLayout.tsx index d78650b..8288a27 100644 --- a/frontend/src/layouts/PlatformLayout.tsx +++ b/frontend/src/layouts/PlatformLayout.tsx @@ -24,7 +24,7 @@ const PlatformLayout: React.FC = ({ user, darkMode, toggleT useScrollToTop(); // Fetch ticket data when modal is opened from notification - const { data: ticketFromNotification } = useTicket(ticketModalId || undefined); + const { data: ticketFromNotification } = useTicket(ticketModalId && ticketModalId !== 'undefined' ? ticketModalId : undefined); const handleTicketClick = (ticketId: string) => { setTicketModalId(ticketId); @@ -38,7 +38,7 @@ const PlatformLayout: React.FC = ({ user, darkMode, toggleT
{/* Mobile menu */}
- {}} /> + { }} />
{isMobileMenuOpen &&
setIsMobileMenuOpen(false)}>
} @@ -51,32 +51,32 @@ const PlatformLayout: React.FC = ({ user, darkMode, toggleT
{/* Platform Top Bar */}
-
- -
- - smoothschedule.com - / - Admin Console -
+
+ +
+ + smoothschedule.com + / + Admin Console
+
-
- - - -
+
+ + + +
diff --git a/frontend/src/pages/EmailTemplates.tsx b/frontend/src/pages/EmailTemplates.tsx index c3d7d7e..1c1c16f 100644 --- a/frontend/src/pages/EmailTemplates.tsx +++ b/frontend/src/pages/EmailTemplates.tsx @@ -62,7 +62,7 @@ const EmailTemplates: React.FC = () => { const { data: templates = [], isLoading, error } = useQuery({ queryKey: ['email-templates'], queryFn: async () => { - const { data } = await api.get('/api/email-templates/'); + const { data } = await api.get('/email-templates/'); return data.map((t: any) => ({ id: String(t.id), name: t.name, @@ -85,7 +85,7 @@ const EmailTemplates: React.FC = () => { // Delete template mutation const deleteMutation = useMutation({ mutationFn: async (templateId: string) => { - await api.delete(`/api/email-templates/${templateId}/`); + await api.delete(`/email-templates/${templateId}/`); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['email-templates'] }); @@ -97,7 +97,7 @@ const EmailTemplates: React.FC = () => { // Duplicate template mutation const duplicateMutation = useMutation({ mutationFn: async (templateId: string) => { - const { data } = await api.post(`/api/email-templates/${templateId}/duplicate/`); + const { data } = await api.post(`/email-templates/${templateId}/duplicate/`); return data; }, onSuccess: () => { diff --git a/frontend/src/pages/HelpApiDocs.tsx b/frontend/src/pages/HelpApiDocs.tsx index d684cb5..1a615b2 100644 --- a/frontend/src/pages/HelpApiDocs.tsx +++ b/frontend/src/pages/HelpApiDocs.tsx @@ -41,7 +41,7 @@ const LANGUAGES: Record = { // Default test credentials (used when no tokens are available) const DEFAULT_TEST_API_KEY = 'ss_test_'; const DEFAULT_TEST_WEBHOOK_SECRET = 'whsec_test_abc123def456ghi789jkl012mno345pqr678'; -const SANDBOX_URL = 'https://sandbox.smoothschedule.com/api/v1'; +const SANDBOX_URL = 'https://sandbox.smoothschedule.com/v1'; // Multi-language code interface interface MultiLangCode { @@ -1111,7 +1111,7 @@ my $response = $ua->get('${SANDBOX_URL}/services/', )} { const { data: plugins = [], isLoading, error } = useQuery({ queryKey: ['plugin-installations'], queryFn: async () => { - const { data } = await api.get('/api/plugin-installations/'); + const { data } = await api.get('/plugin-installations/'); return data.map((p: any) => ({ id: String(p.id), template: String(p.template), @@ -88,7 +88,7 @@ const MyPlugins: React.FC = () => { // Uninstall plugin mutation const uninstallMutation = useMutation({ mutationFn: async (pluginId: string) => { - await api.delete(`/api/plugin-installations/${pluginId}/`); + await api.delete(`/plugin-installations/${pluginId}/`); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['plugin-installations'] }); @@ -100,7 +100,7 @@ const MyPlugins: React.FC = () => { // Rate plugin mutation const rateMutation = useMutation({ mutationFn: async ({ pluginId, rating, review }: { pluginId: string; rating: number; review: string }) => { - const { data } = await api.post(`/api/plugin-installations/${pluginId}/rate/`, { + const { data } = await api.post(`/plugin-installations/${pluginId}/rate/`, { rating, review, }); @@ -118,7 +118,7 @@ const MyPlugins: React.FC = () => { // Update plugin mutation const updateMutation = useMutation({ mutationFn: async (pluginId: string) => { - const { data } = await api.post(`/api/plugin-installations/${pluginId}/update/`); + const { data } = await api.post(`/plugin-installations/${pluginId}/update/`); return data; }, onSuccess: () => { @@ -129,7 +129,7 @@ const MyPlugins: React.FC = () => { // Edit config mutation const editConfigMutation = useMutation({ mutationFn: async ({ pluginId, configValues }: { pluginId: string; configValues: Record }) => { - const { data } = await api.patch(`/api/plugin-installations/${pluginId}/`, { + const { data } = await api.patch(`/plugin-installations/${pluginId}/`, { config_values: configValues, }); return data; diff --git a/frontend/src/pages/PluginMarketplace.tsx b/frontend/src/pages/PluginMarketplace.tsx index a0d5e65..024a1e7 100644 --- a/frontend/src/pages/PluginMarketplace.tsx +++ b/frontend/src/pages/PluginMarketplace.tsx @@ -95,7 +95,7 @@ const PluginMarketplace: React.FC = () => { const { data: plugins = [], isLoading, error } = useQuery({ queryKey: ['plugin-templates', 'marketplace'], queryFn: async () => { - const { data } = await api.get('/api/plugin-templates/?view=marketplace'); + const { data } = await api.get('/plugin-templates/?view=marketplace'); return data.map((p: any) => ({ id: String(p.id), name: p.name, @@ -120,7 +120,7 @@ const PluginMarketplace: React.FC = () => { const { data: installedPlugins = [] } = useQuery<{ template: number }[]>({ queryKey: ['plugin-installations'], queryFn: async () => { - const { data } = await api.get('/api/plugin-installations/'); + const { data } = await api.get('/plugin-installations/'); return data; }, }); @@ -133,7 +133,7 @@ const PluginMarketplace: React.FC = () => { // Install plugin mutation const installMutation = useMutation({ mutationFn: async (templateId: string) => { - const { data } = await api.post('/api/plugin-installations/', { + const { data } = await api.post('/plugin-installations/', { template: templateId, }); return data; @@ -187,7 +187,7 @@ const PluginMarketplace: React.FC = () => { // Fetch full plugin details including plugin_code setIsLoadingDetails(true); try { - const { data } = await api.get(`/api/plugin-templates/${plugin.id}/`); + const { data } = await api.get(`/plugin-templates/${plugin.id}/`); setSelectedPlugin({ ...plugin, pluginCode: data.plugin_code, diff --git a/frontend/src/pages/Tasks.tsx b/frontend/src/pages/Tasks.tsx index ae59c1c..5014ebd 100644 --- a/frontend/src/pages/Tasks.tsx +++ b/frontend/src/pages/Tasks.tsx @@ -99,7 +99,7 @@ const Tasks: React.FC = () => { const { data: scheduledTasks = [], isLoading: tasksLoading } = useQuery({ queryKey: ['scheduled-tasks'], queryFn: async () => { - const { data } = await axios.get('/api/scheduled-tasks/'); + const { data } = await axios.get('/scheduled-tasks/'); return data; }, }); @@ -108,7 +108,7 @@ const Tasks: React.FC = () => { const { data: eventAutomations = [], isLoading: automationsLoading } = useQuery({ queryKey: ['global-event-plugins'], queryFn: async () => { - const { data } = await axios.get('/api/global-event-plugins/'); + const { data } = await axios.get('/global-event-plugins/'); return data; }, }); @@ -129,7 +129,7 @@ const Tasks: React.FC = () => { // Delete task const deleteMutation = useMutation({ mutationFn: async (taskId: string) => { - await axios.delete(`/api/scheduled-tasks/${taskId}/`); + await axios.delete(`/scheduled-tasks/${taskId}/`); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['scheduled-tasks'] }); @@ -143,7 +143,7 @@ const Tasks: React.FC = () => { // Toggle task active status const toggleActiveMutation = useMutation({ mutationFn: async ({ taskId, status }: { taskId: string; status: 'ACTIVE' | 'PAUSED' }) => { - await axios.patch(`/api/scheduled-tasks/${taskId}/`, { status }); + await axios.patch(`/scheduled-tasks/${taskId}/`, { status }); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['scheduled-tasks'] }); @@ -157,7 +157,7 @@ const Tasks: React.FC = () => { // Trigger task manually const triggerMutation = useMutation({ mutationFn: async (taskId: string) => { - await axios.post(`/api/scheduled-tasks/${taskId}/trigger/`); + await axios.post(`/scheduled-tasks/${taskId}/trigger/`); }, onSuccess: () => { toast.success('Task triggered successfully'); @@ -170,7 +170,7 @@ const Tasks: React.FC = () => { // Delete event automation const deleteEventAutomationMutation = useMutation({ mutationFn: async (automationId: string) => { - await axios.delete(`/api/global-event-plugins/${automationId}/`); + await axios.delete(`/global-event-plugins/${automationId}/`); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['global-event-plugins'] }); @@ -184,7 +184,7 @@ const Tasks: React.FC = () => { // Toggle event automation active status const toggleEventAutomationMutation = useMutation({ mutationFn: async (automationId: string) => { - await axios.post(`/api/global-event-plugins/${automationId}/toggle/`); + await axios.post(`/global-event-plugins/${automationId}/toggle/`); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['global-event-plugins'] }); @@ -198,7 +198,7 @@ const Tasks: React.FC = () => { // Update event automation const updateEventAutomationMutation = useMutation({ mutationFn: async ({ id, data }: { id: string; data: Partial }) => { - await axios.patch(`/api/global-event-plugins/${id}/`, data); + await axios.patch(`/global-event-plugins/${id}/`, data); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['global-event-plugins'] }); diff --git a/frontend/src/pages/VerifyEmail.tsx b/frontend/src/pages/VerifyEmail.tsx index 3782e4c..057e94f 100644 --- a/frontend/src/pages/VerifyEmail.tsx +++ b/frontend/src/pages/VerifyEmail.tsx @@ -3,6 +3,7 @@ import { useSearchParams, useNavigate } from 'react-router-dom'; import { CheckCircle, XCircle, Loader2, Mail, ShieldCheck } from 'lucide-react'; import apiClient from '../api/client'; import { deleteCookie } from '../utils/cookies'; +import { getBaseDomain } from '../utils/domain'; type VerificationStatus = 'pending' | 'loading' | 'success' | 'error' | 'already_verified'; @@ -115,7 +116,12 @@ const VerifyEmail: React.FC = () => { Your email address has been successfully verified. You can now sign in to your account.