Voos partilhados em Portugal | SkyFuns 
{$safeUser})"; } $sql .= " ORDER BY CASE WHEN f.date IS NULL OR f.date = '' THEN 1 ELSE 0 END, f.date ASC, f.time ASC LIMIT 8"; if ($result = $conn->query($sql)) { while ($row = $result->fetch_assoc()) { $title = trim((string)($row['title'] ?? '')); if ($title === '') { $title = 'SkyFuns flight'; } $departureRaw = trim((string)($row['departure'] ?? '')); $destinationRaw = trim((string)($row['destination'] ?? '')); $departureInfo = sf_lookup_airport($departureRaw); $destinationInfo = sf_lookup_airport($destinationRaw); $departureLabel = sf_format_airport_label($departureRaw); $destinationLabel = sf_format_airport_label($destinationRaw); $routeLabel = $departureLabel !== '' && $destinationLabel !== '' ? $departureLabel . ' to ' . $destinationLabel : ($departureLabel !== '' ? 'From ' . $departureLabel : ($destinationLabel !== '' ? 'To ' . $destinationLabel : 'Flexible route')); $dateLabel = ''; if (!empty($row['date'])) { $timestamp = strtotime($row['date']); if ($timestamp !== false) { $dateLabel = date('d M', $timestamp); } } $timeLabel = ''; if (!empty($row['time'])) { $timeLabel = substr($row['time'], 0, 5); } $scheduleLabel = trim( ($dateLabel !== '' ? $dateLabel : 'Flexible date') . ' | ' . ($timeLabel !== '' ? $timeLabel : 'Flexible time'), " |" ); $seatsValue = isset($row['seats']) ? (int)$row['seats'] : 0; $seatsLabel = $seatsValue > 0 ? ($seatsValue === 1 ? '1 seat available' : $seatsValue . ' seats available') : 'Seats on request'; $priceValue = isset($row['price']) ? (float)$row['price'] : null; $priceLabel = $priceValue !== null && $priceValue > 0 ? 'EUR ' . number_format($priceValue, 0) . ' per seat' : 'Price confirmed with pilot'; $description = trim((string)($row['description'] ?? '')); if ($description === '') { $description = 'Explore Portugal from the air with a verified SkyFuns pilot.'; } if (strlen($description) > 140) { $description = rtrim(substr($description, 0, 140)) . '...'; } $coverRaw = $row['cover'] ?? $row['cover_image'] ?? ''; $cover = sf_resolve_media_path($coverRaw, $defaultCover); // Pilot data $pilotName = trim((string)($row['pilot_name'] ?? 'SkyFuns pilot')); $pilotAvatar = '/Assets/Images/Icons/defaultPP.jpg'; if (!empty($row['pilot_avatar'])) { $rawAvatar = trim($row['pilot_avatar']); if (preg_match('#^https?://#i', $rawAvatar)) { $pilotAvatar = $rawAvatar; } else { $pilotAvatar = '/' . ltrim($rawAvatar, '/'); } } $pilotRating = isset($row['pilot_avg_rating']) ? (float)$row['pilot_avg_rating'] : null; $pilotReviewCount = isset($row['pilot_review_count']) ? (int)$row['pilot_review_count'] : 0; $tagLabel = 'Featured'; if (!empty($departureInfo['code'])) { $tagLabel = strtoupper((string)$departureInfo['code']); } elseif ($departureLabel !== '') { $tagLabel = strtoupper($departureLabel); } $ctaHref = 'index.php?page=book-flight&flight=' . (int)$row['id'] . '&lang=' . urlencode($langCode); $flightCards[] = [ 'id' => (int)$row['id'], 'cover' => $cover, 'tag' => $tagLabel, 'title' => $title, 'summary' => $description, 'pilot_name' => $pilotName, 'pilot_avatar' => $pilotAvatar, 'pilot_rating' => $pilotRating, 'pilot_review_count' => $pilotReviewCount, 'meta' => [ ['icon' => 'map', 'label' => $routeLabel], ['icon' => 'calendar', 'label' => $scheduleLabel], ['icon' => 'users', 'label' => $seatsLabel], ], 'price' => $priceLabel, 'cta_guest' => 'Reserve seats', 'cta_member' => $userRole === 'pilot' ? 'View flight' : 'Book this seat', 'cta_href' => $ctaHref, ]; } $result->close(); } } if (!$flightCards && $userRole !== 'pilot') { $fallbackHref = 'index.php?page=flights&lang=' . urlencode($langCode); $flightCards = [ [ 'id' => null, 'cover' => 'https://images.unsplash.com/photo-1500835556837-99ac94a94552?auto=format&fit=crop&w=900&q=80', 'tag' => 'Coastal', 'title' => 'Atlantic sunrise hop', 'summary' => 'Lift from Cascais at sunrise for shoreline views and a coffee stop in Faro.', 'meta' => [ ['icon' => 'map', 'label' => 'Cascais to Faro'], ['icon' => 'calendar', 'label' => '12 Oct | 07:10'], ['icon' => 'users', 'label' => '3 seats available'], ], 'price' => 'EUR 140 per seat', 'cta_guest' => 'Reserve seats', 'cta_member' => 'View flight', 'cta_href' => $fallbackHref, ], [ 'id' => null, 'cover' => 'https://images.unsplash.com/photo-1552432553-7ff5163c4862?auto=format&fit=crop&w=900&q=80', 'tag' => 'Adventure', 'title' => 'Azores crater tour', 'summary' => 'Circle volcanic lakes with a veteran pilot and touch down for a thermal soak.', 'meta' => [ ['icon' => 'map', 'label' => 'Ponta Delgada to Sete Cidades'], ['icon' => 'calendar', 'label' => '21 Oct | 09:30'], ['icon' => 'users', 'label' => '2 seats available'], ], 'price' => 'EUR 180 per seat', 'cta_guest' => 'Plan this flight', 'cta_member' => 'View flight', 'cta_href' => $fallbackHref, ], [ 'id' => null, 'cover' => 'https://images.unsplash.com/photo-1515879218367-8466d910aaa4?auto=format&fit=crop&w=900&q=80', 'tag' => 'Harvest', 'title' => 'Douro tasting fly-out', 'summary' => 'Depart Porto for vineyard landings, cellar tours, and sunset tasting notes.', 'meta' => [ ['icon' => 'map', 'label' => 'Porto to Douro Valley'], ['icon' => 'calendar', 'label' => '18 Oct | 10:00'], ['icon' => 'users', 'label' => '2 seats available'], ], 'price' => 'EUR 165 per seat', 'cta_guest' => 'Plan this flight', 'cta_member' => 'View flight', 'cta_href' => $fallbackHref, ], [ 'id' => null, 'cover' => 'https://images.unsplash.com/photo-1526401281623-359ef6425c6b?auto=format&fit=crop&w=900&q=80', 'tag' => 'City break', 'title' => 'Lisbon sunset skyline', 'summary' => 'Soar over the Tagus at golden hour with a slow loop around Lisbon\'s landmarks.', 'meta' => [ ['icon' => 'map', 'label' => 'Lisbon coastal loop'], ['icon' => 'calendar', 'label' => 'Flexible timing'], ['icon' => 'users', 'label' => '4 seats available'], ], 'price' => 'EUR 120 per seat', 'cta_guest' => 'Explore voos', 'cta_member' => 'View flight', 'cta_href' => $fallbackHref, ], ]; } $hasFlightCards = !empty($flightCards); $highlightFlights = $hasFlightCards ? array_slice($flightCards, 0, 3) : []; $recommendedFlights = $hasFlightCards ? array_slice($flightCards, 0, 3) : []; $guestQuickCards = [ [ 'icon' => 'luggage', 'title' => 'Passageiros', 'copy' => 'Meet your local pilot, receive seat alerts and share the passion of flying.', 'page' => 'register', 'label' => 'Become a Skyfuns Passenger', ], [ 'icon' => 'plane', 'title' => 'Pilotos', 'copy' => 'Publish seats, build hours, and recover cost share with ease.', 'page' => 'become-pilot', 'label' => 'Become a SkyFuns Pilot', ], [ 'icon' => 'sparkles', 'title' => 'Experiências', 'copy' => 'Discover Top rated tours and adventure routes curated by our pilots.', 'page' => 'flights', 'label' => 'Leve-me ao topo', ], ]; $memberQuickCards = []; if ($isAuthenticated) { if ($userRole === 'pilot') { $memberQuickCards = [ [ 'icon' => 'plane', 'title' => 'Publique um novo assento', 'copy' => 'Share a fresh route and review enquiries from your cockpit hub.', 'page' => 'pilot-add-flight', 'label' => 'Add flight', ], [ 'icon' => 'file-text', 'title' => 'Atualize documentos de piloto', 'copy' => 'Upload licences, insurance, and aircraft logs before they expire.', 'page' => 'pilot-documents', 'label' => 'Open documents centre', ], [ 'icon' => 'layout-dashboard', 'title' => 'Ver painel do piloto', 'copy' => 'Track approvals, bookings, and recent passenger feedback in one place.', 'page' => 'dashboard-pilot', 'label' => 'Go to dashboard', ], ]; } else { $memberQuickCards = [ [ 'icon' => 'search', 'title' => 'Encontre seu próximo assento', 'copy' => 'Filter live flights by departure, budget, duration, and available seats.', 'page' => 'flights', 'label' => 'Explore voos', ], [ 'icon' => 'bookmark', 'title' => 'Itinerários salvos', 'copy' => 'Review and compare seats you have bookmarked for upcoming getaways.', 'page' => 'dashboard-passenger', 'label' => 'View dashboard', ], [ 'icon' => 'message-square', 'title' => 'Pergunte à comunidade', 'copy' => 'Swap tips with local pilots and passengers inside the SkyFuns hub.', 'page' => 'community', 'label' => 'Visit community', ], ]; } } if ($userRole === 'admin' && $isAuthenticated) { $memberQuickCards[] = [ 'icon' => 'shield-check', 'title' => 'Console administrativo', 'copy' => 'Review verification requests, reports, and platform analytics.', 'page' => 'dashboard-admin', 'label' => 'Open admin view', ]; } $processConfig = [ 'eyebrow' => $isAuthenticated ? 'Getting more from SkyFuns' : 'Como funciona', 'title' => $isAuthenticated ? 'Make the most of your SkyFuns account' : 'Three steps to liftoff', 'steps' => $isAuthenticated ? [ ['title' => 'Planeie sua próxima rota', 'copy' => 'Use filtros de voo para alinhar partidas, experiências e assentos à sua rotina.'], ['title' => 'Mantenha seu hub atualizado', 'copy' => 'Gerencie assentos salvos, documentos e alertas para voar em pouco tempo.'], ['title' => 'Compartilhe a experiência', 'copy' => 'Deixe avaliações, compartilhe destaques e convide amigos para a próxima aventura.'], ] : [ ['title' => 'Encontre seu assento', 'copy' => 'Filtre o hub de voos por partida, experiência ou orçamento para achar a rota ideal.'], ['title' => 'Confirme seu assento ', 'copy' => 'Confirme expectativas, revise o itinerário e finalize sua reserva.'], ['title' => 'Pronto para partir', 'copy' => 'Converse com o piloto antes para alinhar o plano de voo e pedidos especiais.'], ], 'cta' => $isAuthenticated ? [ 'label' => $userRole === 'pilot' ? 'Open pilot dashboard' : 'Manage preferences', 'page' => $userRole === 'pilot' ? 'dashboard-pilot' : 'settings', ] : [ 'label' => 'See the full flow', 'page' => 'how-it-works', ], ]; ?> SkyFuns

Welcome back,

Jump into new seats, manage your hub, and keep every shared flight on track.

Descubra o mundo do alto

Viva a aventura com a SkyFuns – pilotos verificados, assentos reais e paisagens inesquecíveis.

Pronto para reservar?

Reserve seu próximo assento em minutos

Explore rotas ao redor do mundo, garanta seu assento e converse com o piloto com antecedência.

$step): ?>

Pague menos por experiências premium

Com a SkyFuns todos ganham: compartilhamento de custos para voar melhor pagando menos.

Segurança acima de tudo

Na SkyFuns, a segurança conduz cada voo. Revisamos perfis de pilotos e conferimos licenças e certificados para garantir que estejam válidos — incluindo datas de expiração.

Impulsionado pela comunidade

Conecte-se com milhares no nosso fórum. A SkyFuns nasceu de quem ama voar; pilotos e passageiros compartilham histórias, dicas e inspirações para aproveitar cada aventura.

Comunidade

Tópicos de planejamento

Ask for advice on weather windows, baggage plans, and passenger briefings.

Encontros

Link up with many aspiring pilots around the world and share common knowledge and experiences.

Histórias

Share highlights from recent flights and inspire the next seat share.

Alugue uma aeronave

Anuncie sua aeronave na SkyFuns

  • Proprietários publicam disponibilidade e recebem contatos diretos de pilotos.
  • Pilotos request slots with document checks already in place.
  • Veja insights de desempenho e apoie pilotos qualificados.

Compliance & prep

Esteja à frente de cada checklist

Conecte o hub de conformidade, cronograma e guias de aeródromos para voos compartilhados fluírem sem sobressaltos.

Cobertura regulatória

Envie apenas documentos legais, válidos e atualizados.

Linha do tempo de 24 horas

Tempo, combustível e briefings conectados para 24 horas até a decolagem.

Chamado final

Finalize verificações e garanta que tudo esteja pronto para decolar.