templates/vitrine/en/homepage.html.twig line 1

Open in your IDE?
  1. {% extends 'vitrine/en/layout.html.twig' %}
  2. {% block title %}Cathedral Heritage Suite - 8-Guest Rental Strasbourg Center{% endblock title %}
  3. {% block description %}Rent our 83m² suite in the heart of Strasbourg. 3 bedrooms, sleeps 8, 100m from Cathedral. Kitchen fully furnished, 2 bathrooms. Book your stay today!{% endblock description %}
  4. {% block robots %}index,follow{% endblock robots %}
  5. {% block canonical %}
  6. <link rel="canonical" href="https://cathedraleheritage.com" />
  7. <link rel="alternate" hreflang="fr" href="https://cathedraleheritage.com/fr" />
  8. <link rel="alternate" hreflang="en" href="https://cathedraleheritage.com" />
  9. <link rel="alternate" hreflang="x-default" href="https://cathedraleheritage.com" />
  10. {% endblock canonical %}
  11. {% block body %}
  12. <section id="hero" class="text-light no-top no-bottom relative overflow-hidden z-1000">
  13. <div class="abs w-100 abs-centered z-2">
  14. <div class="container">
  15. <div class="spacer-double"></div>
  16. <div class="row g-4 align-items-center justify-content-center">
  17. <div class="col-md-8 text-center">
  18. <h1 class="mb-2" style="color:white;">Welcome to Cathedral Heritage Suite</h1>
  19. <p class="lead mb-3" style="color:white; font-size:22px;">Beautifully appointed apartment accommodating up to 8 guests in Strasbourg’s prestigious historical city center</p>
  20. <a class="btn-main btn-line bg-blur fx-slide" href="#about" style="color:white;"><span>Find out more</span></a>
  21. </div>
  22. </div>
  23. </div>
  24. </div>
  25. <div class="vertical-center">
  26. <div class="swiper">
  27. <div class="swiper-wrapper">
  28. <div class="swiper-slide">
  29. <div class="swiper-inner" data-bgimage="url(/images/salon2.jpeg)">
  30. <div class="sw-overlay op-5"></div>
  31. </div>
  32. </div>
  33. <div class="swiper-slide">
  34. <div class="swiper-inner" data-bgimage="url(/images/chambre2.jpeg)">
  35. <div class="sw-overlay op-5"></div>
  36. </div>
  37. </div>
  38. <div class="swiper-slide">
  39. <div class="swiper-inner" data-bgimage="url(/images/noel.jpeg)">
  40. <div class="sw-overlay op-5"></div>
  41. </div>
  42. </div>
  43. </div>
  44. </div>
  45. </div>
  46. <div class="abs w-100 bottom-0 z-2 pb-4 sm-hide">
  47. <div class="container">
  48. <div class="row">
  49. <div class="col-lg-12">
  50. <div class="d-flex justify-content-between">
  51. <div>
  52. <h6 style="color:white;">Cathedral 100m away</h6>
  53. </div>
  54. <div>
  55. <h6 style="color:white;">Museums 200m away</h6>
  56. </div>
  57. <div>
  58. <h6 style="color:white;">Petite France 300m away</h6>
  59. </div>
  60. </div>
  61. </div>
  62. </div>
  63. </div>
  64. </div>
  65. <div class="gradient-edge-bottom op-8"></div>
  66. </section>
  67. <section id="about">
  68. <div class="container">
  69. <div class="row g-4 align-items-end justify-content-between">
  70. <div class="col-lg-5">
  71. <div class="subtitle">About the apartment</div>
  72. <h2>Modern suite in the heart of Strasbourg's Grande Île</h2>
  73. </div>
  74. <div class="col-lg-4">
  75. <p class="mb-4" style="color:#212121;">
  76. Spacious fully equipped appartement ideal for families and groups up to 8 people : 1 master bedroom with en-suite bathroom, one double bedroom, one bedroom with two double bunk beds (sleeps 4), maximum weight of 100kg for upper bunks.
  77. </p>
  78. <p class="mb-4" style="color:#212121;">
  79. Kitchen fully furnished and cozy living-dining room to share great moments together.
  80. </p>
  81. <p class="mb-4" style="color:#212121;">
  82. Amenities: hairdryer, dishwasher, washer-dryer, microwave, oven, ironing board with iron, Nespresso coffee machine, kettle, TV, Wi-Fi and USB outlets for charging your devices.
  83. </p>
  84. </div>
  85. </div>
  86. <div class="spacer-single"></div>
  87. <div class="row g-4">
  88. <div class="col-md-2">
  89. <div class="relative">
  90. <h5>Size</h5>
  91. <div class="d-flex justify-content-start align-items-center" style="padding-top:6px;">
  92. <img src="/images/home.png" width="37" class="me-3" alt="">
  93. <div class="fs-20 fw-600" style="color:#212121;">83 m²</div>
  94. </div>
  95. </div>
  96. </div>
  97. <div class="col-md-2">
  98. <div class="relative">
  99. <h5>Bedrooms</h5>
  100. <div class="d-flex justify-content-start align-items-center" style="padding-top:4px;">
  101. <img src="/images/bed.png" width="37" class="me-3" alt="">
  102. <div class="fs-20 fw-600" style="color:#212121;">3</div>
  103. </div>
  104. </div>
  105. </div>
  106. <div class="col-md-2">
  107. <div class="relative">
  108. <h5>Living Room</h5>
  109. <div class="d-flex justify-content-start align-items-center">
  110. <img src="/images/sofa.png" width="50" class="me-3" alt="">
  111. <div class="fs-20 fw-600" style="color:#212121;">Included</div>
  112. </div>
  113. </div>
  114. </div>
  115. <div class="col-md-2">
  116. <div class="relative">
  117. <h5>Kitchen</h5>
  118. <div class="d-flex justify-content-start align-items-center" style="padding-top:6px;">
  119. <img src="/images/cooking.png" width="37" class="me-3" alt="">
  120. <div class="fs-20 fw-600" style="color:#212121;">Included</div>
  121. </div>
  122. </div>
  123. </div>
  124. <div class="col-md-2">
  125. <div class="relative">
  126. <h5>Bathrooms</h5>
  127. <div class="d-flex justify-content-start align-items-center" style="padding-top:4px;">
  128. <img src="/images/bathroom.png" width="40" class="me-3" alt="">
  129. <div class="fs-20 fw-600" style="color:#212121;">2</div>
  130. </div>
  131. </div>
  132. </div>
  133. <div class="col-md-2">
  134. <div class="relative">
  135. <h5>Guests</h5>
  136. <div class="d-flex justify-content-start align-items-center" style="padding-top:5px;">
  137. <img src="/images/user.png" width="37" class="me-3" alt="">
  138. <div class="fs-20 fw-600" style="color:#212121;">8</div>
  139. </div>
  140. </div>
  141. </div>
  142. </div>
  143. </div>
  144. </section>
  145. <section id="rooms" class="p-0 overflow-hidden">
  146. <div class="container-fluid">
  147. <div class="row">
  148. <div class="col-lg-12">
  149. <div class="owl-custom-nav menu-float" data-target="#room-carousel">
  150. <a class="btn-next"></a>
  151. <a class="btn-prev"></a>
  152. <div id="room-carousel" class="owl-2-cols-center owl-carousel owl-theme">
  153. <div class="item">
  154. <div class="relative">
  155. <div class="overflow-hidden text-light">
  156. <div class="abs h-100 start-0 z-2 p-4">
  157. <h3 style="color:white;">Living Room</h3>
  158. </div>
  159. <img src="/images/salon2.jpeg" class="w-100" alt="Living Room">
  160. </div>
  161. </div>
  162. </div>
  163. <div class="item">
  164. <div class="relative">
  165. <div class="overflow-hidden text-light">
  166. <div class="abs h-100 start-1 z-2 p-4">
  167. <h3 style="color:white;">Bedroom 1</h3>
  168. </div>
  169. <img src="/images/chambre1.jpeg" class="w-100" alt="Bedroom 1">
  170. </div>
  171. </div>
  172. </div>
  173. <div class="item">
  174. <div class="relative">
  175. <div class="overflow-hidden text-light">
  176. <div class="abs h-100 start-2 z-2 p-4">
  177. <h3 style="color:white;">Bedroom 2</h3>
  178. </div>
  179. <img src="/images/chambre2.jpeg" class="w-100" alt="Bedroom 2">
  180. </div>
  181. </div>
  182. </div>
  183. <div class="item">
  184. <div class="relative">
  185. <div class="overflow-hidden text-light">
  186. <div class="abs h-100 start-3 z-2 p-4">
  187. <h3 style="color:white;">Bedroom 3</h3>
  188. </div>
  189. <img src="/images/chambre3.jpeg" class="w-100" alt="Bedroom 3">
  190. </div>
  191. </div>
  192. </div>
  193. <div class="item">
  194. <div class="relative">
  195. <div class="overflow-hidden text-light">
  196. <div class="abs h-100 start-4 z-2 p-4">
  197. <h3 style="color:white;">Kitchen</h3>
  198. </div>
  199. <img src="/images/cuisine.jpeg" class="w-100" alt="Kitchen">
  200. </div>
  201. </div>
  202. </div>
  203. <div class="item">
  204. <div class="relative">
  205. <div class="overflow-hidden text-light">
  206. <div class="abs h-100 start-5 z-2 p-4">
  207. <h3 style="color:white;">Bathroom</h3>
  208. </div>
  209. <img src="/images/salledebain.jpeg" class="w-100" alt="Bathroom 1">
  210. </div>
  211. </div>
  212. </div>
  213. <div class="item">
  214. <div class="relative">
  215. <div class="overflow-hidden text-light">
  216. <div class="abs h-100 start-6 z-2 p-4">
  217. <h3 style="color:white;">Bathroom 2</h3>
  218. </div>
  219. <img src="/images/salledebain2.jpeg" class="w-100" alt="Bathroom 2">
  220. </div>
  221. </div>
  222. </div>
  223. </div>
  224. </div>
  225. </div>
  226. </div>
  227. </div>
  228. </section>
  229. <section id="services" class="overlay-dark-1">
  230. <div class="container">
  231. <div class="row g-4 justify-content-between">
  232. <div class="col-lg-5 relative z-3">
  233. <div class="me-lg-3">
  234. <div class="subtitle wow fadeInUp" data-wow-delay=".0s">Your stay in Strasbourg</div>
  235. <h2 class="wow fadeInUp" data-wow-delay=".2s">Rates and services</h2>
  236. <p style="color:#212121; font-size:18px;">An exceptional suite in the heart of Strasbourg, with optionnal dedicated concierge service to assist you throughout your stay.</p>
  237. <p style="color:#212121; font-size:18px;">Minimum booking of two nights.</p>
  238. <a href="#reservation" class="btn-main" style="color:white;">Booking</a>
  239. </div>
  240. </div>
  241. <div class="col-lg-6" style="color:black;">
  242. <div class="spacer-single spacer-double"></div>
  243. <div class="row">
  244. <div class="col-md-6 wow fadeInUp" data-wow-delay=".2s">
  245. {#
  246. <h5 class=" mb-3">Peak Season</h5>
  247. <p class="fs-500"><small>June 1st to September 30th • November 25th to January 5th</small></p>
  248. <ul class="ul-check fs-500">
  249. <li>€960 per night</li>
  250. <li>10% discount for bookings of 7 nights and up</li>
  251. </ul>
  252. <h5 class="mb-3 mt-4">Off-peak Season</h5>
  253. #}
  254. <ul class="ul-check fs-500">
  255. <li>2 guests: €350 per night</li>
  256. <li>4 guests: €690 per night</li>
  257. <li>from 6 guests and up: €890 per night</li>
  258. <li>10% discount for bookings of 7 nights and up</li>
  259. </ul>
  260. </div>
  261. <div class="col-md-6 wow fadeInUp" data-wow-delay=".4s">
  262. <h5 class="mb-3">Optional services</h5>
  263. <ul class="ul-check fs-500">
  264. <li>One parking space: €24/day or €150/week</li>
  265. <li>Extra cleaning during your stay : 60 euros</li>
  266. <li>Other Extras : Children's workshop, baby amenities, dog policy on request (other pets are unfortunately not allowed in the appartement), Decoration for special occasions, breakfast, Alsatian delicacies, etc</li>
  267. </ul>
  268. <div class="mt-4">
  269. <p class="fs-500">
  270. <strong>On site assistance</strong> <br />
  271. <small>Tuesday to Saturday • 10am-6:45pm</small>
  272. </p>
  273. <p class="fs-500">
  274. <strong>Private concierge subject to availability</strong><br>
  275. <small>Quotation on request</small>
  276. </p>
  277. </div>
  278. </div>
  279. </div>
  280. </div>
  281. </div>
  282. </div>
  283. </section>
  284. <section id="section-gallery" class="relative">
  285. <div class="container relative z-2" id="photos">
  286. <div class="row g-4 gx-5 justify-content-center">
  287. <div class="col-lg-6 text-center">
  288. <h2 class="wow fadeInUp" data-wow-delay=".2s">Apartment Gallery</h2>
  289. <p class="wow fadeInUp" data-wow-delay=".3s" style="color:#212121;">Explore our curated images to discover the residence’s various spaces — from the bedrooms and living area to the kitchen, bathroom, and outdoor surroundings.</p>
  290. </div>
  291. </div>
  292. <div class="row">
  293. <div class="col-md-12 text-center">
  294. <ul id="filters" class="wow fadeInUp" data-wow-delay="0s">
  295. <li><a href="#" data-filter="*" class="selected" style="color:#212121;">Show All</a></li>
  296. <li><a href="#" data-filter=".chambre" style="color:#212121;">Bedrooms</a></li>
  297. <li><a href="#" data-filter=".salon" style="color:#212121;">Living Room</a></li>
  298. <li><a href="#" data-filter=".cuisine" style="color:#212121;">Kitchen</a></li>
  299. <li><a href="#" data-filter=".salledebain" style="color:#212121;">Bathroom</a></li>
  300. <li><a href="#" data-filter=".exterieur" style="color:#212121;">Outdoor surroundings</a></li>
  301. </ul>
  302. </div>
  303. </div>
  304. <div id="gallery" class="row g-3 wow fadeInUp" data-wow-delay=".3s">
  305. <div class="col-md-3 col-sm-6 col-12 item chambre">
  306. <a href="images/chambre1.jpeg" class="image-popup d-block hover">
  307. <div class="relative overflow-hidden">
  308. <div class="absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3">
  309. View
  310. </div>
  311. <div class="absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2"></div>
  312. <img src="images/chambre1.jpeg" class="w-100 hover-scale-1-2" alt="Bedroom">
  313. </div>
  314. </a>
  315. </div>
  316. <div class="col-md-3 col-sm-6 col-12 item chambre">
  317. <a href="images/chambre2.jpeg" class="image-popup d-block hover">
  318. <div class="relative overflow-hidden">
  319. <div class="absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3">
  320. View
  321. </div>
  322. <div class="absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2"></div>
  323. <img src="images/chambre2.jpeg" class="w-100 hover-scale-1-2" alt="Bedroom 2">
  324. </div>
  325. </a>
  326. </div>
  327. <div class="col-md-3 col-sm-6 col-12 item chambre">
  328. <a href="images/chambre3.jpeg" class="image-popup d-block hover">
  329. <div class="relative overflow-hidden">
  330. <div class="absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3">
  331. View
  332. </div>
  333. <div class="absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2"></div>
  334. <img src="images/chambre3.jpeg" class="w-100 hover-scale-1-2" alt="Bedroom 3">
  335. </div>
  336. </a>
  337. </div>
  338. <div class="col-md-3 col-sm-6 col-12 item salon">
  339. <a href="images/salon.jpeg" class="image-popup d-block hover">
  340. <div class="relative overflow-hidden">
  341. <div class="absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3">
  342. View
  343. </div>
  344. <div class="absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2"></div>
  345. <img src="images/salon.jpeg" class="w-100 hover-scale-1-2" alt="Living Room">
  346. </div>
  347. </a>
  348. </div>
  349. <div class="col-md-3 col-sm-6 col-12 item salon">
  350. <a href="images/salon2.jpeg" class="image-popup d-block hover">
  351. <div class="relative overflow-hidden">
  352. <div class="absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3">
  353. View
  354. </div>
  355. <div class="absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2"></div>
  356. <img src="images/salon2.jpeg" class="w-100 hover-scale-1-2" alt="Living Room 2">
  357. </div>
  358. </a>
  359. </div>
  360. <div class="col-md-3 col-sm-6 col-12 item salon">
  361. <a href="images/salon3.jpeg" class="image-popup d-block hover">
  362. <div class="relative overflow-hidden">
  363. <div class="absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3">
  364. View
  365. </div>
  366. <div class="absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2"></div>
  367. <img src="images/salon3.jpeg" class="w-100 hover-scale-1-2" alt="Living Room 3">
  368. </div>
  369. </a>
  370. </div>
  371. <div class="col-md-3 col-sm-6 col-12 item salon">
  372. <a href="images/salon4.jpeg" class="image-popup d-block hover">
  373. <div class="relative overflow-hidden">
  374. <div class="absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3">
  375. View
  376. </div>
  377. <div class="absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2"></div>
  378. <img src="images/salon4.jpeg" class="w-100 hover-scale-1-2" alt="Living Room 4">
  379. </div>
  380. </a>
  381. </div>
  382. <div class="col-md-3 col-sm-6 col-12 item salon">
  383. <a href="images/salon5.jpeg" class="image-popup d-block hover">
  384. <div class="relative overflow-hidden">
  385. <div class="absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3">
  386. View
  387. </div>
  388. <div class="absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2"></div>
  389. <img src="images/salon5.jpeg" class="w-100 hover-scale-1-2" alt="Living Room 5">
  390. </div>
  391. </a>
  392. </div>
  393. <div class="col-md-3 col-sm-6 col-12 item cuisine">
  394. <a href="images/cuisine.jpeg" class="image-popup d-block hover">
  395. <div class="relative overflow-hidden">
  396. <div class="absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3">
  397. View
  398. </div>
  399. <div class="absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2"></div>
  400. <img src="images/cuisine.jpeg" class="w-100 hover-scale-1-2" alt="Kitchen">
  401. </div>
  402. </a>
  403. </div>
  404. <div class="col-md-3 col-sm-6 col-12 item salledebain">
  405. <a href="images/salledebain.jpeg" class="image-popup d-block hover">
  406. <div class="relative overflow-hidden">
  407. <div class="absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3">
  408. View
  409. </div>
  410. <div class="absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2"></div>
  411. <img src="images/salledebain.jpeg" class="w-100 hover-scale-1-2" alt="Bathroom">
  412. </div>
  413. </a>
  414. </div>
  415. <div class="col-md-3 col-sm-6 col-12 item salledebain">
  416. <a href="images/salledebain2.jpeg" class="image-popup d-block hover">
  417. <div class="relative overflow-hidden">
  418. <div class="absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3">
  419. View
  420. </div>
  421. <div class="absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2"></div>
  422. <img src="images/salledebain2.jpeg" class="w-100 hover-scale-1-2" alt="Bathroom 2">
  423. </div>
  424. </a>
  425. </div>
  426. <div class="col-md-3 col-sm-6 col-12 item exterieur">
  427. <a href="images/exterieur.jpeg" class="image-popup d-block hover">
  428. <div class="relative overflow-hidden">
  429. <div class="absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3">
  430. View
  431. </div>
  432. <div class="absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2"></div>
  433. <img src="images/exterieur.jpeg" class="w-100 hover-scale-1-2" alt="Exterior">
  434. </div>
  435. </a>
  436. </div>
  437. </div>
  438. </div>
  439. </section>
  440. <section id="reservation" class="text-light">
  441. <div class="container">
  442. <div class="row g-4 justify-content-center">
  443. <div class="col-lg-6 text-center">
  444. <h2 class="wow fadeInUp" data-wow-delay=".2s">Book your stay</h2>
  445. </div>
  446. </div>
  447. <div class="row g-4 justify-content-center">
  448. <div class="col-md-6">
  449. {{ form_start(form) }}
  450. <div class="row g-4">
  451. <div class="col-md-12">
  452. <div class="calendar-container" style="height:300px;">
  453. <input type="text" id="date_range_picker">
  454. </div>
  455. </div>
  456. <div class="col-md-3">
  457. <label style="color:#212121;">Guests</label>
  458. {{ form_widget(form.persons) }}
  459. </div>
  460. <div class="col-md-3">
  461. <label style="color:#212121;">Arrival</label> <br />
  462. </strong> <span id="info-start" style="color:#212121;">-</span>
  463. </div>
  464. <div class="col-md-3">
  465. <label style="color:#212121;">Departure</label> <br />
  466. <span id="info-end" style="color:#212121;">-</span>
  467. </div>
  468. <div class="col-md-3">
  469. <label style="color:#212121;">Nights</label> <br />
  470. <span id="info-nights" style="color:#212121;">-</span>
  471. </div>
  472. <div class="col-md-12" style="font-size:20px;">
  473. <div id="results"></div>
  474. </div>
  475. <div class="col-md-6">
  476. <label style="color:#212121;">Last name</label>
  477. {{ form_widget(form.lastname) }}
  478. </div>
  479. <div class="col-md-6">
  480. <label style="color:#212121;">First name</label>
  481. {{ form_widget(form.name) }}
  482. </div>
  483. <div class="col-md-12">
  484. <label style="color:#212121;">Email address</label>
  485. {{ form_widget(form.email) }}
  486. </div>
  487. <div class="col-md-12">
  488. <label style="color:#212121;">Message</label>
  489. {{ form_widget(form.message) }}
  490. </div>
  491. <div class="col-md-12">
  492. <div class="text-center" style="color:#212121;">
  493. <input type="checkbox" id="acceptCGV" /> I accept the <a href="/terms" target="_blank" style="text-decoration:underline; color:#212121;">terms and conditions of sale</a>
  494. </div>
  495. </div>
  496. <div class="col-md-12">
  497. <div class="text-center">
  498. <button type="submit" name="submit" value="1" class="btn-main" style="color:white;">Send booking request</button>
  499. </div>
  500. </div>
  501. </div>
  502. {{ form_widget(form.start) }}
  503. {{ form_widget(form.end) }}
  504. {{ form_rest(form) }}
  505. {{ form_end(form) }}
  506. </div>
  507. </div>
  508. </div>
  509. </section>
  510. <section id="faq" class="text-light">
  511. <div class="container">
  512. <div class="row g-4 justify-content-center">
  513. <div class="col-lg-6 text-center">
  514. <h2 class="wow fadeInUp" data-wow-delay=".2s">FAQ</h2>
  515. </div>
  516. </div>
  517. <div class="row g-4 justify-content-center">
  518. <div class="col-lg-6 text-left" style="color:black !important;">
  519. <h3 style="margin-top:7px;">How can I book the accommodation?</h3>
  520. <div>You can book directly on our website and soon via partner platforms. Secure payment immediately confirms your reservation.</div>
  521. <h3 style="margin-top:7px;">What are the check-in and check-out times?</h3>
  522. <div>
  523. <ul>
  524. <li>Check-in: from 3:00 PM</li>
  525. <li>Check-out: before 11:00 AM</li>
  526. </ul>
  527. </div>
  528. <h3 style="margin-top:7px;">Is the accommodation fully equipped?</h3>
  529. <div> Yes, the apartment is fully furnished and equipped: kitchen, bedding, towels, appliances, Wi-Fi, and more.</div>
  530. <h3 style="margin-top:7px;">Is parking available?</h3>
  531. <div>Yes, private parking is available as an option at €24 per 24 hours or €150 per week (7 nights).</div>
  532. <h3 style="margin-top:7px;">Is the accommodation suitable for children?</h3>
  533. <div>Yes, we offer some baby amenities (baby cot, high chair, child-friendly tableware) upon request.</div>
  534. <h3 style="margin-top:7px;"> Are pets allowed?</h3>
  535. <div> Please contact us before booking if you wish to bring a pet. Only dogs are accepted, and prior approval is required.</div>
  536. <h3 style="margin-top:7px;">Can I cancel or modify my reservation?</h3>
  537. <div>Yes, our cancellation policy is provided at the time of booking:
  538. <ul>
  539. <li>85% refund if canceled more than 1 month before arrival</li>
  540. <li>50% refund if canceled between 1 month and 15 days before arrival</li>
  541. <li>No refund if canceled less than 15 days before arrival</li>
  542. </ul>
  543. </div>
  544. <h3 style="margin-top:7px;">Is the accommodation accessible by public transport?</h3>
  545. <div>Yes, major transport options are nearby. The tram station “Langstross, Grand’rue” is less than 100 meters from the apartment, and Strasbourg train station is a 10-minute walk.</div>
  546. <h3 style="margin-top:7px;">Are there shops or restaurants nearby?</h3>
  547. <div>Yes, you’ll find supermarkets, cafés, restaurants, and tourist activities right at the foot of the building.</div>
  548. <h3 style="margin-top:7px;"> What should I do if there’s a problem during my stay?</h3>
  549. <div> We are available 24/7 by email for emergencies or questions about the apartment. You can also call us from 9:00 AM to 8:00 PM at +33 7 61 05 82 43, and we are available on-site on the ground floor of the building from Tuesday to Saturday, 10:00 AM to 6:45 PM.
  550. </div>
  551. </div>
  552. </div>
  553. </div>
  554. </section>
  555. {% endblock body %}
  556. {% block footerjs %}
  557. <script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
  558. <script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/en.js"></script>
  559. <script>
  560. function updateSimulation() {
  561. var start = $("#reservation_form_start").val();
  562. var end = $("#reservation_form_end").val();
  563. var persons = $("#reservation_form_persons").val();
  564. if (start && end && persons) {
  565. $("#results").html('<div class="loading">Calculating...</div>');
  566. $.post(
  567. Routing.generate('simulation_pricing'),
  568. {'start': start, 'end': end, 'persons': persons}
  569. )
  570. .done(function(data) {
  571. $("#results").html(data);
  572. })
  573. .fail(function() {
  574. $("#results").html('<div class="error">Calculation error</div>');
  575. });
  576. } else {
  577. $("#results").html('');
  578. }
  579. }
  580. // Écoute les changements sur le nombre de personnes
  581. $("#reservation_form_persons").change(updateSimulation);
  582. $(document).ready(function() {
  583. // Désactive le bouton au chargement de la page
  584. $('button[type="submit"]').prop('disabled', true);
  585. // Écoute les changements sur la checkbox
  586. $('#acceptCGV').change(function() {
  587. if($(this).is(':checked')) {
  588. $('button[type="submit"]').prop('disabled', false);
  589. } else {
  590. $('button[type="submit"]').prop('disabled', true);
  591. }
  592. });
  593. });
  594. </script>
  595. <script>
  596. $(document).ready(function() {
  597. let bookedRanges = [];
  598. $.ajax({
  599. url: '{{ env('WEBHOOK_CALENDAR_AVAILABILITY') }}',
  600. method: 'POST',
  601. contentType: 'application/json',
  602. data: ''
  603. })
  604. .done(function(data) {
  605. bookedRanges = data.bookings || [];
  606. console.log('✅ Créneaux chargés:', bookedRanges);
  607. initDatePicker();
  608. })
  609. .fail(function(error) {
  610. console.error('❌ Erreur:', error);
  611. initDatePicker();
  612. });
  613. // 🔧 FONCTION POUR CRÉER UNE DATE LOCALE SANS DÉCALAGE UTC
  614. function parseLocalDate(dateStr) {
  615. const [year, month, day] = dateStr.split('-').map(Number);
  616. return new Date(year, month - 1, day);
  617. }
  618. const isMobile = window.innerWidth <= 900;
  619. function initDatePicker() {
  620. flatpickr("#date_range_picker", {
  621. inline: true,
  622. mode: "range",
  623. locale: "fr",
  624. minDate: new Date(new Date().setDate(new Date().getDate() + 1)),
  625. dateFormat: "Y-m-d",
  626. showMonths: isMobile ? 1 : 2,
  627. disable: [
  628. function(date) {
  629. const checkDate = new Date(date);
  630. checkDate.setHours(0, 0, 0, 0);
  631. return bookedRanges.some(range => {
  632. const start = parseLocalDate(range.start_date);
  633. const end = parseLocalDate(range.end_date);
  634. return checkDate >= start && checkDate <= end;
  635. });
  636. }
  637. ],
  638. onChange: function(selectedDates, dateStr, instance) {
  639. console.log('📅 Dates sélectionnées:', selectedDates.length);
  640. if (selectedDates.length === 2) {
  641. const start = selectedDates[0];
  642. const end = selectedDates[1];
  643. if (isRangeAvailable(start, end)) {
  644. // ✅ Met à jour avec jQuery ET déclenche l'événement change
  645. $('#reservation_form_start').val(formatDate(start)).trigger('change');
  646. $('#reservation_form_end').val(formatDate(end)).trigger('change');
  647. console.log('✅ Champs mis à jour:',
  648. $('#reservation_form_start').val(),
  649. '→',
  650. $('#reservation_form_end').val()
  651. );
  652. updateSelectedInfo(start, end);
  653. // ✅ Force la simulation
  654. updateSimulation();
  655. } else {
  656. alert('⚠️ Cette période contient des dates déjà réservées.\nVeuillez choisir une autre période.');
  657. instance.clear();
  658. clearSymfonyFields();
  659. hideSelectedInfo();
  660. $("#results").html('');
  661. }
  662. } else {
  663. clearSymfonyFields();
  664. hideSelectedInfo();
  665. $("#results").html('');
  666. }
  667. },
  668. onDayCreate: function(dObj, dStr, fp, dayElem) {
  669. const date = new Date(dayElem.dateObj);
  670. date.setHours(0, 0, 0, 0);
  671. const isBooked = bookedRanges.some(range => {
  672. const start = parseLocalDate(range.start_date);
  673. const end = parseLocalDate(range.end_date);
  674. return date >= start && date <= end;
  675. });
  676. if (isBooked) {
  677. dayElem.classList.add('booked');
  678. dayElem.title = 'Date indisponible (réservée)';
  679. } else if (date >= new Date()) {
  680. dayElem.classList.add('available');
  681. dayElem.title = 'Date disponible';
  682. }
  683. }
  684. });
  685. }
  686. function isRangeAvailable(startDate, endDate) {
  687. let currentDate = new Date(startDate);
  688. currentDate.setHours(0, 0, 0, 0);
  689. const endCheck = new Date(endDate);
  690. endCheck.setHours(0, 0, 0, 0);
  691. while (currentDate <= endCheck) {
  692. const isBooked = bookedRanges.some(range => {
  693. const start = parseLocalDate(range.start_date);
  694. const end = parseLocalDate(range.end_date);
  695. return currentDate >= start && currentDate <= end;
  696. });
  697. if (isBooked) return false;
  698. currentDate.setDate(currentDate.getDate() + 1);
  699. }
  700. return true;
  701. }
  702. function updateSelectedInfo(start, end) {
  703. const nights = Math.ceil((end - start) / (1000 * 60 * 60 * 24));
  704. $('#info-start').text(start.toLocaleDateString('fr-FR'));
  705. $('#info-end').text(end.toLocaleDateString('fr-FR'));
  706. $('#info-nights').text(`${nights} nuit${nights > 1 ? 's' : ''}`);
  707. $('#selected-dates-info').addClass('active');
  708. }
  709. function hideSelectedInfo() {
  710. $('#selected-dates-info').removeClass('active');
  711. }
  712. function clearSymfonyFields() {
  713. $('#reservation_form_start').val('');
  714. $('#reservation_form_end').val('');
  715. }
  716. function formatDate(date) {
  717. const year = date.getFullYear();
  718. const month = String(date.getMonth() + 1).padStart(2, '0');
  719. const day = String(date.getDate()).padStart(2, '0');
  720. return `${year}-${month}-${day}`;
  721. }
  722. });
  723. </script>
  724. {% endblock footerjs %}
  725. {% block css %}
  726. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
  727. <style>
  728. .calendar-container {
  729. margin: 20px 0;
  730. width: 100%;
  731. overflow: hidden;
  732. }
  733. /* Calendrier inline (toujours visible) */
  734. #date_range_picker {
  735. display: none; /* Le champ input est caché, on affiche juste le calendrier */
  736. }
  737. .flatpickr-calendar.inline {
  738. margin: 0 auto;
  739. box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  740. border-radius: 8px;
  741. max-width: 100%;
  742. }
  743. .flatpickr-day.booked {
  744. background-color: #ff4444 !important;
  745. color: white !important;
  746. cursor: not-allowed !important;
  747. position: relative;
  748. }
  749. .flatpickr-day.booked::after {
  750. content: "✕";
  751. position: absolute;
  752. top: 50%;
  753. left: 50%;
  754. transform: translate(-50%, -50%);
  755. font-size: 20px;
  756. font-weight: bold;
  757. }
  758. .flatpickr-day.booked:hover {
  759. background-color: #ff0000 !important;
  760. }
  761. .flatpickr-day.available:hover {
  762. background-color: #28a745;
  763. color: white;
  764. }
  765. /* Adaptations Mobile */
  766. @media (max-width: 768px) {
  767. .calendar-container {
  768. margin: 10px 0;
  769. padding: 0 10px;
  770. }
  771. .flatpickr-calendar.inline {
  772. width: 100% !important;
  773. max-width: 100% !important;
  774. }
  775. .flatpickr-months {
  776. padding: 8px 10px;
  777. }
  778. .flatpickr-days {
  779. width: 100% !important;
  780. }
  781. .dayContainer {
  782. width: 100% !important;
  783. min-width: 100% !important;
  784. max-width: 100% !important;
  785. }
  786. .flatpickr-day {
  787. height: 40px !important;
  788. line-height: 40px !important;
  789. flex-basis: 14.2857% !important;
  790. max-width: 14.2857% !important;
  791. }
  792. }
  793. </style>
  794. {% endblock css %}