- Contactos: nova página no backoffice (fitme3070_info) e 964 201 137 como telefone principal; o telefone secundário só aparece quando existe. - Equipa: título, aptidões/funções e formações; o cartão mostra foto, nome e título e abre um cartão horizontal de detalhe (hover no desktop, toque no telemóvel) sem mexer na grelha. - Mensalidades: cartões editáveis com um destaque, modal de inscrição que guarda o pedido (RGPD + estado + campos reservados para o CRM) e avisa o ginásio por e-mail; lista de pedidos com estados, notas e CSV. - Reviews Google via Places API (New), filtradas por classificação mínima e em cache configurável; página de configuração com pesquisa do Place ID. - Assets com ?v=<mtime>: site/assets é servido com cache imutável de 1 ano. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
3.3 KiB
SQL
61 lines
3.3 KiB
SQL
-- ─── Mensalidades + pedidos de inscrição ────────────────────────────────────
|
|
-- memberships: cartões de mensalidade editáveis no backoffice. Um só pode estar
|
|
-- em destaque (garantido na aplicação). is_addon = acresce à mensalidade base
|
|
-- (mostra "+X €").
|
|
-- membership_leads: pedidos do modal "Inscrever". Guarda o consentimento RGPD
|
|
-- (texto + IP + UA), o estado de acompanhamento e, reservado para a futura
|
|
-- integração com o CRM do ginásio, crm_ref / crm_synced_at.
|
|
-- Safe to re-run.
|
|
|
|
CREATE TABLE IF NOT EXISTS `memberships` (
|
|
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
|
`name` VARCHAR(100) NOT NULL,
|
|
`subtitle` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`price` DECIMAL(8,2) DEFAULT NULL,
|
|
`is_addon` TINYINT(1) NOT NULL DEFAULT 0,
|
|
`price_suffix` VARCHAR(60) NOT NULL DEFAULT '/mês',
|
|
`features` TEXT DEFAULT NULL,
|
|
`is_featured` TINYINT(1) NOT NULL DEFAULT 0,
|
|
`featured_label` VARCHAR(40) NOT NULL DEFAULT 'Mais popular',
|
|
`cta_label` VARCHAR(40) NOT NULL DEFAULT 'Inscrever',
|
|
`item_order` INT(11) NOT NULL DEFAULT 0,
|
|
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`deleted_at` DATETIME DEFAULT NULL,
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_memberships_list` (`deleted_at`, `is_active`, `item_order`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `membership_leads` (
|
|
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
|
`membership_id` INT(11) DEFAULT NULL,
|
|
`membership_name` VARCHAR(100) NOT NULL DEFAULT '',
|
|
`name` VARCHAR(150) NOT NULL,
|
|
`email` VARCHAR(190) NOT NULL DEFAULT '',
|
|
`phone` VARCHAR(40) NOT NULL DEFAULT '',
|
|
`message` VARCHAR(1000) NOT NULL DEFAULT '',
|
|
`status` ENUM('novo','contactado','inscrito','descartado') NOT NULL DEFAULT 'novo',
|
|
`admin_notes` TEXT DEFAULT NULL,
|
|
`consent` TINYINT(1) NOT NULL DEFAULT 0,
|
|
`consent_text` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`ip` VARCHAR(45) NOT NULL DEFAULT '',
|
|
`user_agent` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`crm_ref` VARCHAR(100) DEFAULT NULL,
|
|
`crm_synced_at` DATETIME DEFAULT NULL,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_membership_leads_status` (`status`, `created_at`),
|
|
KEY `idx_membership_leads_crm` (`crm_synced_at`),
|
|
CONSTRAINT `fk_membership_leads_membership`
|
|
FOREIGN KEY (`membership_id`) REFERENCES `memberships` (`id`) ON DELETE SET NULL
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- Cartão de exemplo (o preço fica por definir no backoffice).
|
|
INSERT INTO `memberships` (`name`, `subtitle`, `price`, `is_addon`, `price_suffix`, `features`, `item_order`)
|
|
SELECT 'Off-hours', 'Mensalidade para as horas baixas do ginásio.', NULL, 1, 'acresce à mensalidade',
|
|
'Acesso nas horas de menor afluência\nSala de musculação e cardio', 10
|
|
FROM DUAL
|
|
WHERE NOT EXISTS (SELECT 1 FROM `memberships`);
|