Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"hosting_tab_LOCAL_SEO": "Visibility Pro",
"hosting_tab_LOCAL_SEO_description": "Seien Sie dort präsent, wo Ihre Kund:innen Sie suchen, aber auch dort, wo sie über Sie sprechen. Mit dieser Lösung für lokale Referenzierung verwalten Sie die Informationen zu Ihrem Unternehmen und Kontaktdaten auf Referenzierungsplattformen und Kundenbewertungsportalen über ein einziges intuitives Interface.",
"hosting_dashboard_local_seo_visibility_check": "Überprüfen Sie Ihre lokale Referenzierung.",
"hosting_tab_LOCAL_SEO_table_header_name": "Name des Unternehmens",
"hosting_tab_LOCAL_SEO_table_header_email": "E-Mail-Account",
"hosting_tab_LOCAL_SEO_table_header_address": "Adresse",
"hosting_tab_LOCAL_SEO_table_value_undefined": "Zu definieren",
"hosting_tab_LOCAL_SEO_state_created": "OK",
"hosting_tab_LOCAL_SEO_state_creating": "Wird erstellt",
"hosting_tab_LOCAL_SEO_state_deleting": "Wird gelöscht",
"hosting_tab_LOCAL_SEO_access_interface": "Zum Interface",
"hosting_tab_LOCAL_SEO_delete": "Abonnement löschen",
"hosting_tab_LOCAL_SEO_delete_confirm": "Sind Sie sicher, dass Sie Ihr „Visibility Pro“ Abonnement für den folgenden Account kündigen möchten?",
"hosting_tab_LOCAL_SEO_delete_success": "Die Löschung des „Visibility Pro“ Abonnements wurde registriert.",
"hosting_tab_LOCAL_SEO_delete_error": "Beim Löschen Ihres „Visibility Pro“ Abonnements ist ein Fehler aufgetreten. {{error}}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"hosting_tab_LOCAL_SEO": "Visibility Pro",
"hosting_tab_LOCAL_SEO_description": "Ensure that your company appears when your customers search for you, and where you do business. With this local SEO ranking solution, you can manage your company information and contact details on SEO platforms and customer review platforms - and you can do this all via a unique, intuitive interface.",
"hosting_dashboard_local_seo_visibility_check": "Check your local online presence",
"hosting_tab_LOCAL_SEO_table_header_name": "Company name",
"hosting_tab_LOCAL_SEO_table_header_email": "Email account",
"hosting_tab_LOCAL_SEO_table_header_address": "Address",
"hosting_tab_LOCAL_SEO_table_value_undefined": "To be defined",
"hosting_tab_LOCAL_SEO_state_created": "OK",
"hosting_tab_LOCAL_SEO_state_creating": "Creating...",
"hosting_tab_LOCAL_SEO_state_deleting": "Deleting...",
"hosting_tab_LOCAL_SEO_access_interface": "Access the interface",
"hosting_tab_LOCAL_SEO_delete": "Remove the subscription",
"hosting_tab_LOCAL_SEO_delete_confirm": "Are you sure you want to cancel your Visibility Pro account?",
"hosting_tab_LOCAL_SEO_delete_success": "Your cancellation request for this Visibility Pro account has been successfully submitted.",
"hosting_tab_LOCAL_SEO_delete_error": "An error has occurred cancelling your Pro Visibility subscription: {{error}}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"hosting_tab_LOCAL_SEO": "Visibilidad Pro",
"hosting_tab_LOCAL_SEO_description": "Aparezca no solo donde sus clientes le buscan, sino también donde hablan de usted. Esta solución de posicionamiento local le permite gestionar, a través de una intuitiva interfaz única, la información y los datos de su empresa en las plataformas de posicionamiento y de opiniones de clientes.",
"hosting_dashboard_local_seo_visibility_check": "Compruebe su posicionamiento local",
"hosting_tab_LOCAL_SEO_table_header_name": "Nombre de la empresa",
"hosting_tab_LOCAL_SEO_table_header_email": "Cuenta de correo electrónico",
"hosting_tab_LOCAL_SEO_table_header_address": "Dirección",
"hosting_tab_LOCAL_SEO_table_value_undefined": "Por determinar",
"hosting_tab_LOCAL_SEO_state_created": "OK",
"hosting_tab_LOCAL_SEO_state_creating": "Creando...",
"hosting_tab_LOCAL_SEO_state_deleting": "Eliminando...",
"hosting_tab_LOCAL_SEO_access_interface": "Acceder al panel",
"hosting_tab_LOCAL_SEO_delete": "Eliminar la suscripción",
"hosting_tab_LOCAL_SEO_delete_confirm": "¿Seguro que quiere dar de baja la suscripción «Visibilidad Pro» para la siguiente cuenta?",
"hosting_tab_LOCAL_SEO_delete_success": "La solicitud de eliminación de la suscripción «Visibilidad Pro» se ha enviado.",
"hosting_tab_LOCAL_SEO_delete_error": "Se ha producido un error al eliminar la suscripción «Visibilidad Pro». {{error}}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"hosting_tab_LOCAL_SEO": "Visibilité Pro",
"hosting_tab_LOCAL_SEO_description": "Soyez présents là où vos clients vous cherchent, mais aussi là où ils parlent de vous. Cette solution de référencement local vous permet de gérer, via une interface unique et intuitive, vos informations et coordonnées d'entreprise sur les plateformes de référencement et d'avis client.",
"hosting_dashboard_local_seo_visibility_check": "Vérifiez votre référencement local",
"hosting_tab_LOCAL_SEO_table_header_name": "Nom de l'entreprise",
"hosting_tab_LOCAL_SEO_table_header_email": "Compte Email",
"hosting_tab_LOCAL_SEO_table_header_address": "Adresse",
"hosting_tab_LOCAL_SEO_table_value_undefined": "À définir",
"hosting_tab_LOCAL_SEO_state_created": "OK",
"hosting_tab_LOCAL_SEO_state_creating": "Création en cours",
"hosting_tab_LOCAL_SEO_state_deleting": "Suppression en cours",
"hosting_tab_LOCAL_SEO_access_interface": "Accéder à l'interface",
"hosting_tab_LOCAL_SEO_delete": "Supprimer l'abonnement",
"hosting_tab_LOCAL_SEO_delete_confirm": "Êtes-vous sûr de vouloir résilier votre abonnement «Visibilité Pro» pour le compte suivant ?",
"hosting_tab_LOCAL_SEO_delete_success": "La suppression de l'abonnement «Visibilité Pro» a bien été prise en compte.",
"hosting_tab_LOCAL_SEO_delete_error": "Une erreur est survenue lors de la suppression de votre abonnement «Visibilité Pro». {{error}}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"hosting_tab_LOCAL_SEO": "Visibilité Pro",
"hosting_tab_LOCAL_SEO_description": "Soyez présents là où vos clients vous cherchent, mais aussi là où ils parlent de vous. Cette solution de référencement local vous permet de gérer, via une interface unique et intuitive, vos informations et coordonnées d'entreprise sur les plateformes de référencement et d'avis client.",
"hosting_dashboard_local_seo_visibility_check": "Vérifiez votre référencement local",
"hosting_tab_LOCAL_SEO_table_header_name": "Nom de l'entreprise",
"hosting_tab_LOCAL_SEO_table_header_email": "Compte Email",
"hosting_tab_LOCAL_SEO_table_header_address": "Adresse",
"hosting_tab_LOCAL_SEO_table_value_undefined": "À définir",
"hosting_tab_LOCAL_SEO_state_created": "OK",
"hosting_tab_LOCAL_SEO_state_creating": "Création en cours",
"hosting_tab_LOCAL_SEO_state_deleting": "Suppression en cours",
"hosting_tab_LOCAL_SEO_access_interface": "Accéder à l'interface",
"hosting_tab_LOCAL_SEO_delete": "Supprimer l'abonnement",
"hosting_tab_LOCAL_SEO_delete_confirm": "Êtes-vous sûr de vouloir résilier votre abonnement «Visibilité Pro» pour le compte suivant ?",
"hosting_tab_LOCAL_SEO_delete_success": "La suppression de l'abonnement «Visibilité Pro» a bien été prise en compte.",
"hosting_tab_LOCAL_SEO_delete_error": "Une erreur est survenue lors de la suppression de votre abonnement «Visibilité Pro». {{error}}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"hosting_tab_LOCAL_SEO": "Visibility Pro",
"hosting_tab_LOCAL_SEO_description": "Assicurati che la tua azienda sia visibile nel momento in cui i tuoi clienti la cercano o ne parlano. Questa soluzione di referenziamento locale ti consente di gestire, attraverso un'interfaccia unica e intuitiva, le informazioni e le coordinate della tua azienda sulle piattaforme di SEO e recensioni dei clienti.",
"hosting_dashboard_local_seo_visibility_check": "Verifica il tuo posizionamento locale",
"hosting_tab_LOCAL_SEO_table_header_name": "Nome dell'azienda",
"hosting_tab_LOCAL_SEO_table_header_email": "Account email",
"hosting_tab_LOCAL_SEO_table_header_address": "Indirizzo",
"hosting_tab_LOCAL_SEO_table_value_undefined": "Da definire",
"hosting_tab_LOCAL_SEO_state_created": "OK",
"hosting_tab_LOCAL_SEO_state_creating": "Creazione in corso...",
"hosting_tab_LOCAL_SEO_state_deleting": "Eliminazione in corso...",
"hosting_tab_LOCAL_SEO_access_interface": "Accedi all'interfaccia",
"hosting_tab_LOCAL_SEO_delete": "Elimina l'abbonamento",
"hosting_tab_LOCAL_SEO_delete_confirm": "Vuoi davvero cancellare l'abbonamento \"Visibility Pro\" per il seguente account?",
"hosting_tab_LOCAL_SEO_delete_success": "La cancellazione dell'abbonamento \"Visibility Pro\" è in fase di elaborazione.",
"hosting_tab_LOCAL_SEO_delete_error": "Si è verificato un errore durante la cancellazione del tuo abbonamento \"Visibility Pro\": {{error}}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"hosting_tab_LOCAL_SEO": "Widoczna firma",
"hosting_tab_LOCAL_SEO_description": "Bądź obecny tam, gdzie szukają Cię Twoi klienci, ale również wszędzie, gdzie o Tobie mówią. Narzędzie do lokalnego pozycjonowania pozwala w prosty sposób zarządzać informacjami o Twojej firmie w internecie i w serwisach z opiniami klientów.",
"hosting_dashboard_local_seo_visibility_check": "Sprawdź Twoją lokalną obecność",
"hosting_tab_LOCAL_SEO_table_header_name": "Nazwa firmy",
"hosting_tab_LOCAL_SEO_table_header_email": "Konto e-mail",
"hosting_tab_LOCAL_SEO_table_header_address": "Adres",
"hosting_tab_LOCAL_SEO_table_value_undefined": "Do określenia",
"hosting_tab_LOCAL_SEO_state_created": "OK",
"hosting_tab_LOCAL_SEO_state_creating": "Trwa tworzenie",
"hosting_tab_LOCAL_SEO_state_deleting": "Trwa usuwanie",
"hosting_tab_LOCAL_SEO_access_interface": "Zaloguj się do interfejsu",
"hosting_tab_LOCAL_SEO_delete": "Usuń subskrypcję",
"hosting_tab_LOCAL_SEO_delete_confirm": "Czy na pewno chcesz zrezygnować z subskrypcji pakietu „Widoczna firma\" dla tego konta?",
"hosting_tab_LOCAL_SEO_delete_success": "Żądanie usunięcia subskrypcji pakietu „Widoczna firma\" zostało wysłane.",
"hosting_tab_LOCAL_SEO_delete_error": "Wystąpił błąd podczas usuwania subskrypcji pakietu „Widoczna firma\". {{error}}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"hosting_tab_LOCAL_SEO": "Visibilidade Pro",
"hosting_tab_LOCAL_SEO_description": "Esteja presente onde os seus clientes o procuram, mas também onde falam de si. Esta solução de SEO local permite-lhe gerir, através de uma interface única e intuitiva, as suas informações e os dados da sua empresa nas plataformas de SEO e de opiniões de clientes.",
"hosting_dashboard_local_seo_visibility_check": "Verifique o seu SEO local",
"hosting_tab_LOCAL_SEO_table_header_name": "Nome da empresa",
"hosting_tab_LOCAL_SEO_table_header_email": "Conta de e-mail",
"hosting_tab_LOCAL_SEO_table_header_address": "Morada",
"hosting_tab_LOCAL_SEO_table_value_undefined": "Por definir",
"hosting_tab_LOCAL_SEO_state_created": "OK",
"hosting_tab_LOCAL_SEO_state_creating": "Criação em curso",
"hosting_tab_LOCAL_SEO_state_deleting": "Eliminação em curso",
"hosting_tab_LOCAL_SEO_access_interface": "Aceder à interface",
"hosting_tab_LOCAL_SEO_delete": "Eliminar a subscrição",
"hosting_tab_LOCAL_SEO_delete_confirm": "Tem a certeza de que pretende cancelar a sua subscrição de \"Visibilidade Pro\" para a seguinte conta?",
"hosting_tab_LOCAL_SEO_delete_success": "A eliminação da subscrição de \"Visibilidade Pro\" foi bem-sucedida.",
"hosting_tab_LOCAL_SEO_delete_error": "Ocorreu um erro ao eliminar a subscrição de \"Visibilidade Pro\". {{error}}"
}
10 changes: 10 additions & 0 deletions packages/manager/apps/web-hosting/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,13 @@ export enum ACTIONS {
ORDER = 'ORDER',
ATTACH = 'ATTACH',
}

export const LOCAL_SEO_VISIBILITY_CHECKER =
'https://www.ovh.com/fr/hebergement-web/referencement-local.xml';

export const LOCAL_SEO_ORDER_OPTIONS_SERVICE = {
FR: "https://www.ovh.com/fr/order/domain/#/legacy/domain/hosting/choose?options=~(flow~'hosting_existing_service~serviceName~'{serviceName})",
};

export const LOCAL_SEO_INTERFACE =
'https://localseo.hosting.ovh.net/{lang}/app/ovh?access_token={token}';
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './webHostingDashboard';
export * from './ssl';
export * from './tasks';
export * from './managedWordpress/mocks';
export * from './localSeo';
17 changes: 17 additions & 0 deletions packages/manager/apps/web-hosting/src/data/__mocks__/localSeo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { LocalSeoType, SeoCountry, SeoOffer } from '../types/product/seo';
import { SeoStatus } from '../types/status';

export const localSeoMocks: LocalSeoType[] = [
{
accountId: 5424,
address: '2 rue Kellermann 59100 Roubaix',
country: SeoCountry.FR,
creationDate: '2025-08-25T13:17:39.620Z',
id: 0,
lastUpdate: '2025-08-25T13:17:39.620Z',
name: 'Mon entreprise de test',
offer: SeoOffer.NORMAL,
status: SeoStatus.CREATED,
taskId: 0,
},
];
32 changes: 32 additions & 0 deletions packages/manager/apps/web-hosting/src/data/api/local-seo.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { describe, expect, vi } from 'vitest';

import { hostingDeleteLocation, hostingLocalSeoLogin } from '@/data/api/local-seo';

vi.mock('@ovh-ux/manager-core-api', () => ({
v6: {
get: vi.fn().mockReturnValue({ data: {}, headers: { 'x-pagination-total': '1' } }),
post: vi.fn().mockResolvedValue({ data: {} }),
},
}));

describe('hostingLocalSeoLogin', () => {
it('should call v6.post with the correct URL', async () => {
const serviceName = 'srv-123';
const accountId = 'accountId-123';

await hostingLocalSeoLogin(serviceName, accountId);

expect(hostingLocalSeoLogin).toHaveBeenCalledWith(serviceName, accountId);
});
});

describe('hostingDeleteLocation', () => {
it('should call v6.post with the correct URL', async () => {
const serviceName = 'srv-123';
const locationId = 'locationId-123';

await hostingDeleteLocation(serviceName, locationId);

expect(hostingDeleteLocation).toHaveBeenCalledWith(serviceName, locationId);
});
});
33 changes: 33 additions & 0 deletions packages/manager/apps/web-hosting/src/data/api/local-seo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { v6 } from '@ovh-ux/manager-core-api';

import { LocalSeoAccount } from '../types/product/seo';

export const getHostingLocalSeoAccount = async (
serviceName: string,
id: string,
): Promise<LocalSeoAccount> => {
const { data } = await v6.get<LocalSeoAccount>(
`/hosting/web/${serviceName}/localSeo/account/${id}`,
);
return data;
};

export const hostingLocalSeoLogin = async (
serviceName: string,
accountId: string,
): Promise<string> => {
const { data } = await v6.post<string>(
`/hosting/web/${serviceName}/localSeo/account/${accountId}/login`,
);
return data;
};

export const hostingDeleteLocation = async (
serviceName: string,
locationId: string,
): Promise<string> => {
const { data } = await v6.post<string>(
`/hosting/web/${serviceName}/localSeo/location/${locationId}/terminate`,
);
return data;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import '@testing-library/jest-dom';
import { act, renderHook, waitFor } from '@testing-library/react';
import { beforeEach, describe, expect, vi } from 'vitest';

import { localSeoMocks } from '@/data/__mocks__';
import { hostingDeleteLocation, hostingLocalSeoLogin } from '@/data/api/local-seo';
import { wrapper } from '@/utils/test.provider';

import { useHostingDeleteLocation, useHostingLocalSeoLogin } from './useWebHostingLocalSeo';

vi.mock('@ovh-ux/manager-core-api', () => ({
v6: {
get: vi.fn().mockReturnValue({
data: localSeoMocks,
headers: { 'x-pagination-total': '1' },
}),
},
}));

const onSuccess = vi.fn();
const onError = vi.fn();

describe('useHostingLocalSeoLogin', () => {
beforeEach(() => {
vi.clearAllMocks();
});

it('local seo login for token', async () => {
const { result } = renderHook(() => useHostingLocalSeoLogin('serviceName'), {
wrapper,
});
act(() => result.current.mutate('accountId'));

await waitFor(() => {
expect(hostingLocalSeoLogin).toHaveBeenCalledWith('serviceName', 'accountId');
});
});
});

describe('useHostingDeleteLocation', () => {
beforeEach(() => {
vi.clearAllMocks();
});

it('local seo login for token', async () => {
const { result } = renderHook(
() => useHostingDeleteLocation('serviceName', onSuccess, onError),
{
wrapper,
},
);
act(() => result.current.mutate('locationId'));

await waitFor(() => {
expect(hostingDeleteLocation).toHaveBeenCalledWith('serviceName', 'locationId');
expect(onSuccess).toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useMutation, useQuery } from '@tanstack/react-query';

import { ApiError } from '@ovh-ux/manager-core-api';

import {
getHostingLocalSeoAccount,
hostingDeleteLocation,
hostingLocalSeoLogin,
} from '@/data/api/local-seo';

export const useGetHostingLocalSeoAccount = (serviceName: string, id: string) =>
useQuery({
queryKey: ['hosting', 'web', serviceName, 'localSeo', 'account', id],
queryFn: () => getHostingLocalSeoAccount(serviceName, id),
enabled: Boolean(id),
});

export const useHostingLocalSeoLogin = (serviceName: string) => {
const mutation = useMutation({
mutationFn: (accountId: string) => hostingLocalSeoLogin(serviceName, accountId),
});

return {
hostingLocalSeoLogin: mutation.mutateAsync,
...mutation,
};
};

export const useHostingDeleteLocation = (
serviceName: string,
onSuccess: () => void,
onError: (error: ApiError) => void,
) => {
const mutation = useMutation({
mutationFn: (locationId: string) => hostingDeleteLocation(serviceName, locationId),
onSuccess,
onError,
});

return {
hostingDeleteLocation: mutation.mutate,
...mutation,
};
};
31 changes: 31 additions & 0 deletions packages/manager/apps/web-hosting/src/data/types/product/seo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { SeoStatus } from '../status';

export enum SeoCountry {
FR = 'FR',
}

export enum SeoOffer {
NORMAL = 'normal',
}

export type LocalSeoType = {
accountId: number;
address: string;
country: SeoCountry;
creationDate: string;
id: number;
lastUpdate: string;
name: string;
offer: SeoOffer;
status: SeoStatus;
taskId: number;
};

export type LocalSeoAccount = {
creationDate: string;
email: string;
id: number;
lastUpdate: string;
status: SeoStatus;
taskId: number;
};
7 changes: 7 additions & 0 deletions packages/manager/apps/web-hosting/src/data/types/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ export enum GitStatus {
INITIALERROR = 'INITIAL_ERROR',
}

export enum SeoStatus {
CREATED = 'created',
CREATING = 'creating',
DELETING = 'deleting',
UPDATING = 'updating',
}

export enum TaskStatus {
ERROR = 'ERROR',
PENDING = 'PENDING',
Expand Down
Loading
Loading