Към съдържанието

Changelog

Όλες οι ενημερώσεις και τα νέα features του ChalkidikiHub

v3.35.0

23 Μαΐου 2026

140 νέες παραλίες από OpenStreetMap με unique AI περιγραφές × 7 γλώσσες (980 νέες indexable σελίδες), public host pages για owners με ≥2 καταλύματα (νέο /host/[slug] route), νέα admin tools (hosts dashboard + mass-email segment), build perf fix για να μην ξαναχτυπήσουμε το 45-min Vercel ceiling

🏖️

140 νέες παραλίες από OSM Overpass με unique περιεχόμενο

Νέο pipeline σε 6 scripts (`scripts/import-beaches-osm.js` κλπ) που τραβάει όλες τις natural=beach POIs στη Χαλκιδική από OpenStreetMap (free, no key), κάνει dedupe με proximity + same-name (250m strict, 800m όταν όνομα ταιριάζει), αυτο-classify σε kassandra/sithonia/athos/mainland με γεωγραφικούς κανόνες lat/lng, και upsert στο Supabase. Φιλτράρει non-beach POIs (bar/restaurant/hotel/camping tags). Συνολικά 165 παραλίες στο DB από 25 πριν.

✍️

AI-generated unique περιγραφές 140 × 7 γλώσσες (980 sections)

Δύο OpenAI passes ανά παραλία: (1) gpt-4o-mini με per-beach style+tone seed από 8×3 = 24 παραλλαγές, hardcoded village proximity hints από lat/lng (~50 anchor villages), 80-120 word Ελληνικά κείμενο που αποφεύγει AI clichés ("κρυστάλλινα νερά", "παράδεισος") και ξεκινάει με μη-επαναλαμβανόμενες δομές. (2) Batch JSON translation σε 6 γλώσσες + per-locale meta_title (50-60 chars) + meta_description (140-155 chars). Συνολικό κόστος ~$0.80 για 140 παραλίες. Regex pass στο τέλος καθάρισε leftover coordinate strings που το AI έβαζε αυτούσιες (41 fixes).

🏷️

OSM tag enrichment για features + crowd estimator

Νέο scripts/enrich-beaches-osm-tags.js ξανατραβάει OSM beaches με πλήρη tags, ταιριάζει με τις DB rows με proximity (200m) και αντιστοιχίζει surface, sunbeds, naturism, wheelchair, lifeguard, access σε BeachFeature array. 81 παραλίες πήραν πραγματικά OSM features (sandy/pebble/nudist/free), 59 fallback "free". Όλες έχουν πλέον rating ≥ 3.5 ώστε ο crowd estimator (getPopularity στο crowd-estimation.ts) να βγάζει meaningful score αντί για 0.

🖼️

Per-area Unsplash images + ad-hoc per-beach upgrades

Δύο scripts: `assign-beach-images-by-area.js` τραβάει 1 Unsplash photo ανά region (Kassandra/Sithonia/Athos/Mainland), τα ανεβάζει σε Supabase Storage και τα assign-άρει σε όλες τις παραλίες της περιοχής. `assign-per-beach-unsplash.js` σταδιακά αναβαθμίζει σε per-beach photos όπου το Unsplash έχει σχετικό αποτέλεσμα — 38 παραλίες έχουν ήδη unique cover (rate-limited στο demo tier 50/hr, συνεχίζεται με scheduled task).

👤

Public host pages — /host/[slug] για owners με 2+ καταλύματα

Νέο SSR route που εμφανίζει την προσωπική σελίδα ενός ιδιοκτήτη με όλα του τα δημοσιευμένα καταλύματα σε grid, plus avatar/logo, 7-language bio, public contact (email/phone), social links (Facebook/Instagram/website), aggregate stats. Gating με ≥2 published listings + explicit toggle. Person JSON-LD schema + BreadcrumbList, canonical + 7 hreflang alternates, στο sitemap automatically. Migration 042 πρόσθεσε public_slug, public_page_enabled, bio_{el..sr}, social_*, public_{display_name,avatar,email,phone} στο profiles, με public-read RLS policy μόνο για enabled+slug rows.

⚙️

Host page editor στο /dashboard/profile

Το dashboard profile section επεκτάθηκε με sections για host-page management: enable toggle (disabled μέχρι ≥2 published listings), manual slug με live preview + sanitization, public display name, avatar URL, public email/phone, Facebook/Instagram/website inputs, και bio editor σε 7 γλώσσες με collapsible textareas. Αυτόματο revalidate trigger στο /api/revalidate?type=host μετά το Save ώστε το production cache να ενημερωθεί άμεσα.

🪧

Marketing banner στο /dashboard/listings για eligible owners

Νέο HostPagePromoBanner client component που εμφανίζεται σε owners με ≥2 published listings που δεν έχουν ακόμα ενεργοποιήσει host page. Gradient primary→indigo design με decorative blurs, 3 value props (one link / SEO+schema / AI discoverability), CTA σε /dashboard/profile. Όταν είναι enabled, αντικαθίσταται από compact "live" confirmation card με View page + Edit. Dismissable με sessionStorage persistence.

🔗

HostLinkBanner στο /listings/[slug] (cross-portfolio nav)

Server component που εμφανίζεται κάτω από κάθε listing detail page και προτείνει "Δες τα {N} άλλα καταλύματα του {host}" με link στο /host/[slug]. Φαίνεται μόνο όταν ο owner έχει public_page_enabled + ≥2 published + το current listing δεν είναι το μοναδικό άλλο. 7-locale copy.

📊

Νέο admin panel /admin/hosts — επισκόπηση όλων των hosts

Νέα σελίδα admin/hosts με 4 stat tiles (Enabled / Eligible-not-enabled για outreach / Total eligible / All owners) και sortable table που δείχνει για κάθε owner: avatar+name+email, slug+clickable production URL, listings count, bio fill status (✓/empty), status badge (Live/Eligible/—), και inline Enable/Disable button που κάνει αυτόματο revalidate. Filter chips (Enabled/Eligible/All) + search across name/email/slug.

✉️

Νέο mass-email segment "2+ καταλύματα χωρίς host page"

Στο /admin/email προστέθηκε νέα κατηγορία παραληπτών για στοχευμένη outreach προς owners που είναι eligible αλλά δεν έχουν ενεργοποιήσει τη σελίδα τους ακόμα. Bonus: το listingCount σε όλο το email panel μετράει πλέον μόνο published listings (πριν περιελάμβανε drafts/closed), ώστε οι αριθμοί να συμπίπτουν με αυτούς του /admin/hosts.

Build perf — on-demand detail rendering για high-cardinality routes

Μετά το 45-min Vercel build ceiling που χτύπησε με την εισαγωγή των +140 παραλιών (+980 SSG pages × 7 locales), το generateStaticParams για beaches/listings/restaurants/activities/blog άλλαξε σε `return []`. Pages renderάρονται στο first request και cache-άρονται για 1h μέσω του υπάρχοντος revalidate. Sitemap συνεχίζει να τις listάρει, οπότε το Google discovery δεν επηρεάζεται. Build time έπεσε από >45min σε ~3min.

🚑

Force-dynamic hotfix για Next.js 16 SSG-to-dynamic edge case

Μετά το perf change, το /listings/[slug] (και άλλα) βγάζανε 500 γιατί στο Next.js 16 + Turbopack το generateStaticParams() που επιστρέφει [] δεν κάνει αυτόματο fallback σε on-demand σωστά. Προστέθηκε `export const dynamic = "force-dynamic"` στις detail routes για να γίνει instant fix. Επόμενο cycle: investigation για proper ISR config χωρίς force-dynamic, μόλις ξεκαθαρίσει το Next 16 behavior.

🌍

Area mismatch fix για southern Sithonia (Σάρτη, Νέος Μαρμαράς)

Ο αρχικός import classifier marked beaches με lon ≥ 23.92 ως Athos, αλλά το νότιο άκρο της Σιθωνίας εκτείνεται μέχρι lon ~24.0 (Sykia, Kalamitsi area). Conservative reclassification fix στο `scripts/fix-beach-areas.js` διόρθωσε 2 ξεκάθαρα λάθη (Σάρτη + Νέος Μαρμαράς από athos σε sithonia), αφήνοντας borderline cases (Άγιος Γεώργιος Σιθωνίας @ 40.32) ως είχαν.

🔧

Storage relabel + image-optimizer rollback (egress savings)

Νέο /api/admin/storage-relabel endpoint που backfill-άρει long Cache-Control headers σε υπάρχοντα Supabase Storage uploads (πριν είχαν default 1h). Νέο storage-recompress για legacy oversized images. Vercel image optimizer απενεργοποιήθηκε προσωρινά για να ξεμπλοκάρει production downloads. Auto-blog cron μεταφέρθηκε σε weekly. PMS crons disabled (unused).

🛡️

SEO meta improvements + auto-noindex thin translations

Rich per-page meta descriptions αντί generic site-wide fallback (από v3.34 baseline). Duplicate "ChalkidikiHub | ChalkidikiHub" στους titles αφαιρέθηκε. Auto-noindex σε /guide και /places translations που έχουν source description < threshold — Google δεν τιμωρεί πλέον για thin foreign-language pages όταν δεν υπάρχει substantive content. AI auto-fill admin endpoint για bulk content generation σε αυτά τα slots.

📝

Email send history με recipient list στο admin/email

Το activity_logs τώρα αποθηκεύει την πλήρη λίστα emails που στάλθηκαν σε κάθε mass send. Νέο expandable panel στο send history δείχνει τη λίστα παραληπτών με Copy και "Επαναχρήση παραληπτών" buttons — άμεσο follow-up στους ίδιους χρήστες ως external recipients χωρίς να ξαναστήσεις το φίλτρο.

Pinned featured listings (Amira House στο top)

Νέο PINNED_LISTING_SLUG_PREFIXES array στο data.ts + pinFeaturedListings() helper που εξασφαλίζει συγκεκριμένα listings (αρχικά Amira House) εμφανίζονται πάντα πρώτα στο /listings index και στο homepage, ανεξάρτητα από τη χρονολογική σειρά δημιουργίας. Wire-up σε getListings().


v3.34.0

7 Μαΐου 2026

AdSense compliance overhaul, 532 νέες σελίδες με AI-generated owner stories (76 listings × 7 γλώσσες), 3 data-driven features (sea temperature, price benchmarks, driving distances), νέα /about, honest cookie consent + GDPR-clean privacy

🛡️

AdSense compliance — διορθώσεις απόρριψης "low-value content"

Συνολικό overhaul για το AdSense rejection. /book/[slug] "under construction" placeholders → 308 permanentRedirect στο /listings/[slug] (462 thin URLs εξαφανίστηκαν). AdSense adsbygoogle.js βγήκε από το interaction-gate και φορτώνει με afterInteractive ώστε ο reviewer crawler να το ανιχνεύει. /changelog noindex (internal/dev content). /in/[location]/[category] επιστρέφει 404 όταν τα results είναι 0, αντί για κενό template. /listings/[slug] auto-noindex όταν source description < 200 chars (νέο thinThreshold option στο getContentMeta).

🍪

Honest cookie consent + NPA gating για AdSense

CookieConsent ξαναγράφτηκε σε 7 γλώσσες με ειλικρινές copy (αναφέρει ρητά Google AdSense + Google Analytics + opt-in mechanism), granular επιλογή Accept all / Essential only, link σε privacy. DeferredScripts τώρα setάρει window.adsbygoogle.requestNonPersonalizedAds=1 πριν φορτώσει το script όταν consent είναι unknown ή rejected — non-personalized ads χωρίς consent. GA φορτώνει μόνο μετά από explicit accept (παραμένει gated σε interaction/idle για LCP/TBT).

📄

Νέα /about σελίδα σε 7 γλώσσες

Πλήρης About page (~430 λέξεις/locale) με sections "Mission / What you will find / How we are different / Get in touch", AboutPage JSON-LD με Organization mainEntity (founder, foundingDate, contact, areaServed, sameAs social), σωστά canonical + 7 hreflang alternates + x-default. Footer link στο "Legal" column με tNav("about"). Sitemap entry για /about × 7 locales. Trust signal που έλειπε για AdSense.

🌡️

Live sea temperature card στο /beaches/[slug]

Νέο /api/sea-temperature route που καλεί Open-Meteo Marine API (free, no key, edge-cached 1h). Νέο SeaTemperatureCard component εμφανίζει current temp + 7-day forecast + monthly historical heatmap (Aegean baseline) σε 60+ beach pages. Πραγματικά μοναδικά live data για κάθε παραλία.

💶

Price benchmark + Cuisine ratio στο /places/[slug]

Νέο place-stats.ts helper με 2 functions: getVillagePriceStats (avg/min/max με comparison vs Halkidiki overall, ≥3 listings required) και getVillageCuisineStats (Greek/traditional vs international ratio βασισμένο σε cuisine tags, area-fallback όταν <5 categorised). Δύο νέα cards στο VillagePage μετά το quick-stats grid, locale-aware copy σε 7 γλώσσες. Παράδειγμα Toroni: "€116/βραδιά, 14% πιο φθηνά από Χαλκιδική avg, δείγμα 6", "33% παραδοσιακά εστιατόρια / 67% διεθνή".

🚗

Driving distance table στο /from/[city]

Νέο driving-distances.ts: Haversine + 1.4× road factor + adaptive speed (55/70/85 km/h ανά trip length) χωρίς external routing API. Coordinates + localised names για όλες τις 8 origin cities. Νέο DistanceTable component εμφανίζει sortable table με 11 popular Halkidiki villages + km + drive time + links στο /places/[slug]. 7-locale copy + disclaimer.

🤖

AI-generated owner stories — 532 νέες σελίδες με unique content

Νέο /api/admin/generate-owner-stories endpoint που με 1 cURL γεμίζει το owner_story_<locale> field για όλα τα 76 published listings σε 7 γλώσσες. Δύο OpenAI calls per listing: gpt-4o-mini για 150-200 word Greek narrative grounded σε real facts (location, capacity, amenities), batch JSON translation σε en/de/bg/ru/ro/sr (sr σε Latin script). Bulk-run κάλυψε 100% των 76 listings (35 + 33 + 8 pre-existing) με 0 failures, ~$0.40 OpenAI cost. Total: 532 σελίδες με original AI-written content που δεν υπάρχει αλλού.

📋

Privacy Policy honest cookies section (6 locales)

Section 5 ξαναγράφτηκε σε el/en/de/bg/ru/ro με σαφή τρεις κατηγορίες cookies (essential / advertising-AdSense / analytics-GA) και reference στο cookie banner ως opt-in mechanism. Το προηγούμενο "no tracking cookies" copy ήταν σε αντίφαση με το νέο banner — αυτό από μόνο του θα μπορούσε να δικαιολογήσει AdSense rejection.

🐛

Build fix για /stay/[slug]/guide (production-only)

Δύο pre-existing bugs που εμφανίστηκαν μόνο σε next build (Turbopack dev mode τα έπιανε): import path του villages_body.json είχε 7 ../ levels (έβγαινε εκτός project root) → 6, και το cast listing as Record<string, string|null> χρειάστηκε intermediate as unknown γιατί το listing_images array δεν είναι compatible με string.


v3.33.0

21 Απριλίου 2026

Area guide σε όλα τα 66 καταλύματα × 7 γλώσσες (462 νέες indexable σελίδες), /book κλειδωμένο με contact-only, PMS kill-switch

🗺️

Οδηγός περιοχής σε ΟΛΑ τα καταλύματα (462 νέες σελίδες)

Το area guide που πριν δούλευε μόνο στο Thespis Villa 3 είναι τώρα live σε όλα τα 66 καταλύματα × 7 γλώσσες. Κάθε οδηγός έχει τις 6 κοντινότερες παραλίες, 8 εστιατόρια και 6 δραστηριότητες ταξινομημένα με Haversine distance, 3ήμερο προτεινόμενο itinerary, FAQ section με airport transfer info, και 4 internal links προς σχετικά καταλύματα (village-first, area-fallback). Κάθε guide: ~350KB HTML, ~10 JSON-LD schemas, πλήρως SSR, ISR revalidate 24h

🎯

Cross-area POI fallback — καμία σελίδα με thin content

Το πρώτο audit έδειξε 13 Kassandra listings με μόνο 3 εστιατόρια και 2 mainland listings με 2 παραλίες (λόγω sparse δεδομένων στις αντίστοιχες περιοχές). Αντί να περιοριστώ σε .eq("area", area), τώρα φέρνω POIs από όλη τη Χαλκιδική και ταξινομώ με πραγματική απόσταση. Η Χαλκιδική είναι αρκετά μικρή ώστε ένα beach 10χλμ μακριά να είναι πιο χρήσιμο από padding με 2-item section. Μετά το fix: όλα τα 66 guides έχουν 6 παραλίες + 8 εστιατόρια + 6 δραστηριότητες

📰

Article JSON-LD + OG tags στα guides

Κάθε area guide έχει τώρα Article schema με datePublished/dateModified, author (ChalkidikiHub), publisher με logo, εικόνα κάλυψη του καταλύματος. Open Graph image 1200×630 με alt text + Twitter summary_large_image card. Η Google τα πιάνει ως content articles αντί για product pages — unlocks "News & Discover" placement

🔗

1.848 νέα internal paths από related listings

Κάθε guide δείχνει 4 σχετικά καταλύματα: priority στο ίδιο χωριό (stronger topical signal), fallback σε ίδια περιοχή αν το χωριό έχει <4 listings. Εικόνα, τιμή, link — το καθένα τραβάει crawl equity στο source listing. 462 guides × 4 links = 1.848 νέα εσωτερικά paths, αυξάνει crawl depth + PageRank flow σε όλο το directory

🚧

/book/[slug] κλειδωμένο με contact-only σελίδα

Το online booking δεν είναι έτοιμο ακόμα. Αντί για half-baked form, η /book/[slug] σε 7 γλώσσες δείχνει "Online κρατήσεις υπό κατασκευή — επικοινωνήστε απευθείας με τον ιδιοκτήτη" με tel:/mailto:/wa.me/website buttons. robots: noindex, follow — δεν χάνουμε link equity, αλλά και δεν γεμίζουμε τη Google με thin "coming soon" pages. Link πίσω στο listing

🔒

PMS kill-switch — owner-level disable

Νέο pms_enabled flag στο pms_owner_settings (migration 039). Αν ένας owner έχει pms_enabled=false, όλα τα public API routes (/api/pms/public/{book,quote,checkout}) επιστρέφουν 503 pms_disabled. Admin dashboard τώρα έχει toggle για instant activation/deactivation χωρίς να πειράξουμε τα existing listings — χρήσιμο για phased rollout ή emergency stop

📍

Guide CTA στη StayPage

Το "Οδηγός περιοχής: {village}" CTA εμφανίζεται τώρα σε κάθε listing page (πριν εμφανιζόταν μόνο αν είχε lat/lon). BookOpen icon + area name, link σε /stay/{slug}/guide. 7-locale translations. Δίνει visibility στα νέα 462 guide URLs μέσα από τη φυσική user journey

🗂️

Sitemap — 462 νέα guide URLs

Το /sitemap.xml τώρα περιλαμβάνει uncontionally /stay/{slug}/guide για κάθε listing × 7 γλώσσες, priority 0.8, changefreq weekly, lastmod από updated_at. Η Google παίρνει ρητό signal ότι αυτές είναι canonical σελίδες που θέλουμε indexed


v3.32.0

21 Απριλίου 2026

SEO — SSR village pages, smart data-driven meta, FAQ schema: fix για 1.510 "Discovered, not indexed" URLs στο GSC

🚑

Fix 500 errors σε όλα τα /places/[slug] routes

Μετά το v3.31.0, η αλλαγή από dynamic="force-dynamic" σε revalidate=3600 έσπασε όλα τα village pages γιατί το generateStaticParams() επέστρεφε άδεια λίστα → Next.js προσπάθησε static render αλλά το setRequestLocale() καλεί headers() → "Page changed from static to dynamic at runtime" error. Hotfix επαναφέρει force-dynamic προσωρινά (eb9071e), permanent solution στο ίδιο version: το generateStaticParams τώρα κατεβάζει όλα τα village slugs από Supabase και τα pre-renderάρει

SSR village pages με pre-rendered slugs (~1.900 pages στο edge)

VillagePage + VillageContentPage μετατράπηκαν από Client Components με useEffect fetch σε Server Components με pre-fetched props. Η Google βλέπει πλήρες HTML χωρίς JS — ονόματα παραλιών, εστιατορίων, δραστηριοτήτων, FAQs, όλα στο initial response. generateStaticParams σε /places/[slug] + /beaches + /restaurants + /activities pre-renderάρει 67 χωριά × 7 γλώσσες × 4 σελίδες ≈ 1.876 static pages στο build time. Instant TTFB από Vercel edge cache αντί για Supabase query ανά crawl

🏗️

ISR revalidate=3600 σε όλες τις village routes

revalidate=3600 (1 ώρα) αντικαθιστά το force-dynamic hotfix. Κάθε village σελίδα ξανα-generάρεται μία φορά την ώρα στο background — ο crawler βλέπει cached HTML, οι real users βλέπουν fresh data. Η Supabase τώρα τρέχει ~67 queries/ώρα συνολικά αντί για ~67 queries ανά crawler visit. Crawl budget της Google δεν καίγεται σε slow dynamic responses

📚

FAQPage JSON-LD ανά χωριό (rich results target)

buildFaqs() helper στο /places/[slug]/page.tsx παράγει 2-4 questions ανά χωριό βασισμένες σε πραγματικά counts: "Πού βρίσκεται η {village};", "Υπάρχουν παραλίες κοντά;" (αν >0), "Πού να φάω;" (αν >0), "Τι να κάνω;" (αν >0). EL + EN variants — απαντήσεις template-ized με τα actual counts ώστε η Google να τα θεωρεί αξιόπιστα. BreadcrumbList + Place schema ήδη υπήρχαν, τώρα τρία schemas συν-εμφανίζονται στο head

🧠

Smart meta descriptions στις κεντρικές village pages

GSC audit έδειξε 66/67 villages με meta_description_el που ξεκινάει με "Ανακαλύψτε την X..." — near-duplicate template που η Google downrankάρει. Το generateMetadata στο /places/[slug]/page.tsx τώρα τρέχει 3 count-only queries (beaches/restaurants/activities για το area) παράλληλα με top 2 beach names, και χτίζει unique per-village meta: "Σάρτη (Σιθωνία, Χαλκιδική): 7 παραλίες (Κληματαριά, Καρύδι), 58 εστιατόρια και 8 δραστηριότητες. Οδηγός, κριτικές, χάρτες." Localized σε 7 γλώσσες με σωστά plurals + conjunctions (και/and/und/и/și/i)

🎯

Smart meta + H1 στις subpages (beaches/restaurants/activities)

Το meta-helper.ts τώρα φέρνει count + top 2 ranked items ανά (village, content type) και γράφει unique title + description + H1. Πριν: "Best beaches near Sarti, Χαλκιδική." Μετά: "7 παραλίες κοντά στο Σάρτη (Σιθωνία, Χαλκιδική) — Παραλία Κληματαριά, Καρύδι. Φωτογραφίες, χάρτες, κριτικές." Η ίδια λογική τρέχει και στο H1, οπότε και το heading της σελίδας είναι unique — όχι μόνο το head tag. Συνολικά ~1.407 νέα unique routes (67 × 7 × 3)

🇷🇸

Serbian (sr) σε όλα τα SEO helpers

Το sr locale έλειπε από τα LABELS του meta-helper.ts και από το metadata query στο /places/[slug]/page.tsx. Προστέθηκε στις 3 content-type maps (beaches/restaurants/activities), στα meta_title_sr + meta_description_sr columns του village query, και στο META_LABELS table για το smart description generator. Όλα τα 7 locales τώρα παράγουν properly localized output (Χαλκιδική/Halkidiki/Chalkidiki/Халкидики/...)

🌐

x-default hreflang σε κάθε village URL

Κάθε metadata.alternates.languages map τώρα περιλαμβάνει x-default που δείχνει στην Ελληνική έκδοση (default locale). Η Google / Bing ξέρουν ποια γλώσσα να σερβίρουν σε visitors εκτός των 7 υποστηριζόμενων locales αντί για guessing με Accept-Language header. Ενσωματωμένο σε /places/[slug] και στις 3 subpages


v3.31.0

20 Απριλίου 2026

5 νέοι travel guides + SEO comprehensive upgrade: CSP, hreflang x-default, Activity Schema.org, noindex hardening

🗺️

5 νέοι travel guides με πλήρες SEO

Νέα κείμενα στο /guide/first-time-halkidiki, /guide/kassandra-sithonia-athos, /guide/hiking-halkidiki, /guide/wine-tours-halkidiki, /guide/petralona-cave. Ελληνικό content ~2000 λέξεις ανά guide με τοπικά insider tips ώστε να μην φαίνεται AI-generated, + μεταφράσεις σε 6 γλώσσες (en/de/bg/ru/ro/sr). 96-139 internal links ανά guide με hub&spoke strategy προς /places/<village>, /best/<collection>, /beaches/feature/<feature>, /itinerary/<days>, /from/<city>, /mount-athos. Καθένας έχει Article JSON-LD, OG images, hreflang alternates σε 7 γλώσσες

🔒

Content-Security-Policy header στο next.config.ts

Προσθήκη CSP header σε όλες τις responses ως defense in depth vs XSS: default-src self, script-src self unsafe-inline unsafe-eval (για Next inline scripts), style-src self unsafe-inline (για Tailwind JIT), img-src self data: https:, font-src self data:, frame-src self https://js.stripe.com. Αν κάτι προσπαθήσει να κάνει inject remote script από unknown origin, ο browser το μπλοκάρει πριν εκτελεστεί

🧠

Activity JSON-LD με Schema.org subtypes

Το generateActivityLD() στο seo.ts μετατρέπει πλέον την κατηγορία (water-sports, spa, nightlife, religious, adventure) σε αντίστοιχο Schema.org subtype: SportsActivityLocation για water-sports/adventure, HealthAndBeautyBusiness για spa, NightClub για nightlife, PlaceOfWorship για religious. Προστέθηκαν επίσης πεδία touristType, image, priceRange, duration, geo.latitude/longitude και aggregateRating (conditional — μόνο αν υπάρχουν reviews). Google τώρα καταλαβαίνει τι είναι η κάθε δραστηριότητα αντί για γενικό TouristAttraction

🌐

hreflang x-default σε κάθε page & layout

Κάθε σελίδα (places, beaches, guides, activities, restaurants, blog, faq, itinerary, from, costs, ev-chargers, sales, stay, best, mount-athos και όλες οι υπόλοιπες) δηλώνει τώρα x-default alternate που δείχνει στην Ελληνική έκδοση του URL. Μαζί με τα 7 locale alternates, Google και Bing ξέρουν ποια γλώσσα να σερβίρουν σε επισκέπτες που δεν ταιριάζουν με κανένα από τα υποστηριζόμενα locales — αντί για guessing με βάση το Accept-Language header

🤖

robots.ts + X-Robots-Tag noindex layered defense

Το /robots.txt πλέον απαγορεύει ρητά τα paths /admin, /dashboard, /api, /auth, /owner, /_next για όλους τους crawlers. Επιπλέον, ο proxy.ts στέλνει X-Robots-Tag: noindex, nofollow header σε κάθε response από private routes — έτσι ακόμα κι αν κάποιος bot αγνοήσει το robots.txt (το οποίο είναι advisory, όχι enforcing), το header βλέπεται στο response πριν γίνει index. Defense in depth σε δύο επίπεδα

🧹

Consolidation src/lib/seo.ts — removal src/lib/json-ld.ts

Διαγραφή του legacy src/lib/json-ld.ts (51 lines που διπλάσιαζε helpers). Όλα τα JSON-LD builders πλέον ζουν σε ένα αρχείο: generateBreadcrumbLD, generateFAQLD, generateArticleLD, generateActivityLD, localeUrl, ogImageUrl, collectionMeta. +81 lines στο seo.ts για τα συνενωμένα helpers. Κάθε page/layout έχει ενημερωθεί ώστε να κάνει import από μόνο ένα place — μικρότερο bundle, λιγότερη duplication, ευκολότερη συντήρηση

🗺️

Sitemap x-default + OG cache + a11y + localized 404

Το /sitemap.xml τώρα περιλαμβάνει x-default alternate για κάθε URL alongside τα 7 locale alternates ώστε να είναι coherent με τα metadata alternates. /api/og route στέλνει Cache-Control: public, max-age=31536000, immutable — OG images cache-άρονται για 1 έτος από CDN + browsers χωρίς regeneration. ImageGallery thumbnail buttons έχουν aria-label για screen readers. Το not-found.tsx τώρα έχει localized metadata και translated strings και στις 7 γλώσσες αντί για hard-coded Ελληνικά


v3.30.0

19 Απριλίου 2026

PMS — Stripe Connect: OAuth onboarding + deposit auto-charge με 0% commission

💳

Stripe Connect OAuth onboarding

Νέο κουμπί "Connect with Stripe" στο /dashboard/pms/settings → Payments που κάνει redirect στο https://connect.stripe.com/oauth/authorize. Ο owner συνδέει τον Stripe λογαριασμό του (ή φτιάχνει καινούργιο με τα στοιχεία της επιχείρησης), και μετά το Stripe τον στέλνει πίσω στο /api/stripe/connect/callback όπου ανταλλάσσουμε το authorization code με stripe_user_id. Αποθηκεύεται σε pms_owner_settings.stripe_account_id + stripe_onboarded=true

🔐

Anti-CSRF με random state token

Πριν το redirect, το /api/stripe/connect/start γεννάει 64-char hex random state μέσω crypto.getRandomValues() και το αποθηκεύει στο pms_owner_settings.stripe_connect_state του owner. Το callback ψάχνει τον owner μέσω του state value — αν δεν ταιριάξει, επιστρέφει state_mismatch. Έτσι κανείς δεν μπορεί να προσαρτήσει Stripe account άλλου σε owner χωρίς να ξέρει το token. Καθαρίζεται μετά την επιτυχία ή αποτυχία

💰

0% commission με transfer_data.destination

Όταν guest κάνει direct booking σε owner με Stripe onboarded, το /api/pms/public/checkout δημιουργεί Stripe Checkout Session με payment_intent_data[transfer_data][destination]=<owner>.stripe_account_id και application_fee_amount=0. Αυτό σημαίνει ότι τα χρήματα πάνε κατευθείαν στον owner — η ChalkidikiHub δεν κρατάει τίποτα. Το 0% commission είναι η υπόσχεση της πλατφόρμας υλοποιημένη σε κώδικα

🎯

Deposit-only charge στο checkout

Το Checkout χρεώνει μόνο το deposit portion (total × deposit_percentage / 100) σε cents, όχι ολόκληρο το ποσό. Έτσι ο guest δεν επιβαρύνεται με 100% προκαταβολή και το balance (70-80% συνήθως) τακτοποιείται off-platform με bank transfer ή cash πριν το check-in, όπως προτιμάνε οι Έλληνες ιδιοκτήτες. Currency = listing currency (default EUR), product_data.name = "Villa + check_in → check_out"

🪝

Webhook /api/stripe/webhook με HMAC verification

Νέο endpoint που λαμβάνει checkout.session.completed event. Επαληθεύει το stripe-signature header με HMAC-SHA256 μέσω Web Crypto API (crypto.subtle.importKey + sign) και 5-min tolerance window ενάντια σε replay attacks. Βάζει το booking σε payment_status=deposit_paid + stripe_paid_amount (από amount_total/100) + stripe_payment_method + stripe_checkout_session_id. Unsigned ή malformed webhooks απορρίπτονται με 400

🪄

Αυτόματο redirect guest στο Stripe Checkout

Αν ο owner έχει Stripe onboarded, το book API επιστρέφει stripe_enabled=true στο response. Το /book/[slug] τότε αντί να πάει στο confirmed, καλεί /api/pms/public/checkout και redirectάρει στο session.url. Ο guest πληρώνει στο Stripe-hosted checkout page, επιστρέφει στο /success → /confirmed. Αν αποτύχει (cancel button), πάει στο /cancelled με "Try paying again" button που ξανακαλεί το ίδιο endpoint

🗄️

Migration 038_pms_stripe.sql

ALTER pms_owner_settings ADD stripe_connect_state TEXT (nullable, για OAuth flow). ALTER pms_bookings ADD stripe_checkout_session_id TEXT + stripe_paid_amount NUMERIC(10,2) + stripe_payment_method TEXT. Partial index idx_pms_bookings_stripe_session WHERE stripe_checkout_session_id IS NOT NULL για γρήγορο lookup από webhook. Καθαρά nullable ώστε να μην σπάει existing rows — όλοι οι owners ξεκινούν non-onboarded και το stripe flow είναι opt-in


v3.29.0

19 Απριλίου 2026

PMS — Public direct booking page: 0% commission, απευθείας με τον ιδιοκτήτη

🎯

Νέα public page /book/[slug]

Guest-facing booking form σε rose→pink→fuchsia gradient χωρίς login. Hero με cover image του καταλύματος + εκπτωτικό badge "0% OTA". Split layout: αριστερά τα fields (dates, guests counter με +/-, name, email, phone, country, notes), δεξιά sticky quote card με nightly average, νύχτες, σύνολο, applied rules, deposit amount, cancellation policy & instant-book/needs-approval chip

💰

Live pricing με pricing rules engine

Κάθε αλλαγή σε dates/listing καλεί /api/pms/public/quote που εφαρμόζει όλα τα active pms_pricing_rules του καταλύματος (seasonal, weekend, LOS, last-minute, custom) μέσω του υπάρχοντος computeQuote(). Εμφανίζει applied rules με signed delta (+ rose αν ακριβότερο, − emerald αν φθηνότερο). Υπολογισμός deposit με βάση το effective deposit_percentage από mergeSettings()

🛡️

Server-side availability checks

Το /api/pms/public/quote ελέγχει ταυτόχρονα: (1) listing_availability blocks στο range, (2) επικαλυπτόμενες pms_bookings εκτός cancelled, (3) min/max nights από effective settings, (4) advance_notice_hours vs τρέχουσα ώρα. Επιστρέφει availability.available + conflicts[] list ώστε το UI να δείξει τον λόγο (π.χ. "Minimum 3 nights") αντί για generic "unavailable"

📝

POST /api/pms/public/book

Δημιουργεί pms_bookings row με source=direct και status=confirmed αν instant_book ON, αλλιώς inquiry. Service client παρακάμπτει RLS για το insert. Server-side re-validation όλων των checks (dates, min/max nights, availability, guest limits, email format) — ο client δεν ελέγχεται. Επιστρέφει 409 αν οι ημερομηνίες κλείστηκαν εν τω μεταξύ από άλλον channel

Confirmation page /book/[slug]/confirmed

Redirect μετά το submit στο ?id=<booking-id>. Emerald-check icon αν confirmed, amber-clock αν inquiry. Δείχνει listing title, dates, guests, total σε fuchsia, booking ID σε mono. Contact tiles (phone/email) αν ο ιδιοκτήτης έχει ορίσει contact_phone/contact_email στο listing. "0% OTA" badge + link "Επιστροφή στο κατάλυμα"

🔗

"Book direct" CTA στο stay page

Νέο rose button στο sticky price bar (δίπλα στην τιμή/νύχτα) που δείχνει "Κλείσε απευθείας — 0% προμήθεια" σε 7 γλώσσες (el/en/de/bg/ru/ro/sr). Sparkles icon + shadow-rose-500/30 για visual pop. Click → /book/<slug>. Inline στο ίδιο header με την τιμή ώστε να φαίνεται αμέσως η εναλλακτική σε OTA

🔔

Αυτόματες ειδοποιήσεις owner (reuse)

Όταν δημιουργείται direct booking με status=inquiry ή confirmed, πέφτει στο ίδιο pms_bookings table που σκανάρει το /api/cron/pms-notifications (v3.28.0). Ο owner παίρνει email στο next :53 cron run χωρίς extra code — το source=direct filter δεν υπάρχει στον cron, οπότε καλύπτεται by default. Τοξεύεται επίσης στο ίδιο inbox/calendar όπου φαίνονται όλες οι κρατήσεις


v3.28.0

19 Απριλίου 2026

PMS — Email alerts στον owner: inquiry, booking, overdue, check-in/out

📧

Νέο hourly cron /api/cron/pms-notifications

Τρέχει στο :53 κάθε ώρας (ξεχωριστό window από dispatch :29 και auto-tasks :41 ώστε να μην συνωστίζονται τα sends). Σκανάρει 5 kinds: new inquiry (last 2h), new booking confirmed/pending (last 2h), overdue task (scheduled_at < now), check-in σήμερα, check-out σήμερα. Service client για cross-owner

🔔

5 toggles στο /dashboard/pms/settings

Νέο email-alerts block μέσα στο Notifications section με 5 Toggle switches: notify_new_inquiry (default ON), notify_new_booking (ON), notify_overdue_tasks (ON), notify_check_in_today (OFF), notify_check_out_today (OFF). Κάθε toggle έχει hint που εξηγεί πότε στέλνεται

🌍

Bilingual EL + EN σε ένα email

Όλα τα alerts γράφονται EL πάνω και EN από κάτω, χωρισμένα με horizontal divider ─────────────. Subject line: "Νέα κράτηση — Βίλα Καλλιθέα / New booking — Villa Kallithea". Έτσι δεν χρειάζεται να επιλέξεις locale — παίρνεις και τις δύο γλώσσες σε κάθε email

🛡️

Idempotency ανά kind + ref

Νέος πίνακας pms_notifications με UNIQUE (owner_id, kind, ref_id, COALESCE(ref_date, epoch)). Για new_inquiry/new_booking το ref_date είναι NULL (one-shot). Για overdue_task το ref_date=today ώστε να re-notifyεί μία φορά την ημέρα όσο το task παραμένει overdue. Για check_in/out_today ref_date είναι η ίδια η ημερομηνία. Cron safe σε re-runs

📬

Έξυπνο destination resolution

Email alerts πηγαίνουν στο reply_to_email του owner settings — αν κενό, fallback στο auth.users.email του account (μέσω service.auth.admin.getUserById). Έτσι δεν χρειάζεται εξτρά setup για να λειτουργήσει — δουλεύει out-of-the-box με τα stored credentials του account

🧠

Νέο lib/pms/notifications.ts

Export: sendOwnerAlert(supabase, {ownerId, kind, refId, refDate?, emailTo, subjectEl/En, bodyEl/En, creds?, footer?}) → "sent"|"skipped_duplicate"|"skipped_no_email"|"skipped_no_creds"|"failed". Reuses bodyToHtml + sendTemplateEmail + loadGmailCreds από dispatch.ts ώστε logic Gmail να είναι σε ένα μέρος. Records κάθε attempt (success or error) στο pms_notifications για audit

🗄️

Migration 037_pms_notifications.sql

ALTER pms_owner_settings ADD 5 BOOLEAN columns (notify_*) με sensible defaults. Νέος πίνακας pms_notifications: id, owner_id FK CASCADE, kind TEXT (CHECK 5 values), ref_id TEXT, ref_date DATE, email_to, subject, sent_at, error, created_at. UNIQUE index με COALESCE sentinel 1970-01-01. 2 regular indexes (owner, sent_at DESC). RLS owner reads own + admin reads all — inserts γίνονται μόνο από cron με service client


v3.27.0

20 Απριλίου 2026

PMS — Συνεργάτες (Vendors): λίστα επαφών για tasks

🧑‍🔧

Νέο module /dashboard/pms/vendors

Amber-orange-rose gradient hero, κάρτες ανά συνεργάτη με avatar icon ανά role (καθαριστής, συντήρηση, property manager, κλινοσκεπάσματα, κηπουρός, φωτογράφος, άλλο). Filter bar: search (όνομα/email/τηλ), role dropdown, toggle "show inactive". Activate/deactivate με ένα click — inactive απορρίπτονται από το task picker αλλά δεν χάνονται

Add/Edit modal με role picker

Modal form με 7 role icons σε grid (tapping χρωματίζει με το chipCls του role), name, phone, email, default hourly rate, default flat rate, notes. Autofocus στο name field. Live validation — save disabled αν δεν υπάρχει όνομα. Inline error από Supabase με mono font bubble

🔗

Νέο FK vendor_id στο pms_tasks

Optional reference με ON DELETE SET NULL ώστε αν διαγραφεί ο συνεργάτης, τα ιστορικά tasks παραμένουν (με το snapshot assignee_name/phone/email που είχαν τη στιγμή της ανάθεσης). Έτσι τα reports παραμένουν accurate χωρίς dangling refs ή auto-cascade

🎯

Vendor picker στο TaskForm

Νέο violet section "Πιάσε από συνεργάτες" πάνω από τα assignee fields: dropdown φορτωμένο με όλους τους active vendors. Όταν επιλέξεις συνεργάτη, γεμίζουν αυτόματα το name/phone/email/cost (default_flat_rate). Μπορείς πάντα να overrideάρεις χειροκίνητα — δεν "κολλάνε" τα πεδία

📊

Task count badge ανά vendor

Κάθε κάρτα δείχνει αριθμό tasks που έχουν ανατεθεί σε αυτόν τον συνεργάτη (όλων των εποχών). Quick way να δεις ποιον χρησιμοποιείς πιο συχνά και ποιον ίσως αρχίζει να ξεχνάς. Ο αριθμός ενημερώνεται live κάθε φορά που φορτώνει η σελίδα

💶

Default rates (hourly + flat)

Κάθε vendor έχει προαιρετικά default_hourly_rate και default_flat_rate. Εμφανίζονται στην κάρτα με €amount/h και €flat font-mono. Όταν επιλεγεί στο task form, γεμίζει το flat rate αυτόματα στο cost field (αν δεν υπάρχει ήδη value). Hourly μένει για manual entry (e.g. αν η εργασία διήρκησε 2h)

🗄️

Migration 036_pms_vendors.sql

Νέος πίνακας pms_vendors: id, owner_id FK, name, role (CHECK σε 7 values), phone, email, default_hourly_rate, default_flat_rate, notes, active, timestamps. 2 indexes (owner, active). RLS owner manages own + admin reads all. ALTER TABLE pms_tasks ADD vendor_id UUID REFERENCES pms_vendors ON DELETE SET NULL + index pms_tasks_vendor_idx


v3.26.0

20 Απριλίου 2026

PMS — Per-listing overrides: κάθε κατάλυμα έχει τις δικές του πολιτικές

🏠

Νέα /dashboard/pms/settings/listings/[id]

Dedicated page ανά κατάλυμα όπου ορίζεις overrides για instant_book, min/max nights, advance notice, preparation days, check-in/out times, cancellation policy, deposit %, balance days, κόστος καθάρισμα και lead days. Indigo-violet hero με το slug + live link, 4 sections χρωματιστά όπως τα global settings

🔗

Κληρονομικότητα με "Inherit" toggle

Κάθε πεδίο έχει badge πάνω δεξιά: OVERRIDE (indigo, active) ή INHERIT (slate, πατώντας το επαναφέρει σε null). Όταν inherit, το input μετατρέπεται σε read-only box που δείχνει την effective τιμή από τα global defaults. Έτσι βλέπεις με μια ματιά ποια πεδία έχεις αλλάξει και ποια κληρονομεί

📋

Index section στο main settings

Νέα indigo section "Overrides ανά κατάλυμα" στο τέλος του /dashboard/pms/settings με λίστα όλων των καταλυμάτων. Κάθε row δείχνει title + slug + pinned badge με τον αριθμό των active overrides (π.χ. "3 overrides") ή "inherits defaults". Click → page του override

🧠

Νέο lib/pms/settings.ts

Exports mergeSettings(owner, listing) και resolveListingSettings(supabase, listingId, ownerId) που κάνουν tri-state resolution: listing override (αν not null) → owner default (αν not null) → hard default. Consumable από any route handler ή cron. Pure TS, καθαρά interfaces

🔁

Auto-cleaning cron σέβεται overrides

Το /api/cron/pms-auto-tasks τώρα φορτώνει pms_listing_settings ανά owner και merge-άρει checkout_time + cleaning_lead_days + cleaning_default_cost ανά listing πριν δημιουργήσει το task. Έτσι αν ένα ακίνητο έχει 10:00 check-out και άλλο 13:00, τα tasks προγραμματίζονται σωστά

🗑️

Reset to defaults

Κουμπί "Reset σε defaults" στο save bar που διαγράφει την entire row από pms_listing_settings (μέσω DELETE WHERE listing_id=...). Το κατάλυμα επιστρέφει σε full inheritance από owner settings σε όλα τα πεδία ταυτόχρονα — χωρίς να χρειάζεται να toggle-άρεις ένα-ένα

🗄️

Migration 035_pms_listing_settings.sql

Νέος πίνακας pms_listing_settings με PK listing_id, όλα τα override columns NULLABLE (NULL = inherit). CHECK constraint για cancellation_policy μόνο όταν not null. RLS: owner manages own (auth.uid()=owner_id) + admin reads all. Updated-at trigger reused από pms_touch_updated_at()


v3.25.0

20 Απριλίου 2026

PMS — Pricing Rules Engine: αυτόματο quote στο booking form

💶

Νέο lib computeQuote()

Pure TS function στο src/lib/pms/pricing.ts που παίρνει base_rate + dates + rules και υπολογίζει nightly breakdown. Per-night rules (seasonal/weekend/custom) εφαρμόζονται ανά ημέρα σε priority order, booking-scope rules (LOS/last-minute) μετά στο σύνολο. Σεβαστά operations: override/add/subtract/multiply, percentage ή absolute amount

🤖

/api/pms/pricing/quote

POST {listing_id, check_in, check_out, booking_date?} → {base_rate, subtotal_*, nightly_average, applied[]}. RLS-scoped: verifyει ότι το listing ανήκει στον caller. Επιστρέφει array εφαρμοσμένων κανόνων με name, operation, scope (night/booking), nights_affected και signed delta σε €

Auto-quote στο BookingForm

Gradient fuchsia→pink box μέσα στο Money section που εμφανίζεται όταν listing + dates είναι set. Auto-fetch κάθε φορά που αλλάζει listing_id/check_in/check_out/status. Δείχνει 4 KPIs (Base/night, Avg/night, Nights, Subtotal) + λίστα εφαρμοσμένων κανόνων με icon (↑ rose αν ακριβότερο, ↓ emerald αν φθηνότερο, % για booking-scope)

🖱️

"Εφαρμογή στα πεδία" button

Κουμπί μέσα στο quote box που γεμίζει nightly_rate (avg) + total_amount (subtotal + cleaning + taxes). Έτσι βλέπεις πρώτα την τιμή, μετά επιλέγεις αν θα την κρατήσεις ή θα κάνεις manual override (το pricing rules engine προτείνει, δεν επιβάλλει)

🎯

Αυτόματο skip σε blocks/inquiries

Όταν το booking είναι status=blocked ή source=blocked το quote widget αποκρύπτεται (δεν έχει νόημα τιμολόγηση σε owner block). Το ίδιο ισχύει όταν απουσιάζουν dates ή check_in >= check_out. Error messages εμφανίζονται inline χωρίς να χαλάει η ροή του form

📊

Tally ανά κανόνα

Αν ο ίδιος κανόνας (π.χ. "Σαββατοκύριακα +20%") εφαρμοστεί σε 3 νύχτες, εμφανίζεται μια φορά με sum των deltas + "3 νύχτες" χαρακτηρισμός. Για LOS/last-minute εμφανίζεται "σε όλο το σύνολο". Tα % operations δεν compound — βασίζονται στο base_rate (per night) ή στο subtotal (per booking)

🧮

Math σεβαστά με edge cases

Math.max(0) clamp για να μην βγει αρνητική τιμή από aggressive subtract, days_until_checkin για last_minute rules υπολογίζεται σε ολόκληρες ημέρες UTC, weekdays array 0=Sun..6=Sat όπως Postgres. Seasonal ranges είναι inclusive [start_date, end_date]


v3.24.0

20 Απριλίου 2026

PMS — Auto-προγραμματισμός καθαρισμού όταν έρχεται check-out

Auto-cleaning task ανά booking

Νέο hourly cron (/api/cron/pms-auto-tasks) που σκανάρει κρατήσεις με check-out τις επόμενες 14 ημέρες και δημιουργεί pending task καθαρισμού με τίτλο "Cleaning — <guest> checkout". Idempotency: δεν διπλοδημιουργεί αν υπάρχει ήδη task τύπου cleaning για το ίδιο booking

Lead-days & checkout_time

Scheduled_at = check_out date στην ώρα checkout_time του owner. Αν ο owner θέλει ο καθαριστής να έρχεται πιο νωρίς, ορίζει cleaning_lead_days=1 και το task προγραμματίζεται την προηγούμενη. Default: 0 (ίδια μέρα, ίδια ώρα με check-out)

👤

Default assignee & cost

Νέα πεδία στο pms_owner_settings: cleaning_default_assignee_name/phone/email + cleaning_default_cost. Κάθε auto task έρχεται προ-συμπληρωμένο. Αλλαγές γίνονται πάντα χειροκίνητα στο detail page του task (π.χ. override για συγκεκριμένη κράτηση)

🔘

Toggle "Αυτόματος καθαρισμός"

Νέα ενότητα στο /dashboard/pms/settings με toggle auto_cleaning_enabled. Όταν OFF, ο cron παραλείπει τον owner. Όταν ON, εμφανίζονται και τα assignee/cost/lead-days fields για customization. Opt-in by default (μην σπάσουμε υπάρχουσες workflows)

🛡️

Respect status filter

Κρατήσεις με status=cancelled ή blocked δεν λαμβάνουν auto-task. Έτσι ακυρώσεις τελευταίας στιγμής δεν αφήνουν task να εμφανιστεί στα Pending. Όταν μια κράτηση μετακινηθεί σε νέα ημερομηνία, επόμενος cron run δημιουργεί νέο task (αν δεν υπάρχει ήδη)

🔁

Cron schedule

Τρέχει στο :41 κάθε ώρας (vercel.json). Ξεχωριστό από το pms-dispatch (:29) ώστε spikes να μην επηρεάζουν email sends. Service client για να δουλεύει cross-owner χωρίς auth context

🗄️

Migration 034_pms_auto_tasks.sql

Προσθέτει 6 στήλες στο pms_owner_settings: auto_cleaning_enabled, cleaning_default_assignee_name/phone/email, cleaning_default_cost (NUMERIC), cleaning_lead_days (INT 0-7). RLS μένει το υπάρχον "owner manages own settings" — δεν χρειάζεται νέο policy


v3.23.0

20 Απριλίου 2026

PMS — Template Dispatch Engine: αυτόματα emails με triggers & {{variables}}

📨

Αυτόματη Αποστολή στο Σωστό Trigger

Νέο hourly cron (/api/cron/pms-dispatch) σκανάρει όλα τα active non-manual templates και στέλνει email όπου ταιριάζει booking: on_inquiry/on_book/on_cancel (με βάση status), 3/1 days before check-in, on_checkin, on_checkout, 7 days after. Καλείται από Vercel Cron στο λεπτό :29 κάθε ώρας

🧠

{{variables}} Substitution με Locale Fallback

Κάθε template γίνεται render με guest_name, listing_name, check_in, check_out, nights, total, owner_name, owner_phone, owner_email. Η γλώσσα επιλέγεται από guest_country (GR/CY→el, DE/AT/CH→de, FR/BE/LU→fr, IT→it, ES/MX/AR→es, αλλιώς en), με fallback EN → EL → οποιοδήποτε locale έχει content

🔁

Idempotency ανά (template, booking)

Το dispatch engine ελέγχει αν υπάρχει ήδη message με ίδιο template_id + booking_id και skipάρει. Έτσι cron runs κάθε ώρα χωρίς κίνδυνο διπλού email. Force re-send επιτρέπεται με flag για edge cases (manual override)

✉️

Gmail via Nodemailer

Χρησιμοποιεί το ίδιο Gmail account με το password-reset flow (site_settings.gmail_address + gmail_app_password). Reply-to γεμίζει από pms_owner_settings.reply_to_email ή owner email, ώστε απαντήσεις guest να φτάνουν στον owner όχι στο system inbox

🖱️

<TemplatePicker/> στο Thread View

Νέα section στο /dashboard/pms/messages/[id] όταν το thread έχει booking: λίστα όλων των templates που ταιριάζουν στο listing, preview subject+body με συμπληρωμένες variables, Send button ανά template. Έλεγχος γλώσσας, inline override (UI-only preview), "Εστάλη" badge + Re-send option

🛡️

Owner-scoped API /api/pms/messages/send-template

Endpoint για manual send από UI. Verifyει RLS-scoped ότι template + booking ανήκουν στον caller, φορτώνει listing + owner profile, και delegates στο shared dispatchTemplateToBooking lib. Service client μόνο για site_settings read + cross-policy pms_messages insert

📝

Outbound Log στο Inbox

Κάθε template send γράφεται σαν κανονικό outbound message στο pms_messages (channel=email, is_automated=true, template_id FK). Βλέπεις στο thread view τα auto emails με "Auto" badge δίπλα στο channel pill, ώστε να ξέρεις ακριβώς τι ειπώθηκε και πότε


v3.22.0

19 Απριλίου 2026

PMS Finance — Revenue, ADR & Occupancy Dashboard

📈

Dashboard /dashboard/pms/finance

Year + listing filter → 4 KPI cards: Έσοδα (year-over-year delta σε % πάνω στην κάρτα), ADR (Average Daily Rate, €/νύχτα), Occupancy (πληρότητα %), Νύχτες booked (+ σύνολο κρατήσεων). Όλα υπολογίζονται από τα pms_bookings εξαιρώντας ακυρωμένα & blocked dates

📊

Monthly Revenue Bar Chart

12 μήνες σε horizontal bars με gradient emerald→teal, scaled στο max μήνα, με τιμή αριστερά και €amount δεξιά σε tabular-nums. Fast visual για το peak/off-season σου. Προσοχή: αν μια κράτηση πατά δύο μήνες, το nightly amount σπάει ανά ημέρα στον σωστό μήνα (όχι όλο στον checkout month)

🏠

Per-Listing Breakdown

Κατάλογος καταλυμάτων sorted by revenue desc, κάθε κάρτα: revenue € + bar (% του totalYear) + κρατήσεις + νύχτες + ADR. Βλέπεις ποιο κατάλυμα είναι star performer και ποιο underperforms — χωρίς να κοιτάς spreadsheets

📡

Per-Channel Breakdown

Ανά source (Direct, Airbnb, Booking.com, VRBO, Manual, Other) με χρωματιστό pill + revenue + bar + % του συνολικού έτους. Βλέπεις άμεσα πόσο OTA commission αποφεύγεις μέσω direct — key motivator για marketing investment

⚠️

Unpaid Alert Card

Όταν υπάρχουν bookings με payment_status ≠ fully_paid (και όχι refunded/cancelled), εμφανίζεται amber alert με το σύνολο που οφείλεται. Quick reminder να βγάζεις invoices ή να χάκες reminders

🧮

Smart Calculations

Nightly equivalent = total_amount / booking_nights αν υπάρχει total, αλλιώς nightly_rate. Clip στα όρια του έτους για μετακινήσεις Δεκ→Ιαν. Occupancy = nights / (days_up_to_today × listings_count) × 100 — δεν τιμωρείται για μελλοντικές ημέρες που δεν έχει φτάσει ακόμη η χρονιά

🟢

YoY Revenue Delta

Κάτω από το revenue KPI εμφανίζεται +15.2% vs πέρυσι (emerald) ή -8% (rose) όταν υπάρχει πέρυσι data στο ίδιο scope (listing filter + calendar year). Είναι το νούμερο που ρωτάς πρώτο στα end-of-year reviews


v3.21.0

19 Απριλίου 2026

PMS Automations — Message Templates σε 6 Γλώσσες με Triggers

🤖

Λίστα /dashboard/pms/automations

Όλα τα templates σε κάρτες με trigger icon + name + trigger pill + Active/Paused badge + body preview 120 χαρακτήρες + locale codes (EL · EN · DE…) + scope (Όλα τα καταλύματα ή N specific). Paused templates εμφανίζονται σε opacity 75% για να διακρίνονται

9 Triggers

Manual (on-demand insertion σε thread), On inquiry (πρώτο guest message), On booking (confirmation), 3 days before / 1 day before (prep reminders), On check-in (welcome), On check-out (thank-you), 7 days after (review request), On cancel. Radio cards με icon + one-line περιγραφή

🌍

6 Locales σε Tabs

EL 🇬🇷 · EN 🇬🇧 · DE 🇩🇪 · FR 🇫🇷 · IT 🇮🇹 · ES 🇪🇸 — κάθε locale tab δείχνει αν έχει content με πράσινο check. Subject + body per locale, αποθηκεύονται σε JSONB columns (subject_locales, body_locales) ώστε να στέλνεται το σωστό στη γλώσσα του guest χωρίς κόπο

📌

Variables με Click-to-Copy

{{guest_name}}, {{listing_name}}, {{check_in}}, {{check_out}}, {{nights}}, {{total}}, {{owner_name}}, {{owner_phone}} — tap σε variable chip για αυτόματη αντιγραφή στο clipboard. Θα γίνεται substitution την ώρα της αποστολής (render step δεν υλοποιημένο ακόμη)

🎯

Scope: Όλα ή Specific Listings

Toggle buttons "Όλα τα καταλύματα" vs "Επιλεγμένα" — αν specific, checkboxes για κάθε κατάλυμα του owner. Αποθηκεύεται ως UUID[] (null = όλα, array = specific). Για απλά portfolios το "όλα" είναι one-click setup

🔘

Active Toggle + 3 Stats

Templates (σύνολο), Ενεργά, Γλώσσες (μοναδικές locales με content). Pause toggle για εποχική παύση (π.χ. winter rates) χωρίς διαγραφή. Filter bar: trigger dropdown + status (All/Active/Paused) + live search σε name + όλα τα locale bodies

🧩

Shared <TemplateForm/>

4 sections: Basics (name + active), Trigger (9 radio cards), Content (6 locale tabs + subject + body + variables), Scope (all vs specific + checkboxes). Create/edit share the same form, delete with confirm στο edit page


v3.20.0

19 Απριλίου 2026

PMS Messages — Ενοποιημένο Inbox με Threads ανά Κράτηση

📥

Inbox /dashboard/pms/messages

Όλα τα μηνύματα ομαδοποιούνται σε threads — ένα ανά κράτηση, ή ανά guest_email όταν δεν υπάρχει κράτηση. Κάθε thread κάρτα: avatar με αρχικό γράμματος guest, όνομα + channel pill + "Auto" badge για templates + unread counter, subject, body preview 140 char, listing name + message count, relative timestamp (τώρα/5λ πριν/3ώ πριν/18 Απρ)

📊

3 Stat Cards

Threads (ομαδοποιημένες συνομιλίες), Αδιάβαστα (inbound χωρίς read_at), Σύνολο μηνυμάτων (όλα τα records)

🎨

6 Channels με Color Pills

Direct (slate), Email (sky), WhatsApp (emerald), Airbnb (rose), Booking.com (indigo), System (violet) — βοηθάει να εντοπίζεις με μια ματιά από πού ήρθε το μήνυμα. Φιλτράρισμα ανά channel + listing + live search σε guest/subject/body

💬

Thread View /dashboard/pms/messages/[id]

Chat-style bubbles — εξερχόμενα δεξιά (violet), εισερχόμενα αριστερά (slate), system messages γκρι italic. Auto mark-as-read όταν ανοίγεις το thread. Guest panel στην κορυφή με name/email + link στην κράτηση, threaded συνομιλία σε χρονολογική σειρά, inline reply composer από κάτω

✍️

Composer — Inbound ή Outbound Logging

Toggle μεταξύ "Προς guest (εξερχόμενο)" και "Από guest (εισερχόμενο)" — ώστε να μπορείς να καταχωρήσεις ΚΑΙ μηνύματα που έλαβες εξωτερικά (π.χ. από προσωπικό email) στο ίδιο thread. Channel dropdown, optional subject, multi-line body. Auto sets read_at για inbound entries ώστε να μη φαίνονται unread

Νέο Thread /dashboard/pms/messages/new

Διάλεξε listing (required) + optionally κράτηση → αν επιλέξεις booking, το guest name/email γεμίζουν αυτόματα. Support για standalone threads (inquiry που δεν έγινε booking) ή booking-tied threads. Prefill via ?listing_id=&booking_id= για δημιουργία από άλλες σελίδες

🧩

Shared <MessageComposer/>

Ένα component για reply (compact mode) και για new thread (full mode με subject). Reusable για μελλοντικά integrations — όταν συνδεθούν email/WhatsApp/Airbnb parsers, μόνο η μετά-αποστολή logic θα αλλάξει. Διαγραφή thread συνολικά από το [id] page


v3.19.0

19 Απριλίου 2026

PMS Tasks — Καθαρισμοί, Συντήρηση & Ανάθεση σε Συνεργάτες

🧹

Λίστα Εργασιών /dashboard/pms/tasks

Όλες οι εργασίες σε κάρτες με date block (μήνας + ημέρα + ώρα), type pill (Καθαρισμός/Συντήρηση/Επιθεώρηση/Κλινοσκεπάσματα/Υποδοχή/Αναχώρηση/Custom), status pill (Εκκρεμεί/Σε εξέλιξη/Ολοκληρωμένη/Ακυρώθηκε/Παραλείφθηκε), overdue badge όταν pending + περασμένη ώρα, assignee name & κόστος στα δεξιά

📊

4 Stat Cards στο Top

Σήμερα (εργασίες προγραμματισμένες για σήμερα), Εκκρεμούν (status=pending), Καθυστερημένες (pending + passed scheduled_at — κόκκινο warning), Κόστος μήνα (sum completed tasks του τρέχοντα μήνα)

🔎

3-Column Filters + Live Search

Listing dropdown, type dropdown (7 τύποι), status dropdown (5 states) + full-text search σε title/assignee/listing name — όλα combinable, instant filtering client-side

Νέα Εργασία — 4 Sections

/dashboard/pms/tasks/new — WHAT (type radio cards με icons + title + listing + description), WHEN (scheduled datetime + 5 status pills — completed_at field εμφανίζεται μόνο όταν status=completed), WHO (assignee name/phone/email), MONEY (cost σε € + internal notes)

📅

Auto-Default σε Αύριο 10:00

Νέα εργασία ξεκινά με scheduled_at = αύριο 10πμ — sensible default για cleanings/maintenance. Prefill via ?listing_id=&booking_id=&scheduled_at= querystring για αυτόματη δημιουργία από checkout flow στο μέλλον

✏️

Επεξεργασία + Διαγραφή

/dashboard/pms/tasks/[id] — όλα τα πεδία editable, one-click status change, delete με confirm prompt. Shared <TaskForm/> component μεταξύ create & edit. Όταν status→completed, το completed_at γεμίζει αυτόματα με το τώρα αν ήταν κενό

🎨

Rose Theme + Overdue Highlighting

Rose/pink hero gradient, τύποι εργασιών με δικό τους χρωματικό chip, date block γίνεται rose όταν overdue. Status pills είναι buttons στο form (amber pending, sky in-progress, emerald completed, rose cancelled, slate skipped)


v3.18.0

19 Απριλίου 2026

PMS Pricing Rules — Seasonal, Weekend, LOS, Last-Minute

💰

Λίστα Κανόνων /dashboard/pms/pricing

Όλοι οι κανόνες σε κάρτες με type icon (Seasonal/Weekend/Long Stay/Last-minute/Custom), Active ή Paused pill, condition summary (date range, weekdays, min nights, days before) και οικονομικό impact σε χρώμα (+prasino πρόσθεση, -kokkino έκπτωση, =ble override, ×portokali multiply)

🎯

5 Τύποι Κανόνων

Seasonal (date range, π.χ. Peak Ιουλ-Αυγ +40%), Weekend (Πα-Κυ +20% με day pills picker), Long Stay (≥7 νύχτες -10%, ≥14 -15%), Last-minute (≤7 μέρες πριν -15%), Custom (όλα τα fields optional για hybrid rules)

🔄

4 Operations × 2 Units

Set price (override), Add, Subtract, Multiply — με toggle μεταξύ Percentage (%) ή Absolute (€). Radio cards με icon + περιγραφή για να καταλαβαίνει κανένας τι κάνει ο κανόνας χωρίς εξήγηση

🔍

Live Price Preview

Βλέπεις σε real-time το "Βασική τιμή → Τελική τιμή" με % difference καθώς αλλάζεις amount/operation/unit. Χρωματισμός: emerald αν ανέβασες, rose αν κατέβασες, slate αν ίδια. Χρησιμοποιεί το listing.price_per_night

📅

Weekday Picker

7 pill buttons (Κυ-Σα) για weekend και custom rules — tap για select/deselect. Αποθηκεύεται ως INT[] στη βάση (0=Κυριακή). Αν πατήσεις όλα τα Σα & Κυ, έχεις κλασικό Σαββατοκύριακο

Priority + Active Toggle

Priority 0-1000 (default 100) — υψηλότερο νούμερο υπερισχύει όταν επικαλύπτονται κανόνες. Active toggle για pause/resume χωρίς διαγραφή (π.χ. παύση winter rates το καλοκαίρι)


v3.17.0

19 Απριλίου 2026

PMS Bookings — Λίστα Κρατήσεων + Manual Entry

📋

Λίστα Κρατήσεων /dashboard/pms/bookings

Όλες οι κρατήσεις σε κάρτες με dates block, status pill (Ερώτημα/Εκκρεμεί/Επιβεβαιωμένη/Έχει φτάσει/Έφυγε/Ακυρώθηκε), source dot (Direct/Airbnb/Booking/VRBO/Manual), payment pill (Απλήρωτο/Προκαταβολή/Εξοφλημένο), guest info + listing + nights + total amount — sorted με πιο πρόσφατες πάνω

📊

Stats Σύνοψη σε 4 κάρτες

Έρχονται (check-in στις επόμενες 7 μέρες), Τώρα στο κατάλυμα (checked-in guests), Έσοδα μήνα (confirmed + in-stay bookings του τρέχοντα μήνα), Σύνολο (όλες οι ενεργές — εκτός cancelled/blocked)

🔎

Smart Filters

Status pills (όλα τα 7 state), listing dropdown (όλα τα καταλύματά σου), live search σε guest_name/email/phone. Clear filters button όταν δεν ταιριάζει τίποτα

Νέα Κράτηση — Manual Entry

/dashboard/pms/bookings/new — κατάχωρηση κράτησης που ήρθε τηλεφωνικά, με email ή walk-in. 5 sections: Διαμονή (listing + dates με auto nights count), Επισκέπτης (name/email/phone/country/ενήλικες/παιδιά), Status & Source, Οικονομικά (τιμή × νύχτες + καθαριότητα + φόροι → auto total ή manual override), Σημειώσεις

✏️

Επεξεργασία + Διαγραφή

/dashboard/pms/bookings/[id] — όλα τα πεδία editable, change status με ένα click, delete με confirm prompt. Shared <BookingForm/> component για create & edit paths

🛑

Block Mode

Όταν status=blocked ή source=blocked, κρύβονται guest/financials fields και εμφανίζεται μόνο "Αιτία μπλοκαρίσματος" (π.χ. συντήρηση, προσωπική χρήση) — για όταν θες να κλείσεις ημερομηνίες χωρίς guest

💳

Payment Status Pills

5 καταστάσεις: Unpaid (rose), Deposit Paid (amber), Fully Paid (emerald), Refunded (slate), N/A. Χειροκίνητη ενημέρωση μέχρι να ενεργοποιηθεί το Stripe Connect flow


v3.16.0

19 Απριλίου 2026

PMS Settings — Φορολογικά, Πολιτικές, Cancellation & Ειδοποιήσεις

🧾

Φορολογικά στοιχεία σε ένα μέρος

ΑΦΜ, ΑΜΑ (Αριθμός Μητρώου Ακινήτου βραχυχρόνιας μίσθωσης ΑΑΔΕ), συντελεστής ΦΠΑ (default 13% τουριστικός), toggle για τουριστικό φόρο με ποσό ανά διανυκτέρευση — όλα αποθηκεύονται στο pms_owner_settings και θα περιλαμβάνονται αυτόματα στα emails επιβεβαίωσης για νόμιμη τιμολόγηση

📆

Πολιτικές Κράτησης Defaults

Instant Book toggle (αν OFF, κάθε κράτηση περνά από έγκριση), ώρες check-in/out, min/max διανυκτερεύσεις, advance notice σε ώρες, preparation days buffer μεταξύ κρατήσεων — defaults που θα κληρονομούν όλα τα καταλύματα (per-listing overrides αργότερα)

Cancellation Policy 4-in-1

Radio cards για Ευέλικτη (24h πριν) / Μέτρια (7 μέρες πριν) / Αυστηρή (no refund) / Custom (δικά σου λόγια με textarea) — θα εμφανίζεται στο public listing και στα emails επιβεβαίωσης κράτησης

💳

Payments Preview

Stripe Connect status card (read-only μέχρι να ολοκληρωθεί το OAuth onboarding flow), deposit percentage (default 20%), balance due days before check-in (default 14) — ready για όταν ενεργοποιηθεί direct bookings με 0% commission

🔔

Ειδοποιήσεις Owner

Reply-to email για guests (fallback στο account email αν κενό), τηλέφωνο ειδοποιήσεων, SMS toggle (coming soon) — πού να βρίσκουν τον owner οι guests και πού να φτάνουν τα alerts για νέες κρατήσεις

🎨

Color-Coded Sections

5 κάρτες με ξεχωριστή παλέτα ring+icon (amber tax, sky booking, rose cancellation, emerald payments, violet notifications), sticky save bar σε mobile (fixed bottom) + inline σε desktop, upsert με onConflict: owner_id — single atomic save για όλο το form


v3.15.1

19 Απριλίου 2026

Bug Fix — PMS Calendar έδειχνε "Δεν έχεις listings ακόμα"

🐛

Query ζητούσε ανύπαρκτη column

Το /dashboard/pms/calendar έστελνε select στη column listings.is_active που δεν υπάρχει (το schema έχει status: draft/published/archived) — η Postgres γύριζε 42703 "column does not exist" και η σελίδα έπεφτε στο empty state παρόλο που ο owner είχε καταχωρημένο κατάλυμα. Αλλαγή σε status + error surfacing + fallback link στο /dashboard/listings


v3.15.0

19 Απριλίου 2026

PMS Calendar — Ένα Ημερολόγιο ανά Κατάλυμα

📅

Stacked Sections — Ένα Calendar per Listing

Το /dashboard/pms/calendar δεν δείχνει πλέον ένα μόνο ημερολόγιο με dropdown επιλογής καταλύματος — δείχνει ξεχωριστή ενότητα για κάθε κατάλυμα του owner, στοιβαγμένες κάθετα. Κάθε section έχει δικά της feeds, export URL, block-dates, event details — όλα ανεξάρτητα μεταξύ τους

📱

Mobile-First Layout

Grid που στοιβάζει σε mobile (feeds panel πάνω, calendar κάτω) και γίνεται side-by-side σε desktop (340px feeds | rest calendar). Το μηνιαίο navigation και το χρωματικό legend είναι shared και sticky στο top

🔄

Next.js 16 Proxy Migration

Το deprecated middleware.ts μετονομάστηκε σε src/proxy.ts σύμφωνα με την Next.js 16 convention. Χωρίς αυτό το rename, όλα τα locale-less URLs (/auth/login, /listings, /dashboard) επέστρεφαν 404 — το next-intl locale routing δεν έτρεχε καθόλου. Now back to normal


v3.14.1

19 Απριλίου 2026

Bug Fix — Password Reset Email Έβγαζε σε localhost:3000

🐛

Bypass του Supabase Redirect Flow

Το /auth/v1/verify του Supabase αγνοούσε το δικό μας redirect_to (δεν ήταν στο allow-list των Redirect URLs) και έπεφτε πίσω στο project Site URL που ήταν http://localhost:3000 — ο χρήστης κατέληγε σε σελίδα που δεν υπάρχει στο production. Το email link τώρα δείχνει απευθείας στο /auth/reset-password με token_hash και η σελίδα κάνει verifyOtp στο client, χωρίς περάσμα από τον Supabase verify endpoint


v3.14.0

19 Απριλίου 2026

Super-Admin — One-Click Password Reset Email per User

🔑

Password Reset Button στο /admin/users

Νέο εικονίδιο κλειδιού δίπλα από κάθε χρήστη στο admin users table — ένα κλικ στέλνει στον χρήστη email επαναφοράς κωδικού. Με confirm prompt + loading spinner + activity log entry

✉️

Branded Recovery Email

Νέο /api/admin/send-password-reset endpoint — δημιουργεί recovery link μέσω Supabase admin API και το στέλνει με το υπάρχον Gmail SMTP. Branded HTML template (teal gradient header, CTA button, fallback link, security note) ίδιου στιλ με τα QR emails

🔐

Νέα /auth/reset-password Σελίδα

Public landing page όπου καταλήγει ο χρήστης από το email — διαβάζει tokens από το URL hash, κάνει setSession, ζητά νέο κωδικό (≥6 χαρακτήρες, με confirm field), redirect στο login μετά την επιτυχή αλλαγή


v3.13.1

18 Απριλίου 2026

Bug Fix — Type Filter Pages Έδειχναν Μόνο τα 50 Πιο Πρόσφατα

🐛

Όλα τα Καταλύματα στο /listings/type/*

Το /listings/type/with-pool (και όλες οι type-filter σελίδες: sea-view, pet-friendly, family, budget, luxury) ζητούσε μόνο 50 καταλύματα — όσα έχουμε πλέον > 50 publishes, τα παλαιότερα κόβονταν ΠΡΙΝ εφαρμοστεί το client-side φίλτρο. Αποτέλεσμα: καταλύματα με πισίνα σαν το Thespis Villa 2 λείπανε. Αφαιρέθηκε το limit για να ταιριάζει με τη συμπεριφορά του /listings


v3.13.0

17 Απριλίου 2026

Free Social Media Kit Auto-Generator per Listing

🎨

Social Media Kit

Νέα σελίδα /dashboard/listings/[id]/social-kit — ο owner κατεβάζει με ένα κλικ ZIP με 3 έτοιμα γραφιστικά (Instagram Square 1080×1080, Instagram Story 1080×1920, Facebook/X Card 1200×630) φτιαγμένα από τη cover + title + tagline + location του καταλύματος

📱

QR σε κάθε Graphic

Κάθε εικόνα περιέχει branded QR code που δείχνει στη σελίδα του listing (/listings/[slug]) — όποιος το σκανάρει πάει κατευθείαν στην κράτηση

📝

Ready-to-Post Caption

Έτοιμο ελληνικό κείμενο με emojis, hashtags (#Halkidiki #ChalkidikiHub #VisitGreece) + copy button — για γρήγορο share χωρίς να γράφει τίποτα ο owner

📦

ZIP Bundle + README

Lazy-loaded JSZip φτιάχνει client-side το ZIP με τα 3 PNGs + README.txt που έχει filenames, dimensions, platform mapping και το caption

Edge Runtime + Satori

/api/social-kit/[format] τρέχει σε edge με next/og ImageResponse — base64-embedded cover + QR (api.qrserver.com), όχι Node-only APIs. 5-10 min browser cache για γρήγορο preview

🎓

First-Visit Onboarding

3-step modal (Welcome → 3 formats, 1 click → Γιατί έχει σημασία) + 30s "How it works" + 6 benefit tiles + FAQ accordion + bottom CTA — explains γιατί αξίζει χωρίς jargon

🔗

Entry στο Dashboard Listings

Νέο pink-rose gradient κουμπί "Social Kit" δίπλα στο QR button σε κάθε listing card — όχι κρυμμένο σε menu


v3.12.0

17 Απριλίου 2026

Owner UX Overhaul + Analytics Beta + Clean Translation Split

🪄

Dashboard Listings Redesign

Cards με cover thumbnail, Ενεργό/Κλειστό pill, labeled action bar (Στοιχεία, Site, Ημερολόγιο, QR, Στατιστικά), search + status pills με live counts

📱

QR Code Marketing Boost

Full-width dismissible promo banner + purple→fuchsia gradient button "QR για επισκέπτες" με pulsing amber dot — αντικαθιστά το invisible icon

🔒

Translation Moved to Admins

Owners γράφουν μόνο ελληνικά. Αφαιρέθηκαν ~540 γραμμές AI translation UI από FaqsEditor, EmergencyContactsEditor, HouseRulesEditor, PracticalInfoEditor, ExtrasEditor, PhotoCaptionsEditor, ClosedStateEditor + brand page

🌐

Admin Brand Editor Expanded

13 multilingual fields × 7 locales = 91 cells σε ένα side-by-side editor: title, description, tagline, owner_story, closed_reason, house_rules_extra, how_to_reach, wifi_info, parking_info, check_in_info, meta_title, meta_description, image_alt

📊

Analytics Dashboard (Beta)

/dashboard/listings/[id]/analytics με seeded deterministic demo data: 30-day sparkline (inline SVG), country/source/language breakdown, click actions ranking, stat cards με period deltas

🎯

Clean Sidebar

Αφαιρέθηκαν "Ημερολόγια" + "Φτιάξε το site σου" από owner menu — όλα accessible από cards, λιγότερα menu items

🛡️

Resilient Queries

select("*") pattern στο my-listings survives schema drift — αν λείπει column, το page δεν σκάει, δείχνει error banner με hint

🗄️

Migration 030

image_alt_{7 locales} στο listings table + backfill του single image_alt στο image_alt_el


v3.11.0

17 Απριλίου 2026

Temporarily Closed Flag per Listing

🔒

Is-Closed Toggle

Owners μπορούν να κλείσουν προσωρινά το κατάλυμα (σεζόν, ανακαίνιση, προσωπικοί λόγοι) χωρίς να το διαγράψουν ή να κάνουν unpublish

📅

Reopening Date + Reason

Optional ημερομηνία επαναλειτουργίας + αιτιολογία (π.χ. "Ανακαίνιση — επανερχόμαστε Απρίλιο 2026") σε 7 γλώσσες

🎨

Closed Banner στο /stay

Amber-to-orange gradient banner στην κορυφή της σελίδας όταν το κατάλυμα είναι κλειστό — contact buttons παραμένουν για μελλοντικές κρατήσεις

🏷️

Κλειστό Chip Παντού

Visible chip στο /dashboard/listings cards, site-builder hub, admin brand-sites — καθαρή διάκριση από draft/published status

🗄️

Migration 029

listings.is_closed (boolean, default false) + listings.reopening_date + closed_reason_{7 locales}


v3.10.0

17 Απριλίου 2026

Admin Brand Sites Manager + Multilingual Editor + SEO Generator

🏠

/admin/brand-sites Hub

Super-admin βλέπει όλα τα brand pages: coverage badges ανά γλώσσα (x/7), completeness score 0–6, search + area filter, counts για FAQs / Emergency / Extras / Captions

🌍

Side-by-Side 7-Language Editor

Νέο MultilangField component: tabs ανά γλώσσα με ✓ checkmark όταν έχει content, coverage x/7, per-field "Fill missing" button που γεμίζει ελλείπουσες γλώσσες με AI

Bulk "Translate Missing" Action

Ένα κλικ περπατάει όλα τα fields × 6 locales και γεμίζει ελλείπουσες μεταφράσεις από EL ή EN fallback — 54+ translations σε ένα save

🔍

AI SEO Meta Generator

Νέο /api/ai/generate-seo endpoint: GPT-4o-mini παράγει meta_title (55-60 chars) + meta_description (140-160 chars) σε όλες τις 7 γλώσσες — benefit-focused, preserves proper nouns

👥

Site-Builder για Admins

Super-admin στο /dashboard/site-builder βλέπει πλέον ΟΛΑ τα καταλύματα (όχι μόνο τα δικά του) με violet "Admin mode" banner + owner email chip σε κάθε card


v3.9.0

17 Απριλίου 2026

House Rules + Practical Info + Extras + Photo Captions + Nearby Overrides

🛡️

House Rules

Check-in/out times, κάπνισμα (allowed/outside/no), κατοικίδια (allowed/on_request/no), πάρτι, παιδιά, ώρες κοινής ησυχίας + free-text extras. Pill-button selectors για κάθε κανόνα

ℹ️

Practical Info

4 textareas: Πώς θα φτάσετε, Οδηγίες check-in, Wi-Fi, Στάθμευση. Εμφανίζονται σε 2×2 grid cards στο /stay page

Extras & Services

Unlimited add-ons με 9 icon types (Πρωινό, Μεταφορά, Καθαριότητα, Ποδήλατο, Σκάφος, Spa κ.λπ.), τιμή + μονάδα (ανά διαμονή/βράδυ/άτομο/χρήση) ή "Περιλαμβάνεται δωρεάν"

📸

Photo Captions

Λεζάντες ανά φωτογραφία, εμφανίζονται σε hover overlay στη gallery του /stay. Helps SEO alt text + guest context

🗺️

Nearby Overrides

Auto-computed λίστα κοντινών παραλιών/εστιατορίων/δραστηριοτήτων/χωριών με Haversine. Owner μπορεί να hide/unhide individual items

🗄️

Migration 028

listings.check_in_time, rule_*, quiet_hours_*, house_rules_extra_{7}, how_to_reach_{7}, wifi_info_{7}, parking_info_{7}, check_in_info_{7} + listing_images.caption_{7} + new listing_extras table


v3.8.0

17 Απριλίου 2026

FAQs CRUD + Emergency Contacts + Legal Compliance

FAQs με FAQPage Schema

Owners προσθέτουν custom Q&A — inline FAQPage microdata (Schema.org Question/Answer) στο /stay → Google rich results με expandable FAQ carousel στα SERP

🚨

Emergency Contacts

6 default ΕΕ/Ελλάδας numbers εμφανίζονται ΠΑΝΤΑ (112, 100 Αστυνομία, 166 ΕΚΑΒ, 199 Πυροσβεστική, 108 Λιμενικό, 10135 Δηλητηριάσεις) + owner adds τοπικές επαφές

⚖️

Greek Legal Compliance Info

Amber info banner στον editor: "Σύμφωνα με Ν. 4276/2014 (τουριστικά καταλύματα), Ν. 4179/2013, κανονισμούς πυρασφάλειας…" — καλή πρακτική για βραχυχρόνιες μισθώσεις

📱

Tap-to-Call Everywhere

Κάθε τηλέφωνο είναι <a href="tel:…"> — ο guest πατάει και καλεί κατευθείαν από το κινητό του

🗄️

Migration 027

listing_emergency_contacts table: icon_key (10 types), phone, label_{7 locales}, notes_{7 locales}. RLS: public SELECT, owner/admin write


v3.7.0

17 Απριλίου 2026

Dedicated /stay/[slug] Brand Page

Standalone Brand Site

Κάθε κατάλυμα αποκτά δική του full-bleed σελίδα στο /stay/[slug], τελείως διαφορετική εμπειρία από το απλό /listings/[slug] directory entry

🖼️

Hero with Personality

70vh full-width cover image, italic tagline, sticky facts bar (guests · beds · baths · price), contact CTAs (WhatsApp, phone, email)

📖

Story-Driven Layout

Sections με ιεραρχία: Our Story (gradient centered) → Gallery → Description → Amenities → What's Nearby → Map → Availability → FAQs → Contact CTA → Emergency

🔗

Smart Sitemap

/stay/{slug} URLs εμφανίζονται στο sitemap ΜΟΝΟ όταν ο owner έχει γράψει tagline ή story — αποφεύγει duplicate content με /listings

🎯

Directory Cross-Link

Gradient pill "Δείτε το site του καταλύματος →" στο /listings όταν το listing έχει brand content


v3.6.0

17 Απριλίου 2026

Brand Page Tier-1: Tagline, Our Story, Auto Nearby, FAQs Display

🎯

Tagline / Σλόγκαν

Μικρή φράση (~80 chars) κάτω από τον τίτλο του καταλύματος. Είναι το πρώτο πράγμα που τραβά το μάτι του επισκέπτη

📖

"Η ιστορία μας"

Προσωπική αφήγηση του owner για το κατάλυμα (gradient card). Differentiator που κανένα listing site δεν προσφέρει

🌍

Auto "What's Nearby"

Haversine distance calculation με lat/lng bounding box — εμφανίζει nearest παραλίες, εστιατόρια, δραστηριότητες, χωριά με αποστάσεις σε km/m

🗺️

Nearby API Endpoint

Νέο /api/nearby?listing_id=X — returns grouped results, respects owner overrides (hidden items + custom notes)

FAQ Display

Accordion με FAQPage JSON-LD στο /stay. CRUD editor έρχεται στο v3.8

🤖

Translate-Fields API

Generic /api/ai/translate-fields endpoint: send {sourceLocale, fields: {name: text…}}, get back 6-locale translations per field. GPT-4o-mini με JSON response format

🗄️

Migration 026

listings.tagline_{7} + owner_story_{7} + listing_faqs table + listing_nearby_overrides table (owner can hide/reorder auto-suggestions)


v3.5.0

17 Απριλίου 2026

Calendars Hub + Public Visibility Toggle

📅

New Calendars Hub

Dashboard → Ημερολόγια → βλέπεις όλα τα καταλύματα σου με blocked-days counter ανά κατάλυμα

👁️

Show Calendar Toggle

Eye/EyeOff toggle per listing — default OFF (safe for existing listings), owner opt-in. Ελέγχει αν το calendar εμφανίζεται στο /listings directory page

🔓

Always on /stay

Στην προσωπική σελίδα /stay/[slug] το calendar εμφανίζεται ΠΑΝΤΑ — το toggle αφορά μόνο το directory listing

🗄️

Migration 025

listings.show_calendar boolean NOT NULL DEFAULT false


v3.4.0

17 Απριλίου 2026

Availability Calendar για Listings

📆

Owner Calendar Editor

3-month grid με click-to-toggle: 🟠 Μπλοκαρισμένη, 🔴 Κρατημένη, 🟢 Διαθέσιμη. Batch save με pending-changes counter, bulk clear all, past dates disabled, today highlighted

👀

Public Mini Calendar

2-month read-only view στο listing page — άσπρα cells = διαθέσιμη, κόκκινα = μη διαθέσιμη. Localized month/day names για όλες τις 7 γλώσσες

📱

Mobile Tap Targets

Responsive grid, touch-friendly buttons, active:scale-98 feedback

🔐

RLS Security

listing_availability table με public read + owner/admin write policies — RLS ελέγχει ότι δεν πειράζει κανένας κάποιο άλλο listing

🗄️

Migration 024

Νέα listing_availability table με (listing_id, date, status ∈ {blocked,booked}, note). Unique (listing_id, date), auto-updated timestamps


v3.3.0

17 Απριλίου 2026

9 Νέοι SEO Hook Guides: Comparisons + Niche + Practical Tips

⚖️

Halkidiki vs Crete

Σύγκριση με την Κρήτη: παραλίες, πρόσβαση, κόστος, φαγητό, ποιος νικάει. Target: "Halkidiki vs Crete" keyword

⚖️

Halkidiki vs Rhodes

Σύγκριση με τη Ρόδο — ιστορία, παραλίες, κλίμα, κόστος διαμονής

⚖️

Halkidiki vs Corfu

Ιόνιο vs Αιγαίο — climate, beaches, access, Venetian architecture

👵

For Seniors

Guide για ηλικιωμένους: εύκολη πρόσβαση, ήρεμες παραλίες, ιατρικές υπηρεσίες, all-inclusive resorts

💑

For Couples

Πέρα από honeymoon — ρομαντικές παραλίες, δείπνα με θέα, ιδανική περίοδος (Μάιος/Σεπτέμβριος)

🧳

For Solo Travelers

Ασφάλεια, μεταφορές KTEL, social spots, budget €60-100/μέρα, πού να μείνεις

💡

Halkidiki Tips

20+ insider tips: booking timing, beaches, food, exploration, practical — με εσωτερικούς συνδέσμους σε /guide/*

⚠️

Mistakes to Avoid

Συχνά λάθη τουριστών (last-minute booking, only Kassandra, tourist trap restaurants, no cash)

🛡️

Scams to Avoid

Taxi meter, menu χωρίς τιμές, "free" loungers, DCC σε κάρτες, fake "τοπικό" λάδι — πώς να προστατευτείς

📊

63 Νέα SEO URLs

9 guides × 7 γλώσσες στο sitemap. Όλα με Article + BreadcrumbList JSON-LD + εσωτερικά links


v3.2.5

17 Απριλίου 2026

SEO Hook Pages Expansion: +126 Travel / Itinerary / Cost URLs

🚗

Travel from [City] Pages

8 νέες σελίδες: από Σόφια, Βουκουρέστι, Βελιγράδι, Θεσσαλονίκη, Μόναχο, Κωνσταντινούπολη, Σκόπια, Αθήνα. Πλούσιο περιεχόμενο με internal links, χρόνοι διαδρομής, συμβουλές

📅

Itinerary Pages

5 μέρες, 7 μέρες, 10 μέρες, 3 μέρες, weekend — detailed day-by-day planning με εσωτερικούς συνδέσμους σε beaches/restaurants/villages

💶

Cost Guide Pages

5 budget guides: daily budget, food prices, accommodation prices, car rental prices, family budget — πραγματικές τιμές για Χαλκιδική 2026

🔗

Internal Linking Strategy

Κάθε νέα σελίδα έχει 2-4 internal links προς beaches / restaurants / activities / villages / άλλους guides → traffic funneling στο κεντρικό site

🌐

+126 SEO URLs

18 slugs × 7 γλώσσες = 126 νέα sitemap entries με Article + BreadcrumbList JSON-LD

🧹

Cleanup Fixes

Redesigned villages grid στο /areas για mobile (uniform 2-column cards), new /places index page, ItemList JSON-LD για rich results, Mega.webp orphan removed


v3.2.0

14 Απριλίου 2026

Performance Overhaul, Keyword SEO Articles, Smart Search, Auth Fix

ISR + Server-Side Data

Όλες οι σελίδες (collection + detail) φορτώνουν server-side — zero skeleton flash, 10x γρηγορότερο πρώτο load

🖼️

next/image Παντού

Όλα τα cards + blog images χρησιμοποιούν next/image — auto WebP/AVIF, responsive srcSet, 60% μικρότερα αρχεία

🔄

On-Demand Revalidation

Νέο /api/revalidate — admin save → instant cache purge σε 7 γλώσσες. ISR 1 ώρα + on-demand = 95% λιγότερα writes

📦

generateStaticParams

571+ restaurants, 100+ beaches, 70+ activities pre-built στο deploy — zero latency στο πρώτο visit

🔍

Server-Side Search

Νέο /api/search — GlobalSearch κάνει 1 debounced call αντί 5 full-data fetches. -70% bandwidth

🔗

Combined Related Content API

Detail pages κάνουν 1 fetch αντί 3-4 — /api/related-content endpoint. -200-400ms ανά σελίδα

📜

Script Optimization

Google Analytics/AdSense χρησιμοποιούν next/script lazyOnload αντί blocking <script> tags

🔑

20 Keyword SEO Articles

Generator 20 θεματικών articles γύρω από bold keywords χωριών — 246 keywords → auto internal links

🌐

Blog Translation Fix

Batch translation (2 γλώσσες/κλήση × 3 batches) — δεν σκάει σε μεγάλα κείμενα + progress indicator

🔐

Admin Auth Rewrite

requireSuperAdmin() χρησιμοποιεί @supabase/ssr αντί manual cookie parsing — φτιάχνει delete user, send email, reviews

🤖

OpenAI Retry Logic

Όλα τα 6 AI routes: auto-retry, rate limit handling (429), empty response validation

🗺️

OSM Preconnect

Preconnect + dns-prefetch για OpenStreetMap tiles — πιο γρήγοροι χάρτες

💾

Vercel Limits Fix

ISR revalidate 60s → 3600s — μείωση 95% ISR writes (171K/200K → ~5K/μήνα)

🏖️

Charger Slug Fetch

/api/chargers?slug=X — fetch μόνο 1 charger αντί όλους

🖼️

Lightbox Lazy Loading

ImageGallery modal image χρησιμοποιεί loading="lazy"


v3.1.0

12 Απριλίου 2026

SEO Overhaul, Dynamic OG Images, Google AdSense, Airbnb Import

🔍

SEO Overhaul

OG images, metadata σε όλες τις σελίδες, breadcrumbs, split sitemap, canonical URLs

🖼️

Dynamic OG Images

Αυτόματα generated Open Graph images ανά σελίδα για social sharing

💰

Google AdSense

Ενσωμάτωση Google AdSense (ca-pub-9694572418424066) + ads.txt

🏠

Import Airbnb/Booking

Import listings από Airbnb/Booking URL στο admin — auto-parse τίτλο, φωτό, amenities

🇷🇸

Serbian στο Blog

SR tabs σε blog edit, title/excerpt/content/SEO translations

📝

Village Article Generator

AI blog articles ανά χωριό + Beach Article Generator ανά παραλία

🔗

Auto Internal Links HTML

Auto-linking λειτουργεί και σε HTML blog articles (όχι μόνο markdown)

🛡️

Full i18n

Μετάφραση 25+ αρχείων hardcoded text σε 7 γλώσσες

📐

308 Redirects

Αλλαγή 307→308 permanent redirects για καλύτερο SEO

🔎

Admin Search & Filters

Αναζήτηση + φίλτρα σε beaches, restaurants, activities, blog admin pages

2-Step Article Generation

Article generators σπασμένοι σε 2 βήματα — αποφεύγουν Vercel timeout


v3.0.0

11 Απριλίου 2026

Serbian Language, Hero Image, Full SEO Audit, 4,000+ URLs

🇷🇸

Σερβικά (7η γλώσσα)

Πλήρης υποστήριξη Σερβικών: UI, DB columns, AI translations, SEO meta, sitemap — 573 νέα URLs

🖼️

Hero Background Image

Ρυθμιζόμενη background εικόνα στο hero section της αρχικής σελίδας μέσω admin Settings

🔍

Full SEO Audit & Fix

Hreflang 7 γλωσσών σε ΟΛΕΣ τις σελίδες, canonical URLs, meta titles σε SR, terms/privacy/map metadata

Mount Athos SR

Πλήρης μετάφραση οδηγού Αγίου Όρους στα Σερβικά — 8 σελίδες + 20 μονές

🤖

AI 7 Languages

AI Auto-Complete, Bulk Fill, Auto-Blog — όλα υποστηρίζουν 7 γλώσσες + undefined guard

📊

4,011 Sitemap URLs

573 σελίδες × 7 γλώσσες = 4,011 URLs στο sitemap, 0 errors


v2.5.0

10 Απριλίου 2026

Seasonal Guides, Listing Types, Broken Links Scanner, Blog Fix

🗺️

Seasonal Guides

7 θεματικοί οδηγοί (summer, easter, honeymoon, families, budget, winter, nightlife) × 6 γλώσσες = 42 URLs

🏠

Listing Type Pages

6 τύποι καταλυμάτων (pool, sea-view, pet-friendly, family, budget, luxury) × 6 γλώσσες = 36 URLs

🔗

Broken Links Scanner

Νέο εργαλείο στο admin — σκανάρει εσωτερικούς links σε όλο το content, βρίσκει broken

📝

Blog HTML Fix

AI articles τώρα renderάρονται σωστά με HTML formatting αντί raw tags

🤖

Auto-Blog Fix

Κάθε κλικ = διαφορετικό άρθρο (topic rotation βάσει count), Unsplash photos


v2.4.0

10 Απριλίου 2026

Best Of Guides, Auto-Blog Settings, Unsplash Photos

🏆

Best Of Guide Pages

12 οδηγοί (beaches, restaurants, activities per area/theme) × 6 γλώσσες = 72 SEO URLs

⚙️

Auto-Blog Settings

On/Off, συχνότητα (ώρες), ώρα εκτέλεσης — ρυθμιζόμενα από admin Settings

📸

Unsplash Photos

AI articles αυτόματα βρίσκουν σχετική φωτογραφία μέσω Unsplash API

✍️

Rich Formatting

AI articles με h2/h3/lists/blockquote/bold — travel blog style

🔒

Auth Fix

Auto-blog auth μέσω Bearer token + admin client role check


v2.3.0

10 Απριλίου 2026

Auto-Blog AI, Beach Features, Village Combos, 3,300 SEO URLs

🤖

Auto-Blog Generator

AI γράφει 1 άρθρο/ημέρα αυτόματα — 14 rotating topics, πραγματικά data, 6 γλώσσες, SEO, δημοσίευση

🏖️

Beach Feature Pages

12 χαρακτηριστικά παραλιών (sandy, organized, nudist κλπ) × 6 γλώσσες = 72 SEO URLs

🏘️

Village Content Combos

68 χωριά × 3 types (beaches/restaurants/activities) × 6 γλώσσες = 1,224 SEO URLs

📍

Village Pills σε Areas

Κάθε area page δείχνει τα χωριά της ως clickable pills με πληθυσμό

📊

3,300 Sitemap URLs

Σύνολο σελίδων στο sitemap — 0 errors σε full crawl


v2.2.0

10 Απριλίου 2026

Sun & Sea Logo, Monastery Images, Brand Identity

☀️

Sun & Sea Logo

Νέο brand logo — ήλιος + κύματα σε cyan φόντο. Εφαρμογή σε header, footer, favicon, PWA manifest

🖼️

Monastery Images

Κάθε μονή δείχνει φωτογραφία στο hero + full image section στη σελίδα της

🎨

Brand Identity

Reusable BrandIcon component, updated theme-color #0891B2, SVG favicons


v2.1.0

10 Απριλίου 2026

Monastery Admin, Village Filters, Security Hardening, 68 Villages

Monasteries Admin CRUD

Επεξεργασία μονών Αγίου Όρους: 6 γλώσσες, AI Generate description + highlights, AI Auto-Complete SEO

🏘️

68 Χωριά (29 Ενδοχώρα)

29 νέα χωριά Ενδοχώρας — Πολύγυρος, Αρναία, Ολυμπιάδα, Γερακινή κ.α. Σύνολο 408 SEO URLs

🔍

Village Filters & Sorting

Αναζήτηση, φίλτρα (area, image, SEO, population), sortable columns, stats bar

🔒

Security Hardening

Auth checks σε όλα τα admin API, input validation, XSS sanitization, service role key protection

Performance Fixes

Sitemap ISR, map page limits, comments/inquiry caching

20 Monastery Pages

Κάθε μονή δική της σελίδα — 120 SEO URLs, prev/next navigation, JSON-LD, 6 γλώσσες


v2.0.0

10 Απριλίου 2026

Mount Athos Guide, 6-Language Translations, Area Banner

Οδηγός Αγίου Όρους

8 σελίδες: μοναστήρια, κανόνες, μεταφορές, διαμονή, ζωή, πεζοπορία, ιστορία — πλήρης μετάφραση 6 γλωσσών

🌍

48 SEO URLs

8 σελίδες × 6 γλώσσες με meta titles, descriptions, hreflang, JSON-LD schemas

🏷️

Athos Area Banner

Ωραίο banner στη σελίδα /areas/athos που οδηγεί στον πλήρη οδηγό Αγίου Όρους

📝

JSON-LD Schemas

TouristAttraction, Article, FAQPage, ItemList — πλούσια δεδομένα για Google


v1.9.0

10 Απριλίου 2026

Live Weather, AI Formatted Descriptions, SEO Tools Update

🌤️

Live Weather Badge

Τρέχων καιρός (θερμοκρασία + icon) στο hero κάθε χωριού μέσω OpenWeatherMap

📝

AI Formatted Descriptions

Το AI Generate γράφει μορφοποιημένο HTML (headings, lists, bold) για ωραία ανάγνωση

🔍

Villages στα SEO Tools

Τα χωριά συμπεριλαμβάνονται σε Quality Checker, Translation Matrix, SEO Dashboard, AI Bulk SEO

🏘️

39 Χωριά Updated

Κασσάνδρα (18), Σιθωνία (15), Άθως (6) — σωστή λίστα με νέα χωριά


v1.8.0

10 Απριλίου 2026

Village Pages, Admin Restructure, Footer Upgrade

🏘️

39 Village Pages

Σελίδα ανά χωριό Χαλκιδικής — Κασσάνδρα (18), Σιθωνία (15), Άθως (6) με κοντινές παραλίες, εστιατόρια, δραστηριότητες

🤖

AI Village Generator

Αυτόματη δημιουργία περιγραφής + πληθυσμού ανά χωριό μέσω AI

🗺️

Village Admin CRUD

Πλήρης διαχείριση χωριών: New/Edit/Delete + AI Auto-Complete σε 6 γλώσσες + SEO

📍

~234 νέα SEO URLs

39 χωριά × 6 γλώσσες = 234 νέες σελίδες στο sitemap για Google indexing

🏠

Footer Upgrade

"Γιατί ChalkidikiHub;" section + CTA card + Chalkidiki Sales link στο footer

👁️

Admin Preview Fix

Τα preview links σε beaches, restaurants, activities, blog, sales ανοίγουν σωστά με locale


v1.7.0

9 Απριλίου 2026

Admin & Dashboard Redesign, Translation Matrix, Quality Checker

🎛️

Admin Panel Redesign

7 ξεκάθαρα sections αντί για 5 — Places, Properties, Editorial, Moderation, Data & Media, System

📊

Dashboard Redesign (Admin)

SEO Health, Translation Coverage, Action Required banners, Recent Activity feed

🌍

Translation Matrix

Νέα σελίδα — matrix 159 items × 6 γλώσσες με AI Fill button

🛡️

Quality Checker

Νέα σελίδα — σκανάρει όλο το περιεχόμενο, εντοπίζει missing translations, SEO, images

👁️

Preview Links

Κουμπί Preview σε κάθε admin list (beaches, restaurants, activities, blog, sales)

👤

User Dashboard Redesign

Welcome message, Sales stats, compact quick actions, collapsible inquiries

🏠

Footer Upgrade

"Γιατί ChalkidikiHub;" section + CTA card + Chalkidiki Sales link

Review Badges

Pending reviews badge count στο admin sidebar


v1.6.0

9 Απριλίου 2026

Sales Section, SEO Ghost Pages, Admin Edit

🏡

Πωλήσεις Ακινήτων

Ολοκληρωμένο section πωλήσεων — κατοικίες, διαμερίσματα, γη, επαγγελματικά χώροι

🎨

Sales Custom Layout

Ανεξάρτητη αρχική, header, footer με emerald branding για τις πωλήσεις

📝

Admin Edit Sales

Επεξεργασία ακινήτων σε 6 γλώσσες + AI Auto-Complete + AI Format

🌍

Sales 6 Γλώσσες

Πλήρης μετάφραση sales section σε EL, EN, DE, BG, RU, RO

👻

156 SEO Ghost Pages

Κρυφές σελίδες ανά περιοχή/κατηγορία — μόνο στο sitemap για Google ranking

🍽️

Restaurant Category Pages

SEO σελίδες ανά τύπο εστιατορίου (/restaurants/category/[type])

🏗️

Sales Dashboard

Χρήστες δημιουργούν/διαχειρίζονται τις αγγελίες τους

🛡️

Admin Sales Moderation

Publish/unpublish, delete, edit ακινήτων από admin panel

📊

Sales Homepage

Hero, carousel, property types, οδηγίες καταχώρησης, "Τι κάνουμε στο παρασκήνιο"


v1.5.0

8 Απριλίου 2026

Dynamic Business Types, Google Import Activities

🏷️

Dynamic Business Types

Οι κατηγορίες εστιατορίων αποθηκεύονται στη DB — ο admin προσθέτει νέες χωρίς κώδικα

🤖

AI Translate Types

Μετάφραση κατηγοριών σε 6 γλώσσες με ένα κλικ

🏛️

Google Import Activities

Import δραστηριοτήτων από Google Places API με φωτογραφίες + AI περιγραφή


v1.4.0

8 Απριλίου 2026

Performance Optimization, Image Compression

Performance Limits

Όλα τα API calls έχουν πλέον ?limit= — ~80% μείωση μεταφοράς δεδομένων

📸

Image Compression

Αυτόματη συμπίεση εικόνων κατά το upload

🔍

Google Import Photos

Επιλογή φωτογραφιών + AI περιγραφή στο Google Import εστιατορίων

🗺️

Area Override

Επιλογή περιοχής κατά το Google Import


v1.3.0

7 Απριλίου 2026

User Reviews, Blog Comments, Performance Boost

User Reviews

Οι χρήστες αφήνουν κριτικές σε παραλίες, εστιατόρια, δραστηριότητες (login required)

💬

Blog Comments

Σχόλια κάτω από κάθε blog article με moderation

🔍

Interlinking Score

Εργαλείο ανάλυσης internal links ανά σελίδα + AI βελτίωση αδύναμων σελίδων

📸

Photo Filler (Unsplash)

Βρίσκει σελίδες χωρίς φωτό → αναζήτηση δωρεάν φωτογραφιών από Unsplash

🤖

AI Data Import

Bulk import παραλιών, εστιατορίων, δραστηριοτήτων μέσω AI σε 6 γλώσσες

Performance Boost

Optimized API calls (~80% λιγότερα data), cache headers, targeted queries

🍞

Φούρνος

Νέος τύπος κατηγορίας Φαγητό & Ποτό

🛡️

Anti-Spam

Honeypot fields + rate limiting σε register, contact, reviews

👤

User Delete

Ο admin μπορεί να διαγράψει χρήστες (cascading cleanup)


v1.2.0

7 Απριλίου 2026

Booking Integration, Mass Email, External Emails

📊

Booking Click Tracking

Κάθε κλικ σε Booking.com, Airbnb, Phone, Email καταγράφεται

📱

Mobile Sticky Booking Bar

Fixed bar με τιμή + CTA κουμπί σε mobile listing pages

📅

Ζητήστε Διαθεσιμότητα

Inquiry form σε κάθε listing — στέλνει email στον ιδιοκτήτη

📧

Mass Email (Gmail SMTP)

Αποστολή emails σε χρήστες — 5 λίστες + εξωτερικά emails

📬

Email History

Ιστορικό αποστολών με sent/failed counts

🔔

Notification Banners

Pending submissions + unread messages alerts στο admin dashboard

🍽️

Φαγητό & Ποτό

Μετονομασία σε "Φαγητό & Ποτό" + νέοι τύποι: Bar, Cocktail Bar, Brunch, Café-Bar, Beach Bar

📋

Admin Quick Actions

15 κουμπιά γρήγορης πρόσβασης στο admin dashboard

🇬🇷

Ελληνικοί μετρητές

Dashboard stats στα ελληνικά


v1.1.0

7 Απριλίου 2026

QR Guest Guide, Engagement Features, SEO Fixes

📱

QR Guest Guide

Digital concierge — ο πελάτης σκανάρει QR στο δωμάτιο, βλέπει παραλίες, εστιατόρια, τηλέφωνα

❤️

Favorites Counter

Heart icon στο header με αριθμό αγαπημένων

🕐

Recently Viewed

"Είδατε πρόσφατα" strip σε κάθε detail page

🔢

Notification Badges

Badges σε sidebar για pending submissions + messages

🔗

Share/Copy Link

Κουμπί αντιγραφής link σε κάθε σελίδα (Facebook, WhatsApp, Telegram, Email)

✏️

AI Content Formatting

Κουμπί "AI Μορφοποίηση" — ξαναγράφει κείμενο σε παραγράφους, τίτλους, bullet points

🖼️

Inline Blog Images

Εισαγωγή φωτογραφιών μέσα στο κείμενο blog articles

📐

Mobile Admin Panel

Hamburger menu + drawer navigation σε mobile

🎯

User Dashboard Redesign

4 χρωματιστά CTA cards: Κατάλυμα, Εστιατόριο, Δραστηριότητα, Άρθρο


v1.0.0

6 Απριλίου 2026

Full Platform Launch

🏠

Καταλύματα

Καταχώρηση ενοικιαζόμενων δωματίων με φωτογραφίες, χάρτη, amenities

🏖️

Παραλίες

13+ παραλίες Χαλκιδικής με features, rating, crowd estimation

🍽️

Εστιατόρια

70+ εστιατόρια & beach bars με reviews, τηλέφωνα, ωράρια

🏛️

Δραστηριότητες

Αξιοθέατα, εκδρομές, water sports, πεζοπορία

📝

Blog

Άρθρα & οδηγοί με AI auto-linking σε παραλίες, εστιατόρια, δραστηριότητες

EV Chargers

Live δεδομένα φορτιστών ηλεκτρικών οχημάτων (Open Charge Map)

🌍

6 Γλώσσες

Ελληνικά, Αγγλικά, Γερμανικά, Βουλγαρικά, Ρωσικά, Ρουμανικά

🤖

AI Auto-Complete

Μετάφραση + SEO σε 6 γλώσσες με ένα κλικ (GPT-4o-mini)

🔍

Fuzzy Search

Αναζήτηση Greek↔Latin: "σάρτη" = "sarti" = "σαρτι"

🗺️

Interactive Maps

Leaflet χάρτες με location picker σε κάθε καταχώρηση

📊

SEO Complete

JSON-LD, canonical, hreflang, meta tags, sitemap σε κάθε σελίδα

📋

User Submissions

Χρήστες προτείνουν εστιατόρια, δραστηριότητες, άρθρα → admin moderation

📈

Activity Logs

Καταγραφή ενεργειών χρηστών, errors, admin actions

🎨

Admin Panel

Πλήρες panel: Users, Listings, Content, SEO, Tools, Settings, Email

📱

PWA

Progressive Web App — offline support, mobile install

Built with Next.js, Supabase, Tailwind CSS & AI

ChalkidikiHub.gr — Η πλατφόρμα τουρισμού της Χαλκιδικής