diff --git a/api-client/src/endpoints/createShelterContactEndpoint.ts b/api-client/src/endpoints/createShelterContactEndpoint.ts deleted file mode 100644 index 178bf61256..0000000000 --- a/api-client/src/endpoints/createShelterContactEndpoint.ts +++ /dev/null @@ -1,16 +0,0 @@ -import Endpoint from '../Endpoint' -import EndpointBuilder from '../EndpointBuilder' - -const SHELTER_CONTACT_URL = 'wohnraum.tuerantuer.org/wp-json/accommodations/contact' - -export const SHELTER_CONTACT_ENDPOINT_NAME = 'shelter-contact' -type Params = { id: number; cityCode: string; email?: string; phone?: string } - -export type Status = 'success' | 'invalid_contact_data' | 'invalid_accommodation' - -export default (): Endpoint => - new EndpointBuilder(SHELTER_CONTACT_ENDPOINT_NAME) - .withParamsToUrlMapper(params => `https://${params.cityCode}.${SHELTER_CONTACT_URL}`) - .withParamsToBodyMapper(({ id, email, phone }: Params): string => JSON.stringify({ id, email, phone })) - .withMapper((json: { status: Status }): Status => json.status) - .build() diff --git a/api-client/src/endpoints/createShelterEndpoint.ts b/api-client/src/endpoints/createShelterEndpoint.ts deleted file mode 100644 index 9b6193bfcb..0000000000 --- a/api-client/src/endpoints/createShelterEndpoint.ts +++ /dev/null @@ -1,70 +0,0 @@ -import Endpoint from '../Endpoint' -import EndpointBuilder from '../EndpointBuilder' -import ShelterModel from '../models/ShelterModel' -import { JsonShelterType } from '../types' - -const SHELTER_URL = 'wohnraum.tuerantuer.org/wp-json/accommodations' - -export const SHELTER_ENDPOINT_NAME = 'shelter' -type Params = - | { type: 'detail'; id: string; cityCode: string } - | { type: 'list'; page: number; cityCode: string; filter: FilterProps } - -export type FilterProps = { - beds: string | null - city: string | null - pets: string | null -} - -// Map for the filter keys for the endpoint -const paramMap = new Map([ - ['beds', 'min_beds'], - ['city', 'city'], - ['pets', 'pets'], -]) - -// add a key and value as a string for each param -const getFilterQueryParams = (params: FilterProps): string => - Object.keys(params) - .map((key: string) => { - if (params[key as keyof FilterProps]) { - return `&${paramMap.get(key)}=${params[key as keyof FilterProps]}` - } - return '' - }) - .join('') - -export default (): Endpoint => - new EndpointBuilder(SHELTER_ENDPOINT_NAME) - .withParamsToUrlMapper(params => { - const baseUrl = `https://${params.cityCode}.${SHELTER_URL}` - if (params.type === 'list') { - return `${baseUrl}/list?page=${params.page}${getFilterQueryParams(params.filter)}` - } - return `${baseUrl}/${params.id}` - }) - .withMapper((json: JsonShelterType[]): ShelterModel[] => - json.map( - it => - new ShelterModel({ - id: it.id, - name: it.name, - city: it.city, - zipcode: it.zipcode, - languages: it.languages, - beds: it.beds, - accommodationType: it.accommodation_type, - info: it.info, - email: it.email, - phone: it.phone, - rooms: it.rooms, - occupants: it.occupants, - startDate: it.start_date, - period: it.period, - hostType: it.host_type, - costs: it.costs, - comments: it.comments, - }), - ), - ) - .build() diff --git a/api-client/src/index.ts b/api-client/src/index.ts index af13969f12..b42053051c 100644 --- a/api-client/src/index.ts +++ b/api-client/src/index.ts @@ -6,12 +6,8 @@ import { ParamsType as ImportedFeedbackParamsType, AdditionalParamsType as ImportedFeedbackAdditionalParamsType, } from './endpoints/createFeedbackEndpoint' -import { Status as ImportedShelterContactStatus } from './endpoints/createShelterContactEndpoint' -import { FilterProps as ImportedShelterFilterProps } from './endpoints/createShelterEndpoint' import { Return as ImportedReturnType } from './endpoints/hooks/useLoadAsync' -export type ShelterContactStatus = ImportedShelterContactStatus -export type ShelterFilterProps = ImportedShelterFilterProps export type MapParamsToBodyType

= ImportedMapParamsToBodyType

export type MapParamsToUrlType

= ImportedMapParamsToUrlType

export type MapResponseType = ImportedMapResponseType @@ -51,11 +47,6 @@ export { default as createCategoryParentsEndpoint, CATEGORY_PARENTS_ENDPOINT_NAME, } from './endpoints/createCategoryParentsEndpoint' -export { default as createShelterEndpoint, SHELTER_ENDPOINT_NAME } from './endpoints/createShelterEndpoint' -export { - default as createShelterContactEndpoint, - SHELTER_CONTACT_ENDPOINT_NAME, -} from './endpoints/createShelterContactEndpoint' export { default as createCitiesEndpoint, CITIES_ENDPOINT_NAME } from './endpoints/createCitiesEndpoint' export { default as createCityEndpoint, CITY_ENDPOINT_NAME } from './endpoints/createCityEndpoint' export { default as createDisclaimerEndpoint, DISCLAIMER_ENDPOINT_NAME } from './endpoints/createDisclaimerEndpoint' @@ -114,7 +105,6 @@ export { default as ExtendedPageModel } from './models/ExtendedPageModel' export { default as PoiModel } from './models/PoiModel' export { default as PoiCategoryModel } from './models/PoiCategoryModel' export { default as SprungbrettJobModel } from './models/SprungbrettJobModel' -export { default as ShelterModel } from './models/ShelterModel' export { default as OpeningHoursModel } from './models/OpeningHoursModel' export { default as OrganizationModel } from './models/OrganizationModel' export { default as normalizePath } from './normalizePath' diff --git a/api-client/src/models/ShelterModel.ts b/api-client/src/models/ShelterModel.ts deleted file mode 100644 index cc2fee13c1..0000000000 --- a/api-client/src/models/ShelterModel.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { - ShelterAccommodationType, - ShelterCostsType, - ShelterHostType, - ShelterInfo, - ShelterLanguage, - ShelterPeriod, -} from '../types' - -class ShelterModel { - _id: number - _name: string - _city: string - _zipcode: string - _languages: ShelterLanguage[] - _beds: number - _accommodationType: ShelterAccommodationType - _info: ShelterInfo[] - _email: string | null - _phone: string | null - _rooms: number | null - _occupants: number | null - _startDate: string - _period: ShelterPeriod - _hostType: ShelterHostType - _costs: ShelterCostsType - _comments: string | null - - constructor(params: { - id: number - name: string - city: string - zipcode: string - languages: ShelterLanguage[] - beds: string - accommodationType: ShelterAccommodationType - info: ShelterInfo[] - email: string | null - phone: string | null - rooms: string | null - occupants: string | null - startDate: string - period: ShelterPeriod - hostType: ShelterHostType - costs: ShelterCostsType - comments: string | null - }) { - this._id = params.id - this._name = params.name.trim() - this._city = params.city.trim() - this._zipcode = params.zipcode.trim() - this._languages = params.languages - this._beds = parseInt(params.beds, 10) - this._accommodationType = params.accommodationType - this._info = params.info - this._email = params.email?.trim() ?? null - this._phone = params.phone?.trim() ?? null - this._rooms = params.rooms ? parseInt(params.rooms, 10) : null - this._occupants = params.occupants ? parseInt(params.occupants, 10) : null - this._startDate = params.startDate - this._period = params.period - this._hostType = params.hostType - this._costs = params.costs - this._comments = params.comments?.trim() ?? null - } - - get id(): number { - return this._id - } - - get name(): string { - return this._name - } - - get city(): string { - return this._city - } - - get zipcode(): string { - return this._zipcode - } - - get languages(): ShelterLanguage[] { - return this._languages - } - - get beds(): number { - return this._beds - } - - get accommodationType(): ShelterAccommodationType { - return this._accommodationType - } - - get info(): ShelterInfo[] { - return this._info - } - - get email(): string | null { - return this._email - } - - get phone(): string | null { - return this._phone - } - - get rooms(): number | null { - return this._rooms - } - - get occupants(): number | null { - return this._occupants - } - - get startDate(): string { - return this._startDate - } - - get period(): ShelterPeriod { - return this._period - } - - get hostType(): ShelterHostType { - return this._hostType - } - - get costs(): ShelterCostsType { - return this._costs - } - - get comments(): string | null { - return this._comments - } -} - -export default ShelterModel diff --git a/api-client/src/routes/InternalPathnameParser.ts b/api-client/src/routes/InternalPathnameParser.ts index b070d6b837..6fc520e72b 100644 --- a/api-client/src/routes/InternalPathnameParser.ts +++ b/api-client/src/routes/InternalPathnameParser.ts @@ -11,7 +11,6 @@ import { OFFERS_ROUTE, POIS_ROUTE, SEARCH_ROUTE, - SHELTER_ROUTE, SPRUNGBRETT_OFFER_ROUTE, TU_NEWS_TYPE, TuNewsType, @@ -190,13 +189,6 @@ class InternalPathnameParser { ...params, } } - if (route === SHELTER_ROUTE) { - return { - route: SHELTER_ROUTE, - ...params, - id: this._parts[ENTITY_ID_INDEX + 1], - } - } } return null diff --git a/api-client/src/routes/RouteInformationTypes.ts b/api-client/src/routes/RouteInformationTypes.ts index 352eacdd40..a9887018a3 100644 --- a/api-client/src/routes/RouteInformationTypes.ts +++ b/api-client/src/routes/RouteInformationTypes.ts @@ -11,7 +11,6 @@ import { OffersRouteType, PoisRouteType, SearchRouteType, - ShelterRouteType, SprungbrettOfferRouteType, TuNewsType, } from '.' @@ -57,11 +56,6 @@ export type SimpleCityContentFeatureType = ParamsType & { route: DisclaimerRouteType | OffersRouteType | SprungbrettOfferRouteType } -export type IdCityContentFeatureType = ParamsType & { - route: ShelterRouteType - id?: string -} - export type EventsRouteInformationType = ParamsType & { // Routes with customizable ids, e.g. '/augsburg/de/events/1234/' route: EventsRouteType @@ -90,7 +84,6 @@ export type NonNullableRouteInformationType = | SimpleCityContentFeatureType | EventsRouteInformationType | PoisRouteInformationType - | IdCityContentFeatureType | LicensesInformationType | SearchRouteInformationType diff --git a/api-client/src/routes/index.ts b/api-client/src/routes/index.ts index c562383b83..1e4b8b3f19 100644 --- a/api-client/src/routes/index.ts +++ b/api-client/src/routes/index.ts @@ -26,9 +26,6 @@ export const OFFERS_ROUTE: OffersRouteType = 'offers' export type SprungbrettOfferRouteType = 'sprungbrett' export const SPRUNGBRETT_OFFER_ROUTE: SprungbrettOfferRouteType = 'sprungbrett' -export type ShelterRouteType = 'wohnraum' -export const SHELTER_ROUTE: ShelterRouteType = 'wohnraum' - export type SearchRouteType = 'search' export const SEARCH_ROUTE: SearchRouteType = 'search' diff --git a/api-client/src/routes/pathname.ts b/api-client/src/routes/pathname.ts index 06942aa9ff..f08245bb62 100644 --- a/api-client/src/routes/pathname.ts +++ b/api-client/src/routes/pathname.ts @@ -10,7 +10,6 @@ import { OFFERS_ROUTE, POIS_ROUTE, SEARCH_ROUTE, - SHELTER_ROUTE, SPRUNGBRETT_OFFER_ROUTE, } from '.' import { NonNullableRouteInformationType } from '..' @@ -47,11 +46,6 @@ export const pathnameFromRouteInformation = (routeInformation: NonNullableRouteI // https://integreat.app/augsburg/de/offers/sprungbrett return constructPathname([cityCode, languageCode, OFFERS_ROUTE, route]) } - if (routeInformation.route === SHELTER_ROUTE) { - const { cityCode, languageCode, route, id } = routeInformation - // https://integreat.app/augsburg/de/offers/wohnraum/1234, https://integreat.app/augsburg/de/offers/wohnraum - return constructPathname([cityCode, languageCode, OFFERS_ROUTE, route, id]) - } if (routeInformation.route === CATEGORIES_ROUTE) { // https://integreat.app/augsburg/de/, https://integreat.app/augsburg/de/willkommen/erste-schritte return constructPathname([routeInformation.cityContentPath]) diff --git a/api-client/src/types.ts b/api-client/src/types.ts index e000451548..c14b35a256 100644 --- a/api-client/src/types.ts +++ b/api-client/src/types.ts @@ -130,39 +130,6 @@ export type JsonOfferType = { post: JsonOfferPostType | null | undefined } -export type ShelterLanguage = 'deutsch' | 'englisch' | 'ukrainisch' | 'russisch' | 'polnisch' | 'kroatisch' -export type ShelterAccommodationType = 'ges_unterkunft' | 'privatzimmer' | 'gemein_zimmer' -export type ShelterInfo = - | 'barrierefrei' - | 'lgbtiq' - | 'bad' - | 'haustier-katze' - | 'haustier-hund' - | 'haustier' - | 'rauchen' -export type ShelterPeriod = '7t' | '14t' | '1m' | '3m' | '6m' | '12m' | '12m_plus' -export type ShelterHostType = 'allein_maennlich' | 'allein_weiblich' | 'familie_kinder' | 'paar' | 'wg' | null -export type ShelterCostsType = 'uebergang-miete' | 'kostenpflichtig' | 'kostenfrei' -export type JsonShelterType = { - id: number - name: string - city: string - street: string | null - zipcode: string - languages: ShelterLanguage[] - beds: string - accommodation_type: ShelterAccommodationType - info: ShelterInfo[] - email: string | null - phone: string | null - rooms: string | null - occupants: string | null - start_date: string - period: ShelterPeriod - host_type: ShelterHostType - costs: ShelterCostsType - comments: string | null -} export type JsonSprungbrettJobType = { title: string zip: string diff --git a/native/src/hooks/useNavigate.ts b/native/src/hooks/useNavigate.ts index 197bb752c4..42f46e560f 100644 --- a/native/src/hooks/useNavigate.ts +++ b/native/src/hooks/useNavigate.ts @@ -15,7 +15,6 @@ import { POIS_ROUTE, RouteInformationType, SEARCH_ROUTE, - SHELTER_ROUTE, SPRUNGBRETT_OFFER_ROUTE, } from 'api-client' @@ -39,15 +38,13 @@ const navigate = ( return } const url = urlFromRouteInformation(routeInformation) - if (routeInformation.route !== SHELTER_ROUTE) { - sendTrackingSignal({ - signal: { - name: OPEN_PAGE_SIGNAL_NAME, - pageType: routeInformation.route, - url, - }, - }) - } + sendTrackingSignal({ + signal: { + name: OPEN_PAGE_SIGNAL_NAME, + pageType: routeInformation.route, + url, + }, + }) if (routeInformation.route === LICENSES_ROUTE) { navigation.push(LICENSES_ROUTE) @@ -125,11 +122,6 @@ const navigate = ( case SEARCH_ROUTE: navigation.push(SEARCH_ROUTE, { searchText: routeInformation.searchText }) - return - - // Not implemented in native apps, should be opened in InAppBrowser - case SHELTER_ROUTE: - openExternalUrl(url, showSnackbar) } } diff --git a/native/src/routes/Offers.tsx b/native/src/routes/Offers.tsx index db984fc4dc..3bb840a8a7 100644 --- a/native/src/routes/Offers.tsx +++ b/native/src/routes/Offers.tsx @@ -2,28 +2,24 @@ import React, { ReactElement } from 'react' import { useTranslation } from 'react-i18next' import { View } from 'react-native' -import { OfferModel, SHELTER_ROUTE, SPRUNGBRETT_OFFER_ROUTE } from 'api-client' +import { OfferModel, SPRUNGBRETT_OFFER_ROUTE } from 'api-client' import Tiles from '../components/Tiles' import TileModel from '../models/TileModel' -import urlFromRouteInformation from '../navigation/url' type OffersProps = { offers: Array navigateToOffer: (tile: TileModel) => void languageCode: string - cityCode: string } -const Offers = ({ offers, navigateToOffer, languageCode, cityCode }: OffersProps): ReactElement => { +const Offers = ({ offers, navigateToOffer, languageCode }: OffersProps): ReactElement => { const { t } = useTranslation('offers') const tiles = offers.map(offer => { let path = offer.path if (offer.alias === SPRUNGBRETT_OFFER_ROUTE) { path = offer.alias - } else if (offer.alias === SHELTER_ROUTE) { - path = urlFromRouteInformation({ route: SHELTER_ROUTE, cityCode, languageCode }) } return new TileModel({ title: t(offer.title), diff --git a/native/src/routes/OffersContainer.tsx b/native/src/routes/OffersContainer.tsx index 4764bbaa3e..992ac629f0 100644 --- a/native/src/routes/OffersContainer.tsx +++ b/native/src/routes/OffersContainer.tsx @@ -59,7 +59,7 @@ const OffersContainer = ({ navigation, route }: OffersContainerProps): ReactElem return ( {data?.city.offersEnabled && ( - + )} ) diff --git a/translations/translations.json b/translations/translations.json index 73e58d3c74..7c1c4c7e45 100644 --- a/translations/translations.json +++ b/translations/translations.json @@ -5494,173 +5494,139 @@ "offers": { "de": { "offers": "Angebote", - "pageTitle": "Angebote", - "wohnraum": "Wohnraum" + "pageTitle": "Angebote" }, "am": { "offers": "ግብዣዎች/ መጥሪያዎች", - "pageTitle": "ግብዣዎች/ መጥሪያዎች", - "wohnraum": "መኖሪያ ቤት" + "pageTitle": "ግብዣዎች/ መጥሪያዎች" }, "ar": { "offers": "العروض", - "pageTitle": "العروض", - "wohnraum": "غرفة المعيشة" + "pageTitle": "العروض" }, "bg": { "offers": "Оферти", - "pageTitle": "Оферти", - "wohnraum": "Жилище" + "pageTitle": "Оферти" }, "ckb": { "offers": "پێشنیارەکان", - "pageTitle": "پێشنیارەکان", - "wohnraum": "جەوی ژیان" + "pageTitle": "پێشنیارەکان" }, "cs": { "offers": "Nabídky", - "pageTitle": "Nabídky", - "wohnraum": "Obytný prostor" + "pageTitle": "Nabídky" }, "el": { "offers": "Προσφορές", - "pageTitle": "Προσφορές", - "wohnraum": "Κατοικία" + "pageTitle": "Προσφορές" }, "en": { "offers": "Offers", - "pageTitle": "Offers", - "wohnraum": "Housing" + "pageTitle": "Offers" }, "es": { "offers": "Ofertas", - "pageTitle": "Ofertas", - "wohnraum": "Vivienda" + "pageTitle": "Ofertas" }, "fi": { "offers": "Tarjoukset", - "pageTitle": "Tarjoukset", - "wohnraum": "Asuinalue" + "pageTitle": "Tarjoukset" }, "fr": { "offers": "Offres", - "pageTitle": "Offres", - "wohnraum": "Espace vital" + "pageTitle": "Offres" }, "hr": { "offers": "Ponude", - "pageTitle": "Ponude", - "wohnraum": "Stambeni prostor" + "pageTitle": "Ponude" }, "hu": { "offers": "Ajánlatok", - "pageTitle": "Ajánlatok", - "wohnraum": "Lakóterület" + "pageTitle": "Ajánlatok" }, "it": { "offers": "Offerte", - "pageTitle": "Offerte", - "wohnraum": "Vano" + "pageTitle": "Offerte" }, "ka": { "offers": "შეთავაზებები", - "pageTitle": "შეთავაზებები", - "wohnraum": "საცხოვრებელი ოთახი" + "pageTitle": "შეთავაზებები" }, "kmr": { "offers": "Xizmet", - "pageTitle": "Xizmet", - "wohnraum": "Atmosfera jiyanê" + "pageTitle": "Xizmet" }, "mk": { "offers": "Понуди", - "pageTitle": "Понуди", - "wohnraum": "Станбен простор" + "pageTitle": "Понуди" }, "nl": { "offers": "Aanbod", - "pageTitle": "Aanbod", - "wohnraum": "Huisvesting" + "pageTitle": "Aanbod" }, "pes": { "offers": "خدمات", - "pageTitle": "پیشنهادات", - "wohnraum": "مسکن" + "pageTitle": "پیشنهادات" }, "pl": { "offers": "Oferty", - "pageTitle": "Oferty", - "wohnraum": "Zakwaterowania" + "pageTitle": "Oferty" }, "prs": { "offers": "پیشنهادات", - "pageTitle": "پیشنهادات", - "wohnraum": "مسکن" + "pageTitle": "پیشنهادات" }, "ps": { "offers": "وړاندیزونه", - "pageTitle": "وړاندیزونه", - "wohnraum": "د اوسیدلو کوټہ" + "pageTitle": "وړاندیزونه" }, "pt": { "offers": "Ofertas", - "pageTitle": "Ofertas", - "wohnraum": "Habitaciones" + "pageTitle": "Ofertas" }, "ro": { "offers": "Oferte", - "pageTitle": "Oferte", - "wohnraum": "Spațiu de locuit" + "pageTitle": "Oferte" }, "ru": { "offers": "Предложения", - "pageTitle": "Предложения", - "wohnraum": "Жильё" + "pageTitle": "Предложения" }, "so": { "offers": "Heshiisyo", - "pageTitle": "Heshiisyo", - "wohnraum": "Qolka fadhiga" + "pageTitle": "Heshiisyo" }, "sq": { "offers": "Ofertat", - "pageTitle": "Ofertat", - "wohnraum": "Vendbanimi" + "pageTitle": "Ofertat" }, "sr-Cyrl": { "offers": "Понуде", - "pageTitle": "Понуде", - "wohnraum": "Стамбени простор" + "pageTitle": "Понуде" }, "sr-Latn": { "offers": "Ponude", - "pageTitle": "Ponude", - "wohnraum": "Stambeni prostor" + "pageTitle": "Ponude" }, "ti": { "offers": "ውዕላት", - "pageTitle": "ውዕላት", - "wohnraum": "መንበሪ ገዛ" + "pageTitle": "ውዕላት" }, "tr": { "offers": "Teklifler", - "pageTitle": "Teklifler", - "wohnraum": "Oturma odası" + "pageTitle": "Teklifler" }, "uk": { "offers": "Пропозиції", - "pageTitle": "Пропозиції", - "wohnraum": "Житло" + "pageTitle": "Пропозиції" }, "ur": { "offers": "پیش کشیں", - "pageTitle": "پیش کشیں", - "wohnraum": "رابطہ کی تفصیلات" + "pageTitle": "پیش کشیں" }, "zh-CN": { "offers": "提供项目", - "pageTitle": "提供项目", - "wohnraum": "居住空间" + "pageTitle": "提供项目" } }, "pois": { @@ -7594,707 +7560,6 @@ "decline": "拒绝" } }, - "shelter": { - "de": { - "title": "Wohnraum", - "shelterTitle": "{{beds}} in {{location}}", - "shelterInformation": "Angebotener Wohnraum", - "householdInformation": "Angaben zum gesamten Haushalt", - "hostInformation": "Angaben zum Anbietenden", - "contactInformation": "Kontaktdaten", - "shelterButton": "Anschauen", - "bed_one": "{{count}} Bett", - "bed_other": "{{count}} Betten", - "ges_unterkunft": "Gesamte Unterkunft", - "gemein_zimmer": "Gemeinsames Zimmer", - "privatzimmer": "Privatzimmer", - "7t": "bis 7 Tage", - "14t": "bis 14 Tage", - "1m": "bis 1 Monat", - "3m": "bis 3 Monate", - "6m": "bis 6 Monate", - "12m": "bis 12 Monate", - "12m_plus": "länger als 12 Monate", - "starting": "ab", - "now": "ab sofort", - "free": "kostenfrei", - "withCosts": "kostenpflichtig (Preis auf Anfrage)", - "tenancyPossible": "Übergang in Mietverhältnis möglich", - "accessible": "barrierefrei", - "bathroom": "eigenes Bad", - "lgbtiq": "LGBTIQ+ freundlich", - "haustier": "Haustiere erlaubt", - "haustier-katze": "Katzen erlaubt", - "haustier-hund": "Hunde erlaubt", - "smoking": "Rauchen erlaubt", - "rooms": "Anzahl der Zimmer:", - "occupants": "Anzahl der Bewohner:", - "notSpecified": "Keine Angabe", - "name": "Name:", - "zipcode": "Postleitzahl:", - "city": "Ort:", - "hostType": "Hausstand:", - "languages": "Sprachkenntnisse:", - "deutsch": "Deutsch", - "englisch": "Englisch", - "ukrainisch": "Ukrainisch", - "russisch": "Russisch", - "polnisch": "Polnisch", - "kroatisch": "Kroatisch", - "allein_maennlich": "alleinstehend männlich", - "allein_weiblich": "alleinstehend weiblich", - "familie_kinder": "Familie mit Kind(ern)", - "paar": "Paar ohne Kinder", - "wg": "Wohngemeinschaft", - "comments": "Ergänzende Anmerkungen", - "noSheltersAvailable": "Keine Unterkünfte verfügbar", - "shelterType": "Art des Wohnraums", - "startDate": "frühestens verfügbar", - "availableBeds": "verfügbare Betten", - "duration": "mögliche Aufenthaltsdauer", - "contactRequest": { - "title": "Kontaktanfrage", - "description": "Falls du Interesse am angebotenen Wohnraum hast, können wir Deine Kontaktinformationen an den Anbietenden weiterleiten.", - "email": "E-Mail-Adresse", - "phone": "Telefonnummer", - "success": "Deine Kontaktinformationen wurden erfolgreich weitergeleitet.", - "error": "Etwas ist leider fehlgeschlagen.", - "invalid_accommodation": "Dieses Angebot ist nicht mehr verfügbar.", - "invalid_contact_data": "Deine Kontaktinformation waren leider inkorrekt oder wurden bereits zur Kontaktanfrage verwendet.", - "send": "Abschicken" - }, - "facetBeds": "min. Anzahl Betten", - "facetCity": "Ort/PLZ", - "facetPets": "Haustiere erlaubt" - }, - "am": { - "title": "መኖሪያ ክፍል" - }, - "ar": { - "title": "غرفة المعيشة" - }, - "bg": { - "title": "Жилище" - }, - "ckb": { - "title": "جەوی ژیان" - }, - "cs": { - "title": "Obytný prostor", - "shelterTitle": "{{beds}} v lokalitě {{location}}", - "shelterInformation": "Nabízený obytný prostor", - "householdInformation": "Údaje o celé domácnosti", - "hostInformation": "Údaje o nabízejícím", - "contactInformation": "Kontaktní údaje", - "shelterButton": "Zobrazit", - "bed": "1 postel", - "beds": "{{beds}} postele", - "ges_unterkunft": "Celé ubytování", - "gemein_zimmer": "Společný pokoj", - "privatzimmer": "Soukromý pokoj", - "7t": "až 7 dní", - "14t": "až 14 dní", - "1m": "až 1 měsíc", - "3m": "až 3 měsíce", - "6m": "až 6 měsíců", - "12m": "až 12 měsíců", - "12m_plus": "déle než 12 měsíců", - "starting": "od", - "now": "okamžitě", - "free": "zdarma", - "withCosts": "s náklady (cena na vyžádání)", - "tenancyPossible": "možnost přechodu do nájmu", - "accessible": "bezbariérovost", - "bathroom": "vlastní koupelna", - "lgbtiq": "LGBTIO+ friendly", - "haustier": "Domácí zvířata povolena", - "haustier-katze": "kočky povoleny", - "haustier-hund": "Psi povoleni", - "smoking": "Kouření je povoleno", - "rooms": "Počet pokojů:", - "occupants": "Počet osob:", - "notSpecified": "Není specifikováno", - "name": "Jméno:", - "zipcode": "Poštovní směrovací číslo:", - "city": "Město:", - "hostType": "Domácnost:", - "languages": "Jazykové znalosti:", - "deutsch": "Němčina", - "englisch": "Angličtina", - "ukrainisch": "Ukrajinština", - "russisch": "Rušzina", - "polnisch": "Polština", - "kroatisch": "Chorvatština", - "allein_maennlich": "svobodný muž", - "allein_weiblich": "svobodná žena", - "familie_kinder": "rodina s dítětem (dětmi)", - "paar": "pár bez dětí", - "wg": "sdílené bydlení", - "comments": "další poznámky", - "noSheltersAvailable": "není k dispozici žádné ubytování", - "shelterType": "typ ubytování", - "startDate": "k dispozici nejdříve", - "availableBeds": "dostupná lůžka", - "duration": "možná délka pobytu", - "contactRequest": { - "title": "Kontakt", - "email": "E-mail", - "phone": "Telefonní číslo", - "error": "Něco se bohužel pokazilo.", - "invalid_accommodation": "Tato nabídka již není k dispozici.", - "send": "Odeslat" - }, - "facetBeds": "min. počet lůžek", - "facetCity": "Místo/PSČ", - "facetPets": "Domácí zvířata povolena" - }, - "el": { - "title": "Κατοικία" - }, - "en": { - "title": "Housing", - "shelterTitle": "{{beds}} in {{location}}", - "shelterInformation": "Offered housing", - "householdInformation": "Information on the entire household", - "hostInformation": "Details of the provider", - "contactInformation": "Contact details", - "shelterButton": "View", - "bed": "1 bed", - "beds": "{{beds}} beds", - "ges_unterkunft": "Entire accommodation", - "gemein_zimmer": "Shared room", - "privatzimmer": "Private room", - "7t": "up to 7 days", - "14t": "up to 14 days", - "1m": "up to 1 months", - "3m": "up to 3 months", - "6m": "up to 6 months", - "12m": "up to 12 months", - "12m_plus": "longer than 12 months", - "starting": "from", - "now": "immediately", - "free": "free of charge", - "withCosts": "Subject to a fee (price on request)", - "tenancyPossible": "Transition to tenancy possible", - "accessible": "accessible", - "bathroom": "own bathroom", - "lgbtiq": "LGBTIQ+ friendly", - "haustier": "Pets allowed", - "haustier-katze": "Cats allowed", - "haustier-hund": "Dogs allowed", - "smoking": "Smoking allowed", - "rooms": "Number of rooms:", - "occupants": "Number of occupants:", - "notSpecified": "Not specified", - "name": "Name:", - "zipcode": "Zip code:", - "city": "Location:", - "hostType": "Household:", - "languages": "Language skills:", - "deutsch": "German", - "englisch": "English", - "ukrainisch": "Ukrainian", - "russisch": "Russian", - "polnisch": "Polish", - "kroatisch": "Croatian", - "allein_maennlich": "single male", - "allein_weiblich": "single female", - "familie_kinder": "Family with child(ren)", - "paar": "Family without children", - "wg": "Flat-sharing community", - "comments": "Complementary comments", - "noSheltersAvailable": "No accommodations available", - "shelterType": "Type of living", - "startDate": "Earliest available", - "availableBeds": "Available beds", - "duration": "Possible length of stay", - "contactRequest": { - "title": "Contact request", - "email": "E-mail address", - "phone": "Telephone number", - "error": "Something failed, unfortunately.", - "invalid_accommodation": "This offer is no longer available.", - "send": "Send" - }, - "facetBeds": "Number of beds", - "facetCity": "place/zip", - "facetPets": "Pets allowed" - }, - "es": { - "title": "Vivienda" - }, - "fi": { - "title": "Asuinalue" - }, - "fr": { - "title": "Espace vital" - }, - "hr": { - "title": "Stambeni prostor" - }, - "hu": { - "title": "Lakóterület" - }, - "it": { - "title": "Vano" - }, - "ka": { - "title": "საცხოვრებელი ოთახი", - "shelterTitle": "{{beds}} {{location}}-ში", - "shelterInformation": "შეთავაზებული საცხოვრებელი ოთახი", - "householdInformation": "საყოფაცხოვრებო მონაცემები", - "hostInformation": "მონაცემები შემთავაზებლის შესახებ", - "contactInformation": "საკონტაქტო მონაცემები", - "shelterButton": "ნახვა", - "bed": "1 ლოგინი", - "beds": "{{beds}} ლოგინი", - "ges_unterkunft": "მთლიანი საცხოვრისი", - "gemein_zimmer": "საერთო ოთახი", - "privatzimmer": "პირადი ოთახი", - "7t": "7 დღემდე", - "14t": "14 დღემდე", - "1m": "1 თვემდე", - "3m": "3 თვემდე", - "6m": "6 თვემდე", - "12m": "12 თვემდე", - "12m_plus": "12 თვეზე მეტი", - "starting": "შემდეგიდან", - "now": "ახლავე", - "free": "უფასო", - "withCosts": "ფასიანი (ფასი მოთხოვნით)", - "tenancyPossible": "ქირის ხელშეკრულებაზე გადასვლის შესაძლებლობა", - "accessible": "ბარიერების გარეშე", - "bathroom": "საკუთარი სააბაზანო", - "lgbtiq": "LGBTIQ+ მეგობრული", - "haustier": "დაშვებულია შინაური ცხოველები", - "haustier-katze": "კატები დაშვებულია", - "haustier-hund": "ძაღლები დაშვებულია", - "smoking": "მოწევა დაშვებულია", - "rooms": "ოთახების რაოდენობა:", - "occupants": "მაცხოვრებლების რაოდენობა:", - "notSpecified": "არ არის მითითებული", - "name": "სახელი:", - "zipcode": "საფოსტო ინდექსი:", - "city": "ადგილი:", - "hostType": "სახლის მდგომარეობა:", - "languages": "ენა:", - "deutsch": "გერმანული", - "englisch": "ინგლისური", - "ukrainisch": "უკრაინული", - "russisch": "რუსული", - "polnisch": "პოლონური", - "kroatisch": "ხორვატული", - "allein_maennlich": "დამოუკიდებელი მამაკაცი", - "allein_weiblich": "დამოუკიდებელი ქალი", - "familie_kinder": "ოჯახი ბავშვ(ებ)ით", - "paar": "წყვილი ბავშვების გარეშე", - "wg": "საერთო საცხოვრებელი", - "comments": "დასკვნითი შენიშვნები", - "noSheltersAvailable": "საცხოვრისი არ არის ხელმისაწვდომი", - "shelterType": "საცხოვრებელი ოთახის ტიპი", - "startDate": "ყველაზე ადრე ხელმისაწვდომი", - "availableBeds": "ხელმისაწვდომი ლოგინები", - "duration": "დარჩენის შესაძლო ხანგრძლივობა", - "contactRequest": { - "title": "კონტაქტის მოთხოვნა", - "email": "ელფოსტის მისამართი", - "phone": "ტელეფონის ნომერი", - "error": "სამწუხაროდ რაღაც დახარვეზდა.", - "invalid_accommodation": "ეს შეთავაზება აღარ არის ხელმისაწვდომი.", - "send": "გაგზავნა" - }, - "facetBeds": "ლოგინების მინ.რაოდენობა", - "facetCity": "ადგილი/საფოსტო კოდი", - "facetPets": "შინაური ცხოველები დაშვებულია" - }, - "kmr": { - "title": "Atmosfera jiyanê" - }, - "mk": { - "title": "Станбен простор" - }, - "nl": { - "title": "Huisvesting", - "shelterTitle": "{{beds}} op {{location}}", - "shelterInformation": "Aangeboden huisvesting", - "householdInformation": "Informatie over het gehele huishouden", - "hostInformation": "Details van de host", - "contactInformation": "Contactgegevens", - "shelterButton": "bekijken", - "bed": "1 bed", - "beds": "{{beds}} bedden", - "ges_unterkunft": "De gehele accommodatie", - "gemein_zimmer": "Gedeelde kamer", - "privatzimmer": "Privékamer", - "7t": "Tot 7 dagen", - "14t": "Tot 14 dagen", - "1m": "Tot 1 maand", - "3m": "Tot 3 maanden", - "6m": "Tot 6 maanden", - "12m": "Tot 12 maanden", - "12m_plus": "Langer dan 12 maanden", - "starting": "Vanaf", - "now": "Meteen", - "free": "Gratis", - "withCosts": "Er zijn kosten aan verbonden (prijs op aanvraag)", - "tenancyPossible": "Overgang naar huur mogelijk", - "accessible": "Toegankelijk", - "bathroom": "Eigen badkamer", - "lgbtiq": "LGBTIQ+-vriendelijk", - "haustier": "Huisdieren toegestaan", - "haustier-katze": "Katten toegestaan", - "haustier-hund": "Honden toegestaan", - "smoking": "Roken toegestaan", - "rooms": "Aantal kamers:", - "occupants": "Aantal bewoners:", - "notSpecified": "Niet gespecificeerd", - "name": "Naam:", - "zipcode": "Postcode:", - "city": "Locatie:", - "hostType": "Huishouden:", - "languages": "Taalvaardigheden", - "deutsch": "Duits", - "englisch": "Engels", - "ukrainisch": "Oekraïens", - "russisch": "Russisch", - "polnisch": "Pools", - "kroatisch": "Kroatisch", - "allein_maennlich": "Alleenstaande man", - "allein_weiblich": "Alleenstaande vrouw", - "familie_kinder": "Familie met kind(eren)", - "paar": "Familie zonder kinderen", - "wg": "Een gemeenschap die appartementen deelt", - "comments": "Aanvullend commentaar", - "noSheltersAvailable": "Geen accomodaties", - "shelterType": "Soort opvang", - "startDate": "Eerst beschikbaar (or: eerst beschikbare opvang)", - "availableBeds": "Beschikbare bedden", - "duration": "Mogelijke verblijfsduur", - "contactRequest": { - "title": "Contact aanvraag", - "email": "E-mailadres", - "phone": "Telefoonnummer", - "error": "Helaas, er is iets misgegaan.", - "invalid_accommodation": "Dit aanbod is niet langer beschikbaar.", - "send": "Stuur" - }, - "facetBeds": "Aantal bedden", - "facetCity": "Plaats/postcode", - "facetPets": "Huisdieren toegestaan" - }, - "pes": { - "title": "مسکن" - }, - "pl": { - "title": "Zakwaterowania", - "shelterTitle": "{{beds}} w {{location}}", - "shelterInformation": "Oferowane zakwaterowanie", - "householdInformation": "Informacje dotyczące całego domostwa", - "hostInformation": "Informacje o składającym ofertę", - "contactInformation": "Dane kontaktowe", - "shelterButton": "Zobacz", - "bed": "1 łóżko", - "beds": "{{beds}} Łóżka", - "ges_unterkunft": "Całe zakwaterowanie", - "gemein_zimmer": "Pokój wspólny", - "privatzimmer": "Pokój prywatny", - "7t": "do 7 dni", - "14t": "do 14 dni", - "1m": "do 1 miesiąca", - "3m": "do 3 miesięcy", - "6m": "do 6 miesięcy", - "12m": "do 12 miesięcy", - "12m_plus": "dłużej niż 12 miesięcy", - "starting": "od", - "now": "od zaraz", - "free": "nieodpłatnie", - "withCosts": "za opłatą (cena na życzenie)", - "tenancyPossible": "Możliwość zamiany na najem", - "accessible": "bez barier", - "bathroom": "osobna łazienka", - "lgbtiq": "przyjazny dla osób LGBTIQ+", - "haustier": "Zwierzęta domowe dozwolone", - "haustier-katze": "Koty dozwolone", - "haustier-hund": "Psy dozwolone", - "smoking": "Palenie dozwolone", - "rooms": "Liczba pokoi:", - "occupants": "Liczba mieszkańców:", - "notSpecified": "Brak danych", - "name": "Nazwisko:", - "zipcode": "Kod pocztowy:", - "city": "Miejscowość:", - "hostType": "Gospodarze domu:", - "languages": "Znajomość języków obcych:", - "deutsch": "Niemiecki", - "englisch": "Angielski", - "ukrainisch": "Ukraiński", - "russisch": "Rosyjski", - "polnisch": "Polski", - "kroatisch": "Chorwacki", - "allein_maennlich": "samotny mężczyzna", - "allein_weiblich": "samotna kobieta", - "familie_kinder": "Rodzina z dzieckiem (dziećmi)", - "paar": "Para bez dzieci", - "wg": "Mieszkanie wspólne", - "comments": "Uwagi uzupełniające", - "noSheltersAvailable": "Brak miejsc do zakwaterowania", - "shelterType": "Rodzaj zakwaterowania", - "startDate": "najwcześniej dostępne", - "availableBeds": "wolne łóżka", - "duration": "możliwa długość pobytu", - "contactRequest": { - "title": "Kontakt", - "email": "Adres e-mail", - "phone": "Numer telefonu", - "error": "Przepraszamy, coś poszło nie tak.", - "invalid_accommodation": "Ta oferta nie jest już dostępna.", - "send": "Wyślij" - }, - "facetBeds": "min. liczba łóżek", - "facetCity": "miejsce/zamek błyskawiczny", - "facetPets": "Zwierzęta domowe dozwolone" - }, - "prs": { - "title": "مسکن" - }, - "ps": { - "title": "د اوسیدلو کوټہ" - }, - "pt": { - "title": "Habitaciones", - "shelterTitle": "{{beds}} en {{location}}", - "shelterInformation": "Habitación ofrecida", - "householdInformation": "Datos de toda la casa", - "hostInformation": "Datos del ofertante", - "contactInformation": "Datos de contacto", - "shelterButton": "Ver", - "bed": "1 cama", - "beds": "{{beds}} camas", - "ges_unterkunft": "Alojamiento completo", - "gemein_zimmer": "Habitación compartida", - "privatzimmer": "Habitación privada", - "7t": "Hasta 7 días", - "14t": "Hasta 14 días", - "1m": "Hasta 1 mes", - "3m": "Hasta 3 meses", - "6m": "Hasta 6 meses", - "12m": "Hasta 12 meses", - "12m_plus": "Más de 12 meses", - "starting": "Desde", - "now": "Desde ahora", - "free": "Gratis", - "withCosts": "De pago (hay que preguntar el precio)", - "tenancyPossible": "Es posible cambiar a contrato de alquiler", - "accessible": "Accesos adaptados", - "bathroom": "Baño propio", - "lgbtiq": "Pro LGBTIQ+", - "haustier": "Se permiten mascotas", - "haustier-katze": "Se permiten gatos", - "haustier-hund": "Se permiten perros", - "smoking": "Se permite fumar", - "rooms": "Número de habitaciones:", - "occupants": "Número de personas:", - "notSpecified": "Sin datos", - "name": "Nombre:", - "zipcode": "Código postal:", - "city": "Lugar:", - "hostType": "Casa:", - "languages": "Idiomas:", - "deutsch": "Alemán", - "englisch": "Inglés", - "ukrainisch": "Ucraniano", - "russisch": "Ruso", - "polnisch": "Polaco", - "kroatisch": "Croata", - "allein_maennlich": "Hombre soltero", - "allein_weiblich": "Mujer soltera", - "familie_kinder": "Familia con hijo(s)", - "paar": "Pareja sin hijos", - "wg": "Residencia compartida", - "comments": "Otros comentarios", - "noSheltersAvailable": "No hay disponible ningún alojamiento", - "shelterType": "Tipo de habitación", - "startDate": "Disponible lo antes posible", - "availableBeds": "Camas disponibles", - "duration": "Posible duración de la estancia", - "contactRequest": { - "title": "Solicitud de contacto", - "email": "Correo electrónico", - "phone": "Número de teléfono", - "error": "Lamentablemente, algo ha fallado.", - "invalid_accommodation": "Esta oferta ya no está disponible.", - "send": "Enviar" - }, - "facetBeds": "Cantidad de camas mín.", - "facetCity": "Lugar/Código postal", - "facetPets": "Se permiten mascotas" - }, - "ro": { - "title": "Spațiu de locuit" - }, - "ru": { - "title": "Жильё", - "shelterTitle": "{{beds}} в {{location}}", - "shelterInformation": "Доступное жильё", - "householdInformation": "информация обо всей семье", - "hostInformation": "Информация о провайдере", - "contactInformation": "Контактная информация", - "shelterButton": "Посмотреть", - "bed": "1 кровать", - "beds": "{{beds}} Кровати", - "ges_unterkunft": "Квартира", - "gemein_zimmer": "Общая комната", - "privatzimmer": "Отдельная комната", - "7t": "до 7 дней", - "14t": "до 14 дней", - "1m": "до 1 месяца", - "3m": "до 3 месяцев", - "6m": "до 6 месяцев", - "12m": "до 12 месяцев", - "12m_plus": "более 12 месяцев", - "starting": "Начиная с", - "now": "Незамедлительно", - "free": "бесплатно", - "withCosts": "При условии внесения платы (цена по запросу)", - "tenancyPossible": "Переход к аренде жилья возможен", - "accessible": "Доступное для людей с ограниченными возможностями", - "bathroom": "eigenes Bad", - "lgbtiq": "ЛГБТИК+ френдли", - "haustier": "Домашние животные разрешены", - "haustier-katze": "Кошки разрешены", - "haustier-hund": "Собаки разрешены", - "smoking": "Курение разрешено", - "rooms": "Количество номеров:", - "occupants": "Количество жителей:", - "notSpecified": "Не указано", - "name": "Имя:", - "zipcode": "Почтовый индекс:", - "city": "Город:", - "hostType": "Хозяйство:", - "languages": "Знание языков:", - "deutsch": "немецкий", - "englisch": "английский язык", - "ukrainisch": "украинский", - "russisch": "русский", - "polnisch": "польский", - "kroatisch": "хорватский", - "allein_maennlich": "холостой мужчина", - "allein_weiblich": "одинокая женщина", - "familie_kinder": "Семья с детьми", - "paar": "Семья без детей", - "wg": "Общая квартира с друзьями", - "comments": "Дополнительные примечания", - "noSheltersAvailable": "Жилье не предоставляется", - "shelterType": "Тип жилья", - "startDate": "доступное как можно скорее", - "availableBeds": "свободные кровати", - "duration": "возможный срок пребывания", - "contactRequest": { - "title": "Контактная информация", - "email": "адрес электронной почты", - "phone": "Телефонный номер", - "error": "Извините, что-то пошло не так.", - "invalid_accommodation": "Это предложение больше не доступно.", - "send": "Отправить" - }, - "facetBeds": "минимальное количество кроватей", - "facetCity": "ме́сто/почто́вый и́ндекс", - "facetPets": "Домашние животные разрешены" - }, - "so": { - "title": "Qolka fadhiga" - }, - "sq": { - "title": "Vendbanimi" - }, - "sr-Cyrl": { - "title": "Стамбени простор" - }, - "sr-Latn": { - "title": "Stambeni prostor" - }, - "ti": { - "title": "መንበሪ ክፍሊ" - }, - "tr": { - "title": "Oturma odası" - }, - "uk": { - "title": "Житло", - "shelterTitle": "{{beds}} y {{location}}", - "shelterInformation": "Пропонували житло", - "householdInformation": "Інформація про все домогосподарство", - "hostInformation": "Деталі про господаря", - "contactInformation": "Контактна інформація", - "shelterButton": "Перегляд", - "bed": "1 Ліжко", - "beds": "{{beds}}Ліжка", - "ges_unterkunft": "Ціле помешкання", - "gemein_zimmer": "Спільна кімната", - "privatzimmer": "Власна кімната", - "7t": "до 7 днів", - "14t": "до 14 днів", - "1m": "до 1 місяця", - "3m": "до 3 місяців", - "6m": "до 6 місяців", - "12m": "до 12 місяців", - "12m_plus": "довше ніж 12 місяців", - "starting": "з", - "now": "негайно", - "free": "безкоштовно", - "withCosts": "оренда платна (вартість за запитом)", - "tenancyPossible": "Можливий перехід на орендні відносини", - "accessible": "доступно", - "bathroom": "власна ванна кімната", - "lgbtiq": "LGBTIQ+", - "haustier": "можна з тваринами", - "haustier-katze": "можна з котиками", - "haustier-hund": "можна з собаками", - "smoking": "Палити дозволено", - "rooms": "Кількість кімнат:", - "occupants": "Кільксть людей:", - "notSpecified": "Не вказано", - "name": "Ім'я:", - "zipcode": "Почтовий індекс:", - "city": "Місто:", - "hostType": "Господарь:", - "languages": "Знання мови:", - "deutsch": "Німецька", - "englisch": "Англійська", - "ukrainisch": "Українська", - "russisch": "Російська", - "polnisch": "Польська", - "kroatisch": "хорватська", - "allein_maennlich": "Чоловік", - "allein_weiblich": "Жінка", - "familie_kinder": "Сім'я з дітьми", - "paar": "Сім'я без дітей", - "wg": "Комунальна квартира", - "comments": "Коментарі", - "noSheltersAvailable": "Немає доступного житла", - "shelterType": "вид квартири", - "startDate": "Доступне з", - "availableBeds": "наявні ліжка", - "duration": "можлива тривалість перебування", - "contactRequest": { - "title": "Форма для запиту", - "email": "Електронна адреса", - "phone": "Номер телефону", - "error": "Помилка,щось пішло не так.", - "invalid_accommodation": "Ця пропозиція більше не дійсна.", - "send": "Відправлено" - }, - "facetBeds": "кількість ліжок", - "facetCity": "Розташування/Поштовий індекс", - "facetPets": "Допускаються домашні тварини" - }, - "ur": { - "title": "رہنے کا کمرہ" - }, - "zh-CN": { - "title": "居住空间" - } - }, "socialMedia": { "de": { "facebookTooltip": "auf Facebook teilen", diff --git a/web/src/CityContentSwitcher.tsx b/web/src/CityContentSwitcher.tsx index 455135e5b5..e3837c3266 100644 --- a/web/src/CityContentSwitcher.tsx +++ b/web/src/CityContentSwitcher.tsx @@ -13,7 +13,6 @@ import { OFFERS_ROUTE, POIS_ROUTE, SEARCH_ROUTE, - SHELTER_ROUTE, SPRUNGBRETT_OFFER_ROUTE, useLoadFromEndpoint, } from 'api-client' @@ -28,7 +27,6 @@ import LoadingSpinner from './components/LoadingSpinner' import buildConfig from './constants/buildConfig' import { cmsApiBaseUrl } from './constants/urls' import { LOCAL_NEWS_ROUTE, RoutePatterns, RouteType, TU_NEWS_DETAIL_ROUTE, TU_NEWS_ROUTE } from './routes' -import ShelterPage from './routes/ShelterPage' import lazyWithRetry from './utils/retryImport' const TuNewsDetailPage = lazyWithRetry(() => import('./routes/TuNewsDetailPage')) @@ -139,7 +137,6 @@ const CityContentSwitcher = ({ languageCode }: CityContentSwitcherProps): ReactE {render(CATEGORIES_ROUTE, CategoriesPage)} {eventsEnabled && render(EVENTS_ROUTE, EventsPage, ':eventId')} - {offersEnabled && render(SHELTER_ROUTE, ShelterPage, ':shelterId')} {offersEnabled && render(SPRUNGBRETT_OFFER_ROUTE, SprungbrettOfferPage)} {offersEnabled && render(OFFERS_ROUTE, OffersPage)} {poisEnabled && render(POIS_ROUTE, PoisPage, ':slug')} diff --git a/web/src/components/CityContentHeader.tsx b/web/src/components/CityContentHeader.tsx index f2c8ef688b..db7d1feed9 100644 --- a/web/src/components/CityContentHeader.tsx +++ b/web/src/components/CityContentHeader.tsx @@ -12,7 +12,6 @@ import { pathnameFromRouteInformation, POIS_ROUTE, SEARCH_ROUTE, - SHELTER_ROUTE, SPRUNGBRETT_OFFER_ROUTE, } from 'api-client' import { config } from 'translations' @@ -154,7 +153,7 @@ const CityContentHeader = ({ , diff --git a/web/src/components/ShelterContactRequestForm.tsx b/web/src/components/ShelterContactRequestForm.tsx deleted file mode 100644 index 445f3132a1..0000000000 --- a/web/src/components/ShelterContactRequestForm.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import React, { ReactElement, useCallback, useState } from 'react' -import { useTranslation } from 'react-i18next' -import styled from 'styled-components' - -import { createShelterContactEndpoint, ShelterContactStatus } from 'api-client' - -import ShelterInformationSection from './ShelterInformationSection' -import TextInput from './TextInput' -import TextButton from './base/TextButton' - -const Container = styled.form` - padding: 0 12px; - margin-top: 10px; - flex-direction: column; - display: flex; -` - -const TextContainer = styled.div` - display: flex; - justify-content: space-between; - align-items: center; -` - -const StyledTextInput = styled(TextInput)` - width: 50%; -` - -const Label = styled.label` - padding: 10px 0 5px; -` - -const ErrorText = styled.div` - color: red; - padding-top: 12px; -` - -const HonigTopf = styled(TextInput)` - position: absolute; - height: 0; - width: 0; - z-index: -1; -` - -type Status = ShelterContactStatus | 'idle' | 'sending' | 'error' - -type ShelterContactRequestFormProps = { - shelterId: number - cityCode: string -} - -const ShelterContactRequestForm = ({ shelterId, cityCode }: ShelterContactRequestFormProps): ReactElement => { - const [email, setEmail] = useState('') - const [phone, setPhone] = useState('') - const [status, setStatus] = useState('idle') - const [name, setName] = useState('') - const { t } = useTranslation('shelter') - - const postContactRequest = useCallback(async () => { - if (name.length > 0) { - // Prevent spamming by creating a simple honeypot - return - } - try { - setStatus('sending') - const status = await createShelterContactEndpoint().request({ id: shelterId, email, phone, cityCode }) - setStatus(status.data ?? 'error') - } catch (e) { - setStatus('error') - } finally { - setPhone('') - setEmail('') - } - }, [email, phone, shelterId, cityCode, name]) - - const buttonDisabled = status === 'sending' || (email.length === 0 && phone.length === 0 && name.length === 0) - - return ( - - - {t(status === 'success' ? t('contactRequest.success') : t('contactRequest.description'))} - - {['error', 'invalid_contact_data', 'invalid_accommodation'].includes(status) && ( - {t(`contactRequest.${status}`)} - )} - - {status !== 'success' && ( - <> - setName(event.target.value)} - autoComplete='off' - /> - - - - setEmail(event.target.value)} - value={email} - /> - - - - - setPhone(event.target.value)} - value={phone} - /> - - - - )} - - - ) -} - -export default ShelterContactRequestForm diff --git a/web/src/components/ShelterDetail.tsx b/web/src/components/ShelterDetail.tsx deleted file mode 100644 index 62e1e943da..0000000000 --- a/web/src/components/ShelterDetail.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React, { ReactElement } from 'react' - -import { - CityModel, - createShelterEndpoint, - NotFoundError, - pathnameFromRouteInformation, - SHELTER_ROUTE, - useLoadFromEndpoint, -} from 'api-client' - -import CityContentLayout, { CityContentLayoutProps } from './CityContentLayout' -import FailureSwitcher from './FailureSwitcher' -import LoadingSpinner from './LoadingSpinner' -import ShelterInformation from './ShelterInformation' - -type ShelterDetailProps = { - city: CityModel - cityCode: string - languageCode: string - pathname: string - shelterId: string -} - -const ShelterDetail = ({ city, cityCode, languageCode, pathname, shelterId }: ShelterDetailProps): ReactElement => { - const { - data: shelters, - loading, - error, - } = useLoadFromEndpoint(createShelterEndpoint, '', { - type: 'detail', - id: shelterId, - cityCode, - }) - - const languageChangePaths = city.languages.map(({ code, name }) => ({ - path: `${pathnameFromRouteInformation({ route: SHELTER_ROUTE, cityCode, languageCode: code })}/${shelterId}`, - name, - code, - })) - const locationLayoutParams: Omit = { - city, - languageChangePaths, - route: SHELTER_ROUTE, - languageCode, - } - - if (loading) { - return ( - - - - ) - } - - const shelter = shelters?.find(it => it.id.toString() === shelterId) - - if (!shelter) { - const notFoundError = new NotFoundError({ type: 'offer', id: pathname, city: cityCode, language: languageCode }) - return ( - - - - ) - } - return ( - - - - ) -} - -export default ShelterDetail diff --git a/web/src/components/ShelterFilterBar.tsx b/web/src/components/ShelterFilterBar.tsx deleted file mode 100644 index 47479c01b3..0000000000 --- a/web/src/components/ShelterFilterBar.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React, { ReactElement } from 'react' -import { useTranslation } from 'react-i18next' -import styled from 'styled-components' - -import { FilterProps } from 'api-client/src/endpoints/createShelterEndpoint' - -import { BedIcon, PetIcon } from '../assets' -import dimensions from '../constants/dimensions' -import FacetInput from './FacetInput' -import FacetToggle from './FacetToggle' -import HighlightBox from './HighlightBox' - -type ShelterFilterBarProps = { - filter: FilterProps - updateSearchFilter: (key: string, value: string) => void -} - -const FilterContainer = styled(HighlightBox)` - margin: 12px; - font-size: 14px; - display: flex; - justify-content: space-between; - - @media ${dimensions.smallViewport} { - flex-wrap: wrap; - gap: 8px; - } -` - -const ShelterFilterBar: React.FC = ({ - filter, - updateSearchFilter, -}: ShelterFilterBarProps): ReactElement => { - const { t } = useTranslation('shelter') - - return ( - - - {/* TODO comment in when backend is ready https://git.tuerantuer.org/DF/wohnraumboerse_formular/issues/33 */} - {/* */} - - - ) -} - -export default ShelterFilterBar diff --git a/web/src/components/ShelterInformation.tsx b/web/src/components/ShelterInformation.tsx deleted file mode 100644 index d62dddd473..0000000000 --- a/web/src/components/ShelterInformation.tsx +++ /dev/null @@ -1,164 +0,0 @@ -import { DateTime } from 'luxon' -import React, { ReactElement } from 'react' -import { useTranslation } from 'react-i18next' -import styled from 'styled-components' - -import { ShelterModel } from 'api-client' - -import { - AccessibleIcon, - BathroomIcon, - BedIcon, - CalendarIcon, - MailIcon, - EuroIcon, - HouseIcon, - KeyIcon, - LgbtqiIcon, - PetIcon, - PhoneIcon, - SmokingIcon, - TimerIcon, -} from '../assets' -import Caption from './Caption' -import HighlightBox from './HighlightBox' -import ShelterContactRequestForm from './ShelterContactRequestForm' -import ShelterInformationSection from './ShelterInformationSection' -import Tooltip from './Tooltip' -import TextButton from './base/TextButton' - -const FullWidth = styled.div` - flex: 1; -` - -const Container = styled(HighlightBox)` - flex-direction: column; - margin: 12px; -` - -const Detail = styled.div` - padding: 0 12px; - margin-top: 10px; - flex-direction: row; - display: flex; -` - -const IconContainer = styled.div` - margin-right: 18px; -` - -type IconWithTooltipProps = { - tooltip: string - icon: string -} - -const IconWithTooltip = ({ tooltip, icon }: IconWithTooltipProps): ReactElement => ( - - - {tooltip} - - -) - -type ShelterInformationProps = { - shelter: ShelterModel - extended?: boolean - cityCode: string -} - -const ShelterInformation = ({ shelter, cityCode, extended = false }: ShelterInformationProps): ReactElement => { - const { beds, city, id, accommodationType, period, startDate, info, rooms, occupants, name } = shelter - const { zipcode, hostType, languages, email, phone, comments, costs } = shelter - const { t } = useTranslation('shelter') - - const notSpecified = t('notSpecified') - const bedsText = t('bed', { count: beds }) - const titleText = t('shelterTitle', { beds: bedsText, location: city }) - const titleHint = `(#${id})` - const startDateText = - DateTime.fromFormat(startDate, 'dd.LL.yyyy') <= DateTime.now() ? t('now') : `${t('starting')} ${startDate}` - - const allowedPets = info.filter(it => it.includes('haustier')) - const petsTooltip = allowedPets.length === 2 ? t('haustier') : t(allowedPets[0] ?? 'notSpecified') - const petsAllowed = allowedPets.length !== 0 - - const languagesText = languages.length !== 0 ? languages.map(it => t(it)).join(', ') : notSpecified - const isFree = costs !== 'kostenpflichtig' - const tenancyPossible = costs === 'uebergang-miete' - - return ( - - {extended && } - - - - {info.includes('bad') && } - {info.includes('lgbtiq') && } - {info.includes('barrierefrei') && } - {petsAllowed && } - {info.includes('rauchen') && } - - - {extended && ( - <> - - - {!!comments && ( - - )} - {email || phone ? ( - - ) : ( - - )} - - )} - {!extended && undefined} text={t('shelterButton')} />} - - - ) -} - -export default ShelterInformation diff --git a/web/src/components/ShelterInformationSection.tsx b/web/src/components/ShelterInformationSection.tsx deleted file mode 100644 index eca8dcf304..0000000000 --- a/web/src/components/ShelterInformationSection.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import React, { ReactElement } from 'react' -import styled from 'styled-components' - -import useWindowDimensions from '../hooks/useWindowDimensions' -import CleanLink from './CleanLink' -import Tooltip from './Tooltip' -import Icon from './base/Icon' - -const Container = styled.div<{ extended: boolean; elevated: boolean }>` - ${props => (props.elevated ? `background-color: ${props.theme.colors.backgroundColor};` : '')} - ${props => (props.elevated ? `padding: 12px;` : '')} - ${props => (props.elevated ? `margin: 16px;` : '')} - ${props => (props.elevated ? `border-radius: 5px;` : '')} - ${props => (props.elevated ? `box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.15);` : '')} - ${props => (props.extended ? 'padding-bottom: 32px;' : '')} - ${props => (props.extended ? 'border-bottom: 1px solid #d4d4d4;' : '')} -` - -const Row = styled.div` - display: flex; - flex-flow: row wrap; -` - -const RowDetail = styled.div<{ singleColumn: boolean }>` - display: grid; - grid-template-columns: ${props => (props.singleColumn ? `repeat(1, 1fr)` : `repeat(2, 1fr)`)}; -` - -const Title = styled.span` - padding: 16px 12px; - font-size: ${props => props.theme.fonts.subTitleFontSize}; - font-weight: 700; -` - -const TitleHint = styled.span` - padding: 16px 0; - margin: 0 8px; - font-size: ${props => props.theme.fonts.subTitleFontSize}; - color: ${props => props.theme.colors.textSecondaryColor}; -` - -const Detail = styled.div<{ extended: boolean; to?: string }>` - padding: 5px 10px; - display: flex; - align-items: center; - ${props => (props.to ? 'cursor: pointer;' : '')} -` - -const DetailText = styled.span<{ hasText: boolean }>` - margin-left: 16px; - align-self: ${props => (props.hasText ? 'flex-start' : 'center')}; - ${props => props.hasText && ` font-weight: bold;`}; -` - -const RightTextContainer = styled.span` - margin-left: 8px; - align-self: flex-start; -` - -const Label = styled.span` - display: flex; - padding: 0 8px; - margin: auto 8px auto auto; - background-color: #74d49e; - border-radius: 4px; - color: ${props => props.theme.colors.backgroundColor}; - font-size: 14px; - box-shadow: - 0 1px 3px rgba(0, 0, 0, 0.1), - 0 1px 2px rgba(0, 0, 0, 0.15); -` - -const StyledTooltip = styled(Tooltip)` - display: flex; -` - -type InformationType = { - icon?: string - tooltip?: string - text: string - rightText?: string - link?: string -} - -type ShelterInformationSectionProps = { - title: string - titleHint?: string - label?: string - information: InformationType[] - children?: ReactElement - extended: boolean - elevated?: boolean - singleColumn?: boolean -} - -const ShelterInformationSection = ({ - title, - titleHint, - label, - information, - children, - extended, - elevated = false, - singleColumn = false, -}: ShelterInformationSectionProps): ReactElement => { - const { viewportSmall } = useWindowDimensions() - return ( - - - {title} - {!!titleHint && {titleHint}} - {!!label && } - - - {information.map(({ text, icon, rightText, link, tooltip }) => { - const content = ( - <> - {!!icon && } - {text} - {!!rightText && {rightText}} - - ) - return ( - - {tooltip ? ( - - {content} - - ) : ( - content - )} - - ) - })} - {children} - - - ) -} - -export default ShelterInformationSection diff --git a/web/src/components/ShelterListItem.tsx b/web/src/components/ShelterListItem.tsx deleted file mode 100644 index 25241684f7..0000000000 --- a/web/src/components/ShelterListItem.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React, { ReactElement } from 'react' - -import { pathnameFromRouteInformation, SHELTER_ROUTE, ShelterModel } from 'api-client' - -import CleanLink from './CleanLink' -import ShelterInformation from './ShelterInformation' - -type ShelterListItemProps = { - shelter: ShelterModel - cityCode: string - languageCode: string -} - -const ShelterListItem = ({ shelter, cityCode, languageCode }: ShelterListItemProps): ReactElement => ( - - - -) - -export default ShelterListItem diff --git a/web/src/routes/OffersPage.tsx b/web/src/routes/OffersPage.tsx index 200f1d737a..d33ca725a4 100644 --- a/web/src/routes/OffersPage.tsx +++ b/web/src/routes/OffersPage.tsx @@ -6,7 +6,6 @@ import { OfferModel, OFFERS_ROUTE, pathnameFromRouteInformation, - SHELTER_ROUTE, SPRUNGBRETT_OFFER, SPRUNGBRETT_OFFER_ROUTE, useLoadFromEndpoint, @@ -38,8 +37,6 @@ const OffersPage = ({ city, cityCode, languageCode }: CityRouteProps): ReactElem if (offer.alias === SPRUNGBRETT_OFFER) { // the url stored in the sprungbrett offer is the url of the endpoint path = pathnameFromRouteInformation({ route: SPRUNGBRETT_OFFER_ROUTE, cityCode, languageCode }) - } else if (offer.alias === SHELTER_ROUTE) { - path = pathnameFromRouteInformation({ route: SHELTER_ROUTE, cityCode, languageCode }) } return new TileModel({ diff --git a/web/src/routes/ShelterPage.tsx b/web/src/routes/ShelterPage.tsx deleted file mode 100644 index 45a1a0ee99..0000000000 --- a/web/src/routes/ShelterPage.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import React, { ReactElement, useCallback, useState } from 'react' -import { useTranslation } from 'react-i18next' -import { useParams } from 'react-router-dom' - -import { - createShelterEndpoint, - pathnameFromRouteInformation, - SHELTER_ROUTE, - ShelterModel, - ShelterFilterProps, -} from 'api-client' - -import { CityRouteProps } from '../CityContentSwitcher' -import Caption from '../components/Caption' -import CityContentLayout, { CityContentLayoutProps } from '../components/CityContentLayout' -import Helmet from '../components/Helmet' -import InfiniteScrollList from '../components/InfiniteScrollList' -import ShelterDetail from '../components/ShelterDetail' -import ShelterFilterBar from '../components/ShelterFilterBar' -import ShelterListItem from '../components/ShelterListItem' - -const DEFAULT_PAGE = 1 -const ITEMS_PER_PAGE = 10 - -const ShelterPage = ({ city, cityCode, languageCode, pathname }: CityRouteProps): ReactElement | null => { - const { shelterId } = useParams() - const { t } = useTranslation('shelter') - const [filter, setFilter] = useState({ beds: null, city: null, pets: null }) - - const loadShelters = useCallback( - async (page: number) => { - const { data } = await createShelterEndpoint().request({ - type: 'list', - page, - cityCode, - filter, - }) - - if (!data) { - throw new Error('Data missing!') - } - return data - }, - [cityCode, filter], - ) - - if (!city) { - return null - } - - const languageChangePaths = city.languages.map(({ code, name }) => ({ - path: pathnameFromRouteInformation({ route: SHELTER_ROUTE, cityCode, languageCode: code }), - name, - code, - })) - - const updateSearchFilter = (key: string, val: string) => { - switch (key) { - case 'beds': - setFilter({ ...filter, beds: val }) - break - case 'city': - setFilter({ ...filter, city: val }) - break - case 'pets': - setFilter({ ...filter, pets: val }) - break - } - } - - const locationLayoutParams: Omit = { - city, - languageChangePaths, - route: SHELTER_ROUTE, - languageCode, - } - - if (shelterId) { - return ( - - ) - } - - const pageTitle = `${t('title')} - ${city.name}` - - const renderListItem = (shelter: ShelterModel): ReactElement => ( - - ) - - return ( - - - - - - - ) -} - -export default ShelterPage diff --git a/web/src/routes/index.ts b/web/src/routes/index.ts index 2a87223a79..b6deb3ec6c 100644 --- a/web/src/routes/index.ts +++ b/web/src/routes/index.ts @@ -13,7 +13,6 @@ import { OFFERS_ROUTE, POIS_ROUTE, SEARCH_ROUTE, - SHELTER_ROUTE, SPRUNGBRETT_OFFER_ROUTE, TU_NEWS_TYPE, } from 'api-client' @@ -34,7 +33,6 @@ export const RoutePatterns = { // City content routes, relative to /:cityCode/:languageCode [EVENTS_ROUTE]: EVENTS_ROUTE, [SPRUNGBRETT_OFFER_ROUTE]: `${OFFERS_ROUTE}/${SPRUNGBRETT_OFFER_ROUTE}`, - [SHELTER_ROUTE]: `${OFFERS_ROUTE}/${SHELTER_ROUTE}`, [OFFERS_ROUTE]: OFFERS_ROUTE, [POIS_ROUTE]: POIS_ROUTE, [LOCAL_NEWS_ROUTE]: `${NEWS_ROUTE}/${LOCAL_NEWS_ROUTE}`,