The Footer Service manages footer content including contact information, social media links, and branch locations.
Overview
This service provides methods to retrieve and update footer data, managing both general footer information and branch locations.
Dependencies
footerRepository - Database operations for footer data
Methods
Retrieves all footer data including general info and branches in parallel.
import { footerService } from '$lib/server/services/footer.service.js';
const footerData = await footerService.getFooterData();
Footer general information:
description: Company description
address: Main address
phone: Phone number
mobile: Mobile/WhatsApp number
email: Contact email
facebookUrl: Facebook page URL
instagramUrl: Instagram profile URL
tiktokUrl: TikTok profile URL
whatsappUrl: WhatsApp link URL
Array of branch objects:
id: Branch identifier
name: Branch name
address: Branch address
Example Response
{
info: {
description: 'Líder en distribución de materiales de construcción',
address: 'Av. Principal 123, Ciudad',
phone: '+1234567890',
mobile: '+1234567891',
email: 'contacto@provesa.com',
facebookUrl: 'https://facebook.com/provesa',
instagramUrl: 'https://instagram.com/provesa',
tiktokUrl: 'https://tiktok.com/@provesa',
whatsappUrl: 'https://wa.me/1234567891'
},
branches: [
{ id: 1, name: 'Sucursal Centro', address: 'Calle 1 #123' },
{ id: 2, name: 'Sucursal Norte', address: 'Av. Norte 456' }
]
}
Implementation Details
Source: src/lib/server/services/footer.service.js:5-11
The method uses Promise.all() for parallel data fetching:
const [info, branches] = await Promise.all([
footerRepository.getInfo(),
footerRepository.getBranches()
]);
Updates the general footer information.
import { footerService } from '$lib/server/services/footer.service.js';
await footerService.updateFooterInfo({
description: 'Nueva descripción de la empresa',
address: 'Nueva dirección principal',
phone: '+1234567890',
mobile: '+1234567891',
email: 'nuevo@provesa.com',
facebookUrl: 'https://facebook.com/provesa',
instagramUrl: 'https://instagram.com/provesa',
tiktokUrl: 'https://tiktok.com/@provesa',
whatsappUrl: 'https://wa.me/1234567891'
});
Full URL to Facebook page
Full URL to Instagram profile
Full URL to TikTok profile
WhatsApp link URL (format: https://wa.me/PHONE)
Implementation Details
Source: src/lib/server/services/footer.service.js:14-19
addBranch()
Adds a new branch location to the footer.
import { footerService } from '$lib/server/services/footer.service.js';
await footerService.addBranch({
name: 'Sucursal Sur',
address: 'Av. Sur 789, Zona Industrial'
});
Branch name or location identifier
Implementation Details
Source: src/lib/server/services/footer.service.js:22-24
deleteBranch()
Deletes a branch location by ID.
import { footerService } from '$lib/server/services/footer.service.js';
await footerService.deleteBranch(1);
Implementation Details
Source: src/lib/server/services/footer.service.js:27-29
Usage Examples
// src/routes/admin/footer/+page.server.js
import { footerService } from '$lib/server/services/footer.service.js';
import { fail } from '@sveltejs/kit';
export async function load() {
const footerData = await footerService.getFooterData();
return footerData;
}
export const actions = {
updateInfo: async ({ request }) => {
const formData = await request.formData();
try {
await footerService.updateFooterInfo({
description: formData.get('description'),
address: formData.get('address'),
phone: formData.get('phone'),
mobile: formData.get('mobile'),
email: formData.get('email'),
facebookUrl: formData.get('facebookUrl'),
instagramUrl: formData.get('instagramUrl'),
tiktokUrl: formData.get('tiktokUrl'),
whatsappUrl: formData.get('whatsappUrl')
});
return { success: true };
} catch (error) {
return fail(500, { error: error.message });
}
},
addBranch: async ({ request }) => {
const formData = await request.formData();
try {
await footerService.addBranch({
name: formData.get('name'),
address: formData.get('address')
});
return { success: true };
} catch (error) {
return fail(500, { error: error.message });
}
},
deleteBranch: async ({ request }) => {
const formData = await request.formData();
const id = parseInt(formData.get('id'));
try {
await footerService.deleteBranch(id);
return { success: true };
} catch (error) {
return fail(500, { error: error.message });
}
}
};
// src/routes/+layout.server.js
import { footerService } from '$lib/server/services/footer.service.js';
export async function load() {
const footerData = await footerService.getFooterData();
return { footerData };
}
<!-- src/lib/components/Footer.svelte -->
<script>
export let info;
export let branches;
</script>
<footer>
<div class="footer-info">
<p>{info.description}</p>
<p>{info.address}</p>
<p>Tel: {info.phone}</p>
<p>Móvil: {info.mobile}</p>
<p>Email: {info.email}</p>
<div class="social-links">
{#if info.facebookUrl}
<a href="{info.facebookUrl}" target="_blank">Facebook</a>
{/if}
{#if info.instagramUrl}
<a href="{info.instagramUrl}" target="_blank">Instagram</a>
{/if}
{#if info.tiktokUrl}
<a href="{info.tiktokUrl}" target="_blank">TikTok</a>
{/if}
{#if info.whatsappUrl}
<a href="{info.whatsappUrl}" target="_blank">WhatsApp</a>
{/if}
</div>
</div>
<div class="branches">
<h3>Nuestras Sucursales</h3>
{#each branches as branch (branch.id)}
<div class="branch">
<strong>{branch.name}</strong>
<p>{branch.address}</p>
</div>
{/each}
</div>
</footer>
Data Structure
interface FooterInfo {
description: string;
address: string;
phone: string;
mobile: string;
email: string;
facebookUrl: string;
instagramUrl: string;
tiktokUrl: string;
whatsappUrl: string;
}
Branch Object
interface Branch {
id: number;
name: string;
address: string;
}
WhatsApp Integration
Generating WhatsApp URLs
const phone = '1234567890'; // Without + or spaces
const message = encodeURIComponent('Hola, me gustaría obtener más información');
const whatsappUrl = `https://wa.me/${phone}?text=${message}`;
await footerService.updateFooterInfo({
// ... other fields
whatsappUrl
});
- Basic:
https://wa.me/1234567890
- With message:
https://wa.me/1234567890?text=Hello
Best Practices
Validate email addresses and phone numbers before saving.
Ensure social media URLs are complete and valid before updating.
Keep branch addresses concise but complete for better user experience.
Footer info is typically singleton data (one record). The repository handles upsert operations.
Validation Example
import { footerService } from '$lib/server/services/footer.service.js';
function validateEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
function validatePhone(phone) {
return /^\+?[0-9]{10,15}$/.test(phone);
}
function validateUrl(url) {
try {
new URL(url);
return true;
} catch {
return false;
}
}
async function updateFooterWithValidation(data) {
// Validate
if (data.email && !validateEmail(data.email)) {
throw new Error('Invalid email format');
}
if (data.phone && !validatePhone(data.phone)) {
throw new Error('Invalid phone format');
}
const urlFields = ['facebookUrl', 'instagramUrl', 'tiktokUrl', 'whatsappUrl'];
for (const field of urlFields) {
if (data[field] && !validateUrl(data[field])) {
throw new Error(`Invalid ${field}`);
}
}
// Update if valid
await footerService.updateFooterInfo(data);
}