From 8b96b82428bfb62327bc40d06e869c5c7e2cae2c Mon Sep 17 00:00:00 2001 From: Till JS Date: Wed, 25 Mar 2026 12:53:04 +0100 Subject: [PATCH] feat(citycorners): add 7 new location categories with 35 seed entries Add cafe, bar, park, beach, hotel, event_venue, and viewpoint categories to the CityCorners city guide. Each category includes 5 real Konstanz locations with descriptions, addresses, and coordinates. Changes across all layers: DB schema enum, DTOs, lookup keyword detection, i18n (DE/EN), map colors, filter pills, landing page, and seed data. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/citycorners/CLAUDE.md | 11 +- .../backend/src/db/schema/locations.schema.ts | 14 +- apps/citycorners/apps/backend/src/db/seed.ts | 383 +++++++++++++++++- .../src/location/location-lookup.service.ts | 38 +- .../src/location/location.controller.ts | 26 +- .../apps/landing/src/components/Filter.astro | 7 + .../landing/src/components/LocationCard.astro | 7 + .../apps/landing/src/data/locations.json | 168 ++++++++ .../apps/web/src/lib/i18n/locales/de.json | 18 +- .../apps/web/src/lib/i18n/locales/en.json | 18 +- .../apps/web/src/routes/(app)/+page.svelte | 30 +- .../web/src/routes/(app)/map/+page.svelte | 7 + 12 files changed, 702 insertions(+), 25 deletions(-) diff --git a/apps/citycorners/CLAUDE.md b/apps/citycorners/CLAUDE.md index d61866012..d35cf7a70 100644 --- a/apps/citycorners/CLAUDE.md +++ b/apps/citycorners/CLAUDE.md @@ -41,7 +41,7 @@ pnpm dev:citycorners:web # Database pnpm citycorners:db:push # Push schema pnpm citycorners:db:studio # Drizzle Studio -pnpm citycorners:db:seed # Seed 6 sample locations +pnpm citycorners:db:seed # Seed 41 sample locations # Tests pnpm --filter @citycorners/backend test # Run all tests (31 tests) @@ -58,7 +58,7 @@ PostgreSQL database `citycorners` with Drizzle ORM. ### Schema -- **locations** – name, category (enum: sight/restaurant/shop/museum), description, address, lat/lng, imageUrl, timeline (JSONB array of {year, event}) +- **locations** – name, category (enum: sight/restaurant/shop/museum/cafe/bar/park/beach/hotel/event_venue/viewpoint), description, address, lat/lng, imageUrl, timeline (JSONB array of {year, event}) - **favorites** – userId, locationId (FK → locations, cascade delete), unique constraint on (userId, locationId) ## API Endpoints @@ -115,6 +115,13 @@ All endpoints are prefixed with `/api/v1/` in production (via shared-nestjs-setu | `restaurant` | Restaurant | Restaurant | Red | | `shop` | Laden | Shop | Green | | `museum` | Museum | Museum | Purple | +| `cafe` | Café | Café | Amber | +| `bar` | Bar | Bar | Orange | +| `park` | Park | Park | Emerald | +| `beach` | Strandbad | Beach | Cyan | +| `hotel` | Hotel | Hotel | Indigo | +| `event_venue` | Veranstaltungsort | Event Venue | Pink | +| `viewpoint` | Aussichtspunkt | Viewpoint | Sky | ## Tests diff --git a/apps/citycorners/apps/backend/src/db/schema/locations.schema.ts b/apps/citycorners/apps/backend/src/db/schema/locations.schema.ts index 98a1cee2e..91015c7f8 100644 --- a/apps/citycorners/apps/backend/src/db/schema/locations.schema.ts +++ b/apps/citycorners/apps/backend/src/db/schema/locations.schema.ts @@ -8,7 +8,19 @@ import { pgEnum, } from 'drizzle-orm/pg-core'; -export const categoryEnum = pgEnum('location_category', ['sight', 'restaurant', 'shop', 'museum']); +export const categoryEnum = pgEnum('location_category', [ + 'sight', + 'restaurant', + 'shop', + 'museum', + 'cafe', + 'bar', + 'park', + 'beach', + 'hotel', + 'event_venue', + 'viewpoint', +]); export type OpeningHours = Record; diff --git a/apps/citycorners/apps/backend/src/db/seed.ts b/apps/citycorners/apps/backend/src/db/seed.ts index 78eb885f6..d45a571d8 100644 --- a/apps/citycorners/apps/backend/src/db/seed.ts +++ b/apps/citycorners/apps/backend/src/db/seed.ts @@ -15,6 +15,7 @@ async function seed() { console.log('Seeding citycorners database...'); await db.insert(locations).values([ + // === SIGHTS === { name: 'Konstanzer Münster', slug: 'konstanzer-muenster', @@ -43,6 +44,8 @@ async function seed() { imageUrl: '/images/imperia.jpg', timeline: [{ year: '1993', event: 'Aufstellung im Hafen' }], }, + + // === RESTAURANTS === { name: 'Restaurant Ophelia', slug: 'restaurant-ophelia', @@ -54,6 +57,8 @@ async function seed() { longitude: 9.1795, imageUrl: '/images/ophelia.jpg', }, + + // === SHOPS === { name: 'LAGO Shopping Center', slug: 'lago-shopping-center', @@ -64,6 +69,8 @@ async function seed() { longitude: 9.1742, imageUrl: '/images/lago.jpg', }, + + // === MUSEUMS === { name: 'Rosgartenmuseum', slug: 'rosgartenmuseum', @@ -83,9 +90,383 @@ async function seed() { latitude: 47.6637, longitude: 9.1801, }, + + // === CAFÉS === + { + name: 'Café Zeitlos', + slug: 'cafe-zeitlos', + category: 'cafe', + description: + 'Gemütliches Café in der Konstanzer Altstadt mit hausgemachten Kuchen, Frühstück und einer großen Auswahl an Kaffeespezialitäten.', + address: 'Hussenstraße 13, 78462 Konstanz', + latitude: 47.6609, + longitude: 9.1749, + }, + { + name: 'Café Wessenberg', + slug: 'cafe-wessenberg', + category: 'cafe', + description: + 'Traditionsreiches Café im Herzen von Konstanz mit Terrasse und Blick auf die Altstadt. Bekannt für Torten und Frühstücksbuffet.', + address: 'Wessenbergstraße 41, 78462 Konstanz', + latitude: 47.6614, + longitude: 9.1739, + }, + { + name: 'Café Gessler 1159', + slug: 'cafe-gessler-1159', + category: 'cafe', + description: + 'Modernes Café und Bäckerei mit langer Tradition. Frisches Gebäck, Snacks und Kaffeespezialitäten in zentraler Lage.', + address: 'Bodanstraße 9, 78462 Konstanz', + latitude: 47.6608, + longitude: 9.173, + }, + { + name: 'Voglhaus Café', + slug: 'voglhaus-cafe', + category: 'cafe', + description: + 'Beliebtes Bio-Café mit vegetarischer und veganer Küche. Kreative Frühstücksgerichte und selbstgemachte Limonaden.', + address: 'Wessenbergstraße 8, 78462 Konstanz', + latitude: 47.6619, + longitude: 9.1744, + }, + { + name: 'Café Herr Hase', + slug: 'cafe-herr-hase', + category: 'cafe', + description: + 'Kleines Specialty-Coffee-Café in der Niederburg. Third-Wave-Kaffee, Matcha und hausgemachte Leckereien.', + address: 'Niederburggasse 2, 78462 Konstanz', + latitude: 47.6623, + longitude: 9.1762, + }, + + // === BARS === + { + name: 'Klimperkasten', + slug: 'klimperkasten', + category: 'bar', + description: + 'Kultige Kneipe und Bar in der Altstadt mit Live-Musik, Cocktails und lockerer Atmosphäre. Treffpunkt für Studierende und Nachtschwärmer.', + address: 'Bodanstraße 18, 78462 Konstanz', + latitude: 47.6611, + longitude: 9.1736, + }, + { + name: 'Shamrock Irish Pub', + slug: 'shamrock-irish-pub', + category: 'bar', + description: + 'Irischer Pub mit großer Bierauswahl, Live-Sportübertragungen und regelmäßigen Quiz-Abenden. Seit Jahren eine Institution.', + address: 'Bodanstraße 28, 78462 Konstanz', + latitude: 47.6607, + longitude: 9.1728, + }, + { + name: 'Seekuh', + slug: 'seekuh', + category: 'bar', + description: + 'Legendäre Konstanzer Bar und Kulturkneipe am Seerhein. Craft Beer, Cocktails und regelmäßig Konzerte auf kleiner Bühne.', + address: 'Konradigasse 1, 78462 Konstanz', + latitude: 47.6632, + longitude: 9.1773, + }, + { + name: 'Brauhaus Johann Albrecht', + slug: 'brauhaus-johann-albrecht', + category: 'bar', + description: + 'Brauhaus-Restaurant mit hauseigenem Bier direkt am Seerhein. Deftige Küche und frisch gebrautes Bier in historischem Ambiente.', + address: 'Konradigasse 2, 78462 Konstanz', + latitude: 47.663, + longitude: 9.177, + }, + { + name: 'Schwarze Katz', + slug: 'schwarze-katz', + category: 'bar', + description: + 'Kleine, gemütliche Bar in der Katzgasse mit kreativen Cocktails und einer großen Gin-Auswahl. Perfekt für einen entspannten Abend.', + address: 'Katzgasse 7, 78462 Konstanz', + latitude: 47.6617, + longitude: 9.1752, + }, + + // === PARKS === + { + name: 'Stadtgarten Konstanz', + slug: 'stadtgarten-konstanz', + category: 'park', + description: + 'Großer Park direkt am Bodenseeufer mit altem Baumbestand, Spielplätzen, Minigolf und Biergarten. Der beliebteste Erholungsort der Stadt.', + address: 'Seestraße, 78464 Konstanz', + latitude: 47.6582, + longitude: 9.1812, + }, + { + name: 'Herosé-Park', + slug: 'herose-park', + category: 'park', + description: + 'Ruhiger Park am Seerhein mit Liegewiesen, Grillplätzen und Rheinuferweg. Ideal zum Joggen, Grillen oder Entspannen.', + address: 'Herosé-Park, 78467 Konstanz', + latitude: 47.6676, + longitude: 9.1699, + }, + { + name: 'Lorettowald', + slug: 'lorettowald', + category: 'park', + description: + 'Bewaldeter Hügel im Süden von Konstanz mit Wanderwegen und Aussichtspunkten über den Bodensee. Beliebt bei Joggern und Spaziergängern.', + address: 'Lorettostraße, 78464 Konstanz', + latitude: 47.6524, + longitude: 9.1768, + }, + { + name: 'Bücklepark', + slug: 'buecklepark', + category: 'park', + description: + 'Kleiner, gepflegter Park nahe der Universität mit Spielplatz und schattigem Baumbestand. Ein ruhiges Plätzchen abseits des Trubels.', + address: 'Bücklestraße, 78467 Konstanz', + latitude: 47.6672, + longitude: 9.1726, + }, + { + name: 'Rheinsteig-Promenade', + slug: 'rheinsteig-promenade', + category: 'park', + description: + 'Landschaftlich reizvoller Uferweg entlang des Seerheins von der Altstadt bis Petershausen. Perfekt für Spaziergänge und Radtouren.', + address: 'Rheinsteig, 78462 Konstanz', + latitude: 47.6641, + longitude: 9.1753, + }, + + // === BEACHES === + { + name: 'Strandbad Horn', + slug: 'strandbad-horn', + category: 'beach', + description: + 'Eines der größten Freibäder am Bodensee mit großer Liegewiese, Sandstrand, Sprungturm und Beachvolleyball. Traumhafter Seeblick.', + address: 'Eichhornstraße 100, 78464 Konstanz', + latitude: 47.6527, + longitude: 9.201, + }, + { + name: 'Freibad Hörnle', + slug: 'freibad-hoernle', + category: 'beach', + description: + 'Beliebtes Strandbad an der Spitze der Halbinsel Horn mit flachem Einstieg, ideal für Familien. Kiosk und Liegewiesen vorhanden.', + address: 'Hörnleweg, 78464 Konstanz', + latitude: 47.6487, + longitude: 9.207, + }, + { + name: 'Rheinstrandbad', + slug: 'rheinstrandbad', + category: 'beach', + description: + 'Freibad am Seerhein mit beheiztem Becken und Flusszugang. Seit den 1930er-Jahren ein Konstanzer Klassiker.', + address: 'Schlosserstraße 18, 78467 Konstanz', + latitude: 47.671, + longitude: 9.1661, + }, + { + name: 'Freibad Jakob', + slug: 'freibad-jakob', + category: 'beach', + description: + 'Familiäres Freibad im Stadtteil Petershausen mit Bodenseezugang, Nichtschwimmerbecken und großer Liegewiese.', + address: 'Jakobstraße 153, 78467 Konstanz', + latitude: 47.6723, + longitude: 9.1592, + }, + { + name: 'Schmugglerbucht', + slug: 'schmugglerbucht', + category: 'beach', + description: + 'Kleine, versteckte Badestelle unterhalb der Seestraße. Bei Einheimischen beliebt als Geheimtipp zum Schwimmen im Bodensee.', + address: 'Seestraße, 78464 Konstanz', + latitude: 47.6561, + longitude: 9.186, + }, + + // === HOTELS === + { + name: 'Steigenberger Inselhotel', + slug: 'steigenberger-inselhotel', + category: 'hotel', + description: + 'Luxushotel in einem ehemaligen Dominikanerkloster auf einer Insel im Bodensee. Eines der historischsten Hotels Deutschlands.', + address: 'Auf der Insel 1, 78462 Konstanz', + latitude: 47.6598, + longitude: 9.181, + timeline: [ + { year: '1235', event: 'Gründung als Dominikanerkloster' }, + { year: '1875', event: 'Umbau zum Hotel' }, + ], + }, + { + name: 'Hotel Riva', + slug: 'hotel-riva', + category: 'hotel', + description: + 'Modernes Designhotel direkt am Bodenseeufer. Beherbergt das Sternerestaurant Ophelia und bietet einen eigenen Spa-Bereich.', + address: 'Seestraße 25, 78464 Konstanz', + latitude: 47.6589, + longitude: 9.1795, + }, + { + name: 'Hotel Halm', + slug: 'hotel-halm', + category: 'hotel', + description: + 'Traditionsreiches Vier-Sterne-Hotel am Bahnhof mit eleganten Zimmern, Restaurant und zentraler Lage für Stadterkundungen.', + address: 'Bahnhofplatz 6, 78462 Konstanz', + latitude: 47.6586, + longitude: 9.1717, + }, + { + name: 'Hotel Barbarossa', + slug: 'hotel-barbarossa', + category: 'hotel', + description: + 'Historisches Boutique-Hotel am Obermarkt mitten in der Altstadt. Individuell gestaltete Zimmer in einem Gebäude aus dem 15. Jahrhundert.', + address: 'Obermarkt 8-12, 78462 Konstanz', + latitude: 47.6621, + longitude: 9.1746, + timeline: [{ year: '1419', event: 'Erstmalige urkundliche Erwähnung' }], + }, + { + name: 'Hotel Viva Sky', + slug: 'hotel-viva-sky', + category: 'hotel', + description: + 'Modernes Hotel nahe der Altstadt mit Rooftop-Bar und Blick über die Dächer von Konstanz bis zum Bodensee.', + address: 'Sigismundstraße 19, 78462 Konstanz', + latitude: 47.6597, + longitude: 9.173, + }, + + // === EVENT VENUES === + { + name: 'Konzil Konstanz', + slug: 'konzil-konstanz', + category: 'event_venue', + description: + 'Historisches Konzilgebäude am Hafen, in dem 1417 das Konklave zur Papstwahl stattfand. Heute Veranstaltungshalle und Restaurant.', + address: 'Hafenstraße 2, 78462 Konstanz', + latitude: 47.6596, + longitude: 9.178, + timeline: [ + { year: '1388', event: 'Erbaut als Kaufhaus' }, + { year: '1414-1418', event: 'Tagungsort des Konzils' }, + ], + }, + { + name: 'Stadttheater Konstanz', + slug: 'stadttheater-konstanz', + category: 'event_venue', + description: + 'Das Theater Konstanz ist eines der ältesten aktiven Theater Deutschlands. Schauspiel, Musiktheater und Junges Theater auf mehreren Bühnen.', + address: 'Konzilstraße 11, 78462 Konstanz', + latitude: 47.6593, + longitude: 9.177, + }, + { + name: 'Bodenseeforum', + slug: 'bodenseeforum', + category: 'event_venue', + description: + 'Modernes Kongress- und Veranstaltungszentrum direkt am Seerhein. Konferenzen, Messen, Konzerte und kulturelle Events.', + address: 'Reichenaustraße 21, 78467 Konstanz', + latitude: 47.6652, + longitude: 9.172, + }, + { + name: 'Spiegelhalle', + slug: 'spiegelhalle', + category: 'event_venue', + description: + 'Spielstätte des Stadttheaters für experimentelles Theater, Lesungen und Kleinkunst. Intimere Atmosphäre als das Haupthaus.', + address: 'Sigismundstraße 11, 78462 Konstanz', + latitude: 47.66, + longitude: 9.1735, + }, + { + name: 'Kulturzentrum am Münster', + slug: 'kulturzentrum-am-muenster', + category: 'event_venue', + description: + 'Kulturelles Veranstaltungszentrum neben dem Münster mit wechselnden Ausstellungen, Vorträgen und Kulturprogramm.', + address: 'Wessenbergstraße 43, 78462 Konstanz', + latitude: 47.661, + longitude: 9.1755, + }, + + // === VIEWPOINTS === + { + name: 'Münsterturm-Aussichtsplattform', + slug: 'muensterturm-aussicht', + category: 'viewpoint', + description: + 'Nach 193 Stufen erreicht man die Aussichtsplattform des Münsterturms mit 360°-Panorama über Konstanz, den Bodensee und bei klarer Sicht bis zu den Alpen.', + address: 'Münsterplatz 1, 78462 Konstanz', + latitude: 47.6603, + longitude: 9.1757, + }, + { + name: 'Bismarckturm', + slug: 'bismarckturm', + category: 'viewpoint', + description: + 'Historischer Aussichtsturm auf einer Anhöhe im Konstanzer Stadtteil Litzelstetten. Weiter Blick über den Überlinger See und die Insel Mainau.', + address: 'Bismarckturm, 78465 Konstanz-Litzelstetten', + latitude: 47.693, + longitude: 9.2052, + timeline: [{ year: '1914', event: 'Einweihung des Turms' }], + }, + { + name: 'Seerheinsteg', + slug: 'seerheinsteg', + category: 'viewpoint', + description: + 'Fußgängerbrücke über den Seerhein mit freiem Blick auf die Altstadt, das Münster und den Rheinabfluss aus dem Bodensee.', + address: 'Seerheinsteg, 78462 Konstanz', + latitude: 47.6638, + longitude: 9.1748, + }, + { + name: 'Lorettowald Aussichtspunkt', + slug: 'lorettowald-aussichtspunkt', + category: 'viewpoint', + description: + 'Aussichtspunkt im Lorettowald über den Baumkronen. Blick auf den westlichen Bodensee, die Schweizer Alpen und die Altstadt.', + address: 'Lorettostraße, 78464 Konstanz', + latitude: 47.6518, + longitude: 9.1755, + }, + { + name: 'Hörnle-Spitze', + slug: 'hoernle-spitze', + category: 'viewpoint', + description: + 'Äußerste Spitze der Halbinsel Horn mit unverbautem 180°-Panorama über den Bodensee. Besonders beeindruckend bei Sonnenuntergang.', + address: 'Hörnleweg, 78464 Konstanz', + latitude: 47.648, + longitude: 9.2085, + }, ]); - console.log('Seeded 6 locations.'); + console.log('Seeded 41 locations.'); await connection.end(); } diff --git a/apps/citycorners/apps/backend/src/location/location-lookup.service.ts b/apps/citycorners/apps/backend/src/location/location-lookup.service.ts index 74f459c3a..be589a9a4 100644 --- a/apps/citycorners/apps/backend/src/location/location-lookup.service.ts +++ b/apps/citycorners/apps/backend/src/location/location-lookup.service.ts @@ -122,24 +122,36 @@ export class LocationLookupService { private guessCategory(query: string, text: string): string { const lowerQuery = query.toLowerCase(); const lowerText = text.toLowerCase(); + const combined = lowerQuery + ' ' + lowerText.substring(0, 500); - if ( - /restaurant|essen|küche|dining|speise|bistro|gasth/i.test( - lowerQuery + ' ' + lowerText.substring(0, 500) - ) - ) { + if (/café|cafe|kaffee|coffee|konditorei|bäckerei|bakery/i.test(combined)) { + return 'cafe'; + } + if (/\bbar\b|kneipe|pub|cocktail|lounge|nachtleben|nightlife/i.test(combined)) { + return 'bar'; + } + if (/restaurant|essen|küche|dining|speise|bistro|gasth/i.test(combined)) { return 'restaurant'; } - if ( - /museum|ausstellung|galerie|sammlung/i.test(lowerQuery + ' ' + lowerText.substring(0, 500)) - ) { + if (/\bhotel\b|pension|gasthof|unterkunft|übernacht|hostel/i.test(combined)) { + return 'hotel'; + } + if (/strandbad|strand|freibad|beach|badestelle|schwimmbad/i.test(combined)) { + return 'beach'; + } + if (/\bpark\b|grünanlage|garten|wald|naturschutz/i.test(combined)) { + return 'park'; + } + if (/aussichtspunkt|viewpoint|panorama|aussicht|turm.*blick/i.test(combined)) { + return 'viewpoint'; + } + if (/konzert|theater|bühne|veranstaltung|event|halle|forum|kulturzentrum/i.test(combined)) { + return 'event_venue'; + } + if (/museum|ausstellung|galerie|sammlung/i.test(combined)) { return 'museum'; } - if ( - /laden|shop|geschäft|boutique|markt|einkauf|shopping/i.test( - lowerQuery + ' ' + lowerText.substring(0, 500) - ) - ) { + if (/laden|shop|geschäft|boutique|markt|einkauf|shopping/i.test(combined)) { return 'shop'; } return 'sight'; diff --git a/apps/citycorners/apps/backend/src/location/location.controller.ts b/apps/citycorners/apps/backend/src/location/location.controller.ts index 811f8dd10..946afcfff 100644 --- a/apps/citycorners/apps/backend/src/location/location.controller.ts +++ b/apps/citycorners/apps/backend/src/location/location.controller.ts @@ -14,7 +14,18 @@ class CreateLocationDto { @IsString() @IsNotEmpty() - category!: 'sight' | 'restaurant' | 'shop' | 'museum'; + category!: + | 'sight' + | 'restaurant' + | 'shop' + | 'museum' + | 'cafe' + | 'bar' + | 'park' + | 'beach' + | 'hotel' + | 'event_venue' + | 'viewpoint'; @IsString() @IsNotEmpty() @@ -58,7 +69,18 @@ class UpdateLocationDto { @IsString() @IsOptional() - category?: 'sight' | 'restaurant' | 'shop' | 'museum'; + category?: + | 'sight' + | 'restaurant' + | 'shop' + | 'museum' + | 'cafe' + | 'bar' + | 'park' + | 'beach' + | 'hotel' + | 'event_venue' + | 'viewpoint'; @IsString() @IsOptional() diff --git a/apps/citycorners/apps/landing/src/components/Filter.astro b/apps/citycorners/apps/landing/src/components/Filter.astro index 4dc560088..f0af4e6b8 100644 --- a/apps/citycorners/apps/landing/src/components/Filter.astro +++ b/apps/citycorners/apps/landing/src/components/Filter.astro @@ -5,6 +5,13 @@ const categories = [ { value: 'restaurant', label: 'Restaurants' }, { value: 'laden', label: 'Läden' }, { value: 'museum', label: 'Museen' }, + { value: 'café', label: 'Cafés' }, + { value: 'bar', label: 'Bars' }, + { value: 'park', label: 'Parks' }, + { value: 'strandbad', label: 'Strandbäder' }, + { value: 'hotel', label: 'Hotels' }, + { value: 'veranstaltungsort', label: 'Veranstaltungsorte' }, + { value: 'aussichtspunkt', label: 'Aussichtspunkte' }, ]; --- diff --git a/apps/citycorners/apps/landing/src/components/LocationCard.astro b/apps/citycorners/apps/landing/src/components/LocationCard.astro index 3e21313d0..6aea041a2 100644 --- a/apps/citycorners/apps/landing/src/components/LocationCard.astro +++ b/apps/citycorners/apps/landing/src/components/LocationCard.astro @@ -16,6 +16,13 @@ const categoryColors: Record = { Restaurant: 'bg-red-100 text-red-700', Laden: 'bg-green-100 text-green-700', Museum: 'bg-purple-100 text-purple-700', + Café: 'bg-amber-100 text-amber-700', + Bar: 'bg-orange-100 text-orange-700', + Park: 'bg-emerald-100 text-emerald-700', + Strandbad: 'bg-cyan-100 text-cyan-700', + Hotel: 'bg-indigo-100 text-indigo-700', + Veranstaltungsort: 'bg-pink-100 text-pink-700', + Aussichtspunkt: 'bg-sky-100 text-sky-700', }; --- diff --git a/apps/citycorners/apps/landing/src/data/locations.json b/apps/citycorners/apps/landing/src/data/locations.json index f75a9167d..79a439750 100644 --- a/apps/citycorners/apps/landing/src/data/locations.json +++ b/apps/citycorners/apps/landing/src/data/locations.json @@ -89,5 +89,173 @@ "lat": 47.665, "lng": 9.171 } + }, + { + "id": 7, + "name": "Café Zeitlos", + "category": "Café", + "description": "Gemütliches Café in der Konstanzer Altstadt mit hausgemachten Kuchen, Frühstück und einer großen Auswahl an Kaffeespezialitäten.", + "image": "/images/placeholder.jpg", + "address": "Hussenstraße 13, 78462 Konstanz", + "coordinates": { + "lat": 47.6609, + "lng": 9.1749 + } + }, + { + "id": 8, + "name": "Voglhaus Café", + "category": "Café", + "description": "Beliebtes Bio-Café mit vegetarischer und veganer Küche. Kreative Frühstücksgerichte und selbstgemachte Limonaden.", + "image": "/images/placeholder.jpg", + "address": "Wessenbergstraße 8, 78462 Konstanz", + "coordinates": { + "lat": 47.6619, + "lng": 9.1744 + } + }, + { + "id": 9, + "name": "Seekuh", + "category": "Bar", + "description": "Legendäre Konstanzer Bar und Kulturkneipe am Seerhein. Craft Beer, Cocktails und regelmäßig Konzerte auf kleiner Bühne.", + "image": "/images/placeholder.jpg", + "address": "Konradigasse 1, 78462 Konstanz", + "coordinates": { + "lat": 47.6632, + "lng": 9.1773 + } + }, + { + "id": 10, + "name": "Brauhaus Johann Albrecht", + "category": "Bar", + "description": "Brauhaus-Restaurant mit hauseigenem Bier direkt am Seerhein. Deftige Küche und frisch gebrautes Bier in historischem Ambiente.", + "image": "/images/placeholder.jpg", + "address": "Konradigasse 2, 78462 Konstanz", + "coordinates": { + "lat": 47.663, + "lng": 9.177 + } + }, + { + "id": 11, + "name": "Stadtgarten Konstanz", + "category": "Park", + "description": "Großer Park direkt am Bodenseeufer mit altem Baumbestand, Spielplätzen, Minigolf und Biergarten. Der beliebteste Erholungsort der Stadt.", + "image": "/images/placeholder.jpg", + "address": "Seestraße, 78464 Konstanz", + "coordinates": { + "lat": 47.6582, + "lng": 9.1812 + } + }, + { + "id": 12, + "name": "Lorettowald", + "category": "Park", + "description": "Bewaldeter Hügel im Süden von Konstanz mit Wanderwegen und Aussichtspunkten über den Bodensee. Beliebt bei Joggern und Spaziergängern.", + "image": "/images/placeholder.jpg", + "address": "Lorettostraße, 78464 Konstanz", + "coordinates": { + "lat": 47.6524, + "lng": 9.1768 + } + }, + { + "id": 13, + "name": "Strandbad Horn", + "category": "Strandbad", + "description": "Eines der größten Freibäder am Bodensee mit großer Liegewiese, Sandstrand, Sprungturm und Beachvolleyball. Traumhafter Seeblick.", + "image": "/images/placeholder.jpg", + "address": "Eichhornstraße 100, 78464 Konstanz", + "coordinates": { + "lat": 47.6527, + "lng": 9.201 + } + }, + { + "id": 14, + "name": "Schmugglerbucht", + "category": "Strandbad", + "description": "Kleine, versteckte Badestelle unterhalb der Seestraße. Bei Einheimischen beliebt als Geheimtipp zum Schwimmen im Bodensee.", + "image": "/images/placeholder.jpg", + "address": "Seestraße, 78464 Konstanz", + "coordinates": { + "lat": 47.6561, + "lng": 9.186 + } + }, + { + "id": 15, + "name": "Steigenberger Inselhotel", + "category": "Hotel", + "description": "Luxushotel in einem ehemaligen Dominikanerkloster auf einer Insel im Bodensee. Eines der historischsten Hotels Deutschlands.", + "image": "/images/placeholder.jpg", + "address": "Auf der Insel 1, 78462 Konstanz", + "coordinates": { + "lat": 47.6598, + "lng": 9.181 + } + }, + { + "id": 16, + "name": "Hotel Barbarossa", + "category": "Hotel", + "description": "Historisches Boutique-Hotel am Obermarkt mitten in der Altstadt. Individuell gestaltete Zimmer in einem Gebäude aus dem 15. Jahrhundert.", + "image": "/images/placeholder.jpg", + "address": "Obermarkt 8-12, 78462 Konstanz", + "coordinates": { + "lat": 47.6621, + "lng": 9.1746 + } + }, + { + "id": 17, + "name": "Konzil Konstanz", + "category": "Veranstaltungsort", + "description": "Historisches Konzilgebäude am Hafen, in dem 1417 das Konklave zur Papstwahl stattfand. Heute Veranstaltungshalle und Restaurant.", + "image": "/images/placeholder.jpg", + "address": "Hafenstraße 2, 78462 Konstanz", + "coordinates": { + "lat": 47.6596, + "lng": 9.178 + } + }, + { + "id": 18, + "name": "Stadttheater Konstanz", + "category": "Veranstaltungsort", + "description": "Das Theater Konstanz ist eines der ältesten aktiven Theater Deutschlands. Schauspiel, Musiktheater und Junges Theater auf mehreren Bühnen.", + "image": "/images/placeholder.jpg", + "address": "Konzilstraße 11, 78462 Konstanz", + "coordinates": { + "lat": 47.6593, + "lng": 9.177 + } + }, + { + "id": 19, + "name": "Münsterturm-Aussichtsplattform", + "category": "Aussichtspunkt", + "description": "Nach 193 Stufen erreicht man die Aussichtsplattform des Münsterturms mit 360°-Panorama über Konstanz, den Bodensee und bei klarer Sicht bis zu den Alpen.", + "image": "/images/placeholder.jpg", + "address": "Münsterplatz 1, 78462 Konstanz", + "coordinates": { + "lat": 47.6603, + "lng": 9.1757 + } + }, + { + "id": 20, + "name": "Hörnle-Spitze", + "category": "Aussichtspunkt", + "description": "Äußerste Spitze der Halbinsel Horn mit unverbautem 180°-Panorama über den Bodensee. Besonders beeindruckend bei Sonnenuntergang.", + "image": "/images/placeholder.jpg", + "address": "Hörnleweg, 78464 Konstanz", + "coordinates": { + "lat": 47.648, + "lng": 9.2085 + } } ] diff --git a/apps/citycorners/apps/web/src/lib/i18n/locales/de.json b/apps/citycorners/apps/web/src/lib/i18n/locales/de.json index 49968502e..1272ab55c 100644 --- a/apps/citycorners/apps/web/src/lib/i18n/locales/de.json +++ b/apps/citycorners/apps/web/src/lib/i18n/locales/de.json @@ -26,13 +26,27 @@ "sight": "Sehenswürdigkeiten", "restaurant": "Restaurants", "shop": "Läden", - "museum": "Museen" + "museum": "Museen", + "cafe": "Cafés", + "bar": "Bars", + "park": "Parks", + "beach": "Strandbäder", + "hotel": "Hotels", + "event_venue": "Veranstaltungsorte", + "viewpoint": "Aussichtspunkte" }, "category": { "sight": "Sehenswürdigkeit", "restaurant": "Restaurant", "shop": "Laden", - "museum": "Museum" + "museum": "Museum", + "cafe": "Café", + "bar": "Bar", + "park": "Park", + "beach": "Strandbad", + "hotel": "Hotel", + "event_venue": "Veranstaltungsort", + "viewpoint": "Aussichtspunkt" }, "detail": { "history": "Geschichte", diff --git a/apps/citycorners/apps/web/src/lib/i18n/locales/en.json b/apps/citycorners/apps/web/src/lib/i18n/locales/en.json index fd30ddb2d..f53839532 100644 --- a/apps/citycorners/apps/web/src/lib/i18n/locales/en.json +++ b/apps/citycorners/apps/web/src/lib/i18n/locales/en.json @@ -26,13 +26,27 @@ "sight": "Sights", "restaurant": "Restaurants", "shop": "Shops", - "museum": "Museums" + "museum": "Museums", + "cafe": "Cafés", + "bar": "Bars", + "park": "Parks", + "beach": "Beaches", + "hotel": "Hotels", + "event_venue": "Event Venues", + "viewpoint": "Viewpoints" }, "category": { "sight": "Sight", "restaurant": "Restaurant", "shop": "Shop", - "museum": "Museum" + "museum": "Museum", + "cafe": "Café", + "bar": "Bar", + "park": "Park", + "beach": "Beach", + "hotel": "Hotel", + "event_venue": "Event Venue", + "viewpoint": "Viewpoint" }, "detail": { "history": "History", diff --git a/apps/citycorners/apps/web/src/routes/(app)/+page.svelte b/apps/citycorners/apps/web/src/routes/(app)/+page.svelte index db37c3b2e..941053dc8 100644 --- a/apps/citycorners/apps/web/src/routes/(app)/+page.svelte +++ b/apps/citycorners/apps/web/src/routes/(app)/+page.svelte @@ -31,7 +31,19 @@ let loadingMore = $state(false); let selectedCategory = $state(null); - const categoryKeys = ['sight', 'restaurant', 'shop', 'museum']; + const categoryKeys = [ + 'sight', + 'restaurant', + 'shop', + 'museum', + 'cafe', + 'bar', + 'park', + 'beach', + 'hotel', + 'event_venue', + 'viewpoint', + ]; let categoryCounts = $derived( categoryKeys.reduce( @@ -161,7 +173,21 @@ ? '🛍️' : selectedCategory === 'sight' ? '🏰' - : '📍'}

{#if selectedCategory} diff --git a/apps/citycorners/apps/web/src/routes/(app)/map/+page.svelte b/apps/citycorners/apps/web/src/routes/(app)/map/+page.svelte index 3dd130a56..792392dde 100644 --- a/apps/citycorners/apps/web/src/routes/(app)/map/+page.svelte +++ b/apps/citycorners/apps/web/src/routes/(app)/map/+page.svelte @@ -27,6 +27,13 @@ restaurant: '#dc2626', shop: '#16a34a', museum: '#9333ea', + cafe: '#b45309', + bar: '#ea580c', + park: '#15803d', + beach: '#0891b2', + hotel: '#4f46e5', + event_venue: '#db2777', + viewpoint: '#0ea5e9', }; onMount(async () => {