Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 

322 рядки
11 KiB

  1. <template>
  2. <div id="okt-28">
  3. <div class="selection-text">{{selectionText}}</div>
  4. <div class="otf" id="teilnehmen">
  5. <!-- <h1 style="padding-top:1em">Party</h1> -->
  6. <div class="form-wrapper">
  7. </div>
  8. <template v-if="status && status.open">
  9. <form v-if="!success" class="input-form" @submit.prevent="onClickTheButton" style="margin-top: 5vh">
  10. <div class="input-headline">reservation</div>
  11. <input class="input-text" v-model="anzeigename" placeholder="nickname (public)" size="1" />
  12. <input class="input-text" v-model="name" placeholder="real name" size="1" />
  13. <input class="input-text" v-model="email" placeholder="email" size="1" />
  14. <!-- <label class="input-cb" for="newsletter">
  15. <input name="newsletter" id="newsletter" type="checkbox" class="input-checkbox" />stay informed
  16. </label> -->
  17. <input class="input-btn" type="submit" :value="(sending ? 'sending ...' : 'reserve')" :disabled="(sending ? true : false)" />
  18. <div v-if="error">
  19. oh no something went wrong!<br>
  20. {{errorReason.detail}}
  21. </div>
  22. </form>
  23. <div v-if="showHelp" style="margin-bottom: 1em;">
  24. *robot voice* give us your data for the reservation!
  25. </div>
  26. <div v-if="success">
  27. <p style="font-size: 6vw">
  28. Thanks!
  29. </p>
  30. <button @click="resetForm" class="input-btn">✓ see you there!</button>
  31. </div>
  32. </template>
  33. <template v-if="status && !status.open">
  34. {{status.reason}}
  35. </template>
  36. <vue-word-cloud class="wordcloud" style="height: 70vh; width: 80%" :words="words"
  37. :color="() => { return nameColors[Math.floor(Math.random() * nameColors.length)] }"
  38. font-family="'JetBrains Mono'" />
  39. </div>
  40. <!-- <div class="details" ref="details">
  41. TEXT!
  42. </div> -->
  43. <div
  44. v-if="canShare"
  45. @click="share"
  46. style="cursor: pointer; margin-top: 5em;"
  47. >
  48. <svg class="share" fill="#fff" version="1.1" viewBox="0 0 350.22 180.68" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-622.81 -392.3)"><path d="m659.49 392.3v16.427h-16.299v19.182h-20.385v50.605h21.942v18.918h17.175v19.63h55.254l-37.054 55.916h30.57l37.054-55.916h190.84v-16.06h15.991v-18.048h18.443v-50.605h-19.999v-20.05h-16.867v-19.998zm6.9343 23.419h263.37v19.998h19.999v41.866h-18.443v16.06h-263.37v-19.63h-21.942v-41.866h20.385z" stroke-width="0" style="paint-order:stroke fill markers"/><g transform="matrix(.42673 0 0 .42673 457.43 276.68)" aria-label="WILLTEILEN"><path d="m590.71 451.07h-21.891l-6.5625-29.859q-0.46875-1.875-1.5-7.4531-0.98437-5.5781-1.4531-9.3281-0.375 3.0469-1.2188 7.5938-0.84375 4.5-1.6875 8.2969-0.79688 3.7969-6.7969 30.75h-21.891l-16.969-68.531h17.859l7.4531 34.359q2.5312 11.391 3.4688 18.141 0.60937-4.7812 2.1562-12.984 1.5938-8.2031 2.9531-13.594l6.0469-25.922h17.156l5.8594 25.922q1.5 6.2344 3.0469 14.391 1.5469 8.1562 2.0625 12.188 0.60937-5.2031 3.3281-18.047l7.5938-34.453h17.859z"/><path d="m616.44 451.07v-68.531h18.609v68.531z"/><path d="m649.86 451.07v-68.531h18.516v53.578h26.391v14.953z"/><path d="m705.74 451.07v-68.531h18.516v53.578h26.391v14.953z"/><path d="m791.85 451.07h-18.516v-53.391h-16.734v-15.141h51.938v15.141h-16.688z"/><path d="m859.02 451.07h-40.688v-68.531h40.688v14.859h-22.172v10.781h20.531v14.859h-20.531v12.938h22.172z"/><path d="m871.02 451.07v-68.531h18.609v68.531z"/><path d="m904.44 451.07v-68.531h18.516v53.578h26.391v14.953z"/><path d="m1001 451.07h-40.687v-68.531h40.687v14.859h-22.172v10.781h20.531v14.859h-20.531v12.938h22.172z"/><path d="m1078.3 451.07h-24.281l-25.031-48.281h-0.4218q0.8906 11.391 0.8906 17.391v30.891h-16.406v-68.531h24.188l24.938 47.625h0.2813q-0.6563-10.359-0.6563-16.641v-30.984h16.5z"/></g></g></svg>
  49. </div>
  50. <a
  51. v-else
  52. href="mailto:?subject=invitation%20-%20oct%2028&body=%40SWK%0D%0Areservation%20required%3A%20reservation.ck.si "
  53. style="cursor: pointer; margin-top: 5em;"
  54. >
  55. <svg class="share" fill="#fff" version="1.1" viewBox="0 0 350.22 180.68" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-622.81 -392.3)"><path d="m659.49 392.3v16.427h-16.299v19.182h-20.385v50.605h21.942v18.918h17.175v19.63h55.254l-37.054 55.916h30.57l37.054-55.916h190.84v-16.06h15.991v-18.048h18.443v-50.605h-19.999v-20.05h-16.867v-19.998zm6.9343 23.419h263.37v19.998h19.999v41.866h-18.443v16.06h-263.37v-19.63h-21.942v-41.866h20.385z" stroke-width="0" style="paint-order:stroke fill markers"/><g transform="matrix(.42673 0 0 .42673 457.43 276.68)" aria-label="WILLTEILEN"><path d="m590.71 451.07h-21.891l-6.5625-29.859q-0.46875-1.875-1.5-7.4531-0.98437-5.5781-1.4531-9.3281-0.375 3.0469-1.2188 7.5938-0.84375 4.5-1.6875 8.2969-0.79688 3.7969-6.7969 30.75h-21.891l-16.969-68.531h17.859l7.4531 34.359q2.5312 11.391 3.4688 18.141 0.60937-4.7812 2.1562-12.984 1.5938-8.2031 2.9531-13.594l6.0469-25.922h17.156l5.8594 25.922q1.5 6.2344 3.0469 14.391 1.5469 8.1562 2.0625 12.188 0.60937-5.2031 3.3281-18.047l7.5938-34.453h17.859z"/><path d="m616.44 451.07v-68.531h18.609v68.531z"/><path d="m649.86 451.07v-68.531h18.516v53.578h26.391v14.953z"/><path d="m705.74 451.07v-68.531h18.516v53.578h26.391v14.953z"/><path d="m791.85 451.07h-18.516v-53.391h-16.734v-15.141h51.938v15.141h-16.688z"/><path d="m859.02 451.07h-40.688v-68.531h40.688v14.859h-22.172v10.781h20.531v14.859h-20.531v12.938h22.172z"/><path d="m871.02 451.07v-68.531h18.609v68.531z"/><path d="m904.44 451.07v-68.531h18.516v53.578h26.391v14.953z"/><path d="m1001 451.07h-40.687v-68.531h40.687v14.859h-22.172v10.781h20.531v14.859h-20.531v12.938h22.172z"/><path d="m1078.3 451.07h-24.281l-25.031-48.281h-0.4218q0.8906 11.391 0.8906 17.391v30.891h-16.406v-68.531h24.188l24.938 47.625h0.2813q-0.6563-10.359-0.6563-16.641v-30.984h16.5z"/></g></g></svg>
  56. </a>
  57. </div>
  58. </template>
  59. <script>
  60. import VueWordCloud from 'vuewordcloud';
  61. export default {
  62. name: 'Invitation',
  63. data() {
  64. return {
  65. anzeigename: '',
  66. name: '',
  67. email: '',
  68. status: null,
  69. newsletter: false,
  70. guests: [],
  71. sending: false,
  72. showHelp: false,
  73. selection: null,
  74. selectionText: null,
  75. success: false,
  76. error: false,
  77. errorReason: null,
  78. }
  79. },
  80. components: {
  81. [VueWordCloud.name]: VueWordCloud,
  82. },
  83. computed: {
  84. nameColors() {
  85. return ['DeepPink', 'Crimson', 'Blue', 'BlueViolet', 'Fuchsia', 'Navy', 'Indigo']
  86. },
  87. words() {
  88. const names = this.guests.map(guest => {
  89. return guest.anzeigename
  90. })
  91. const nameLengths = names.map(name => {
  92. return name.length
  93. })
  94. const maxNameLength = Math.max(...nameLengths)
  95. return this.guests.map(guest => {
  96. const nameLength = guest.anzeigename.length
  97. let size = maxNameLength - nameLength + 12
  98. return [` ${guest.anzeigename} `, size]
  99. })
  100. },
  101. // guestlist() {
  102. // return this.guests.map( (g) => {
  103. // g.name = g.anzeigename
  104. // return g
  105. // })
  106. // }
  107. canShare () {
  108. return !!navigator.share
  109. }
  110. },
  111. methods: {
  112. async fetchStatus() {
  113. const response = await fetch(`${process.env.VUE_APP_API_URL}status`)
  114. const data = await response.json()
  115. this.status = data
  116. },
  117. async fetchGuests() {
  118. const response = await fetch(`${process.env.VUE_APP_API_URL}guest`)
  119. const data = await response.json()
  120. this.guests = data
  121. },
  122. async onClickTheButton() {
  123. if (this.name.length == 0) {
  124. this.showHelp = true
  125. return false
  126. }
  127. this.showHelp = false
  128. this.sending = true
  129. let data = {
  130. anzeigename: this.anzeigename,
  131. name: this.name,
  132. email: this.email,
  133. newsletter: false,
  134. }
  135. const response = await fetch(
  136. `${process.env.VUE_APP_API_URL}guest`, {
  137. method: 'POST',
  138. headers: {
  139. 'Content-Type': 'application/json',
  140. },
  141. body: JSON.stringify(data),
  142. }
  143. )
  144. if (response.status === 200) {
  145. this.anzeigename = ''
  146. this.name = ''
  147. this.email = ''
  148. this.success = true
  149. this.fetchGuests()
  150. } else {
  151. this.success = false
  152. this.fetchGuests()
  153. this.error = true
  154. this.errorReason = await response.json()
  155. }
  156. this.sending = false
  157. return false
  158. },
  159. resetForm () {
  160. this.anzeigename = ''
  161. this.name = ''
  162. this.email = ''
  163. this.success = false
  164. },
  165. async share () {
  166. location.href = "#";
  167. try {
  168. await navigator.share({ url:"https://reservation.ck.si/" })
  169. } catch (err) {
  170. console.log(`Error: ${err}`)
  171. }
  172. }
  173. },
  174. mounted() {
  175. this.fetchStatus()
  176. this.fetchGuests()
  177. document.addEventListener('selectionchange', () => {
  178. this.selection = document.getSelection()
  179. // console.log(this.selection)
  180. if (this.selection) {
  181. this.selectionText = this.selection.toString()
  182. }
  183. });
  184. // this.$refs.details.$el
  185. },
  186. }
  187. </script>
  188. <style>
  189. body {
  190. font-family: 'JetBrains Mono', monospace;
  191. background-color: rgb(0, 0, 0);
  192. background-image: url('bg.gif');
  193. background-size: cover;
  194. background-position: center center;
  195. background-attachment: fixed;
  196. color: rgb(251, 251, 251);
  197. margin: 0 0 100px;
  198. }
  199. .otf {
  200. width: 100%;
  201. /* background-color: rgb(167, 204, 247); */
  202. /* background-image: url('bg.gif'); */
  203. background-size: cover;
  204. display: flex;
  205. flex-direction: column;
  206. align-items: center;
  207. min-height: 100vh;
  208. position: relative;
  209. }
  210. .input-headline {
  211. color: rgb(255, 255, 255);
  212. font-size: 2.8vh;
  213. margin-bottom: .8vh;
  214. }
  215. .input-form {
  216. display: flex;
  217. flex-direction: column;
  218. width: 100%;
  219. max-width: 800px;
  220. mix-blend-mode: exclusion;
  221. margin-top: 4vh;
  222. z-index: 9;
  223. position: relative;
  224. }
  225. .input-text,
  226. .input-btn,
  227. .input-cb {
  228. color: #000;
  229. background: #fff;
  230. font-size: 2.8vh;
  231. font-family: 'JetBrains Mono', monospace;
  232. border: 0;
  233. padding: .5em 1em;
  234. line-height: 1.4;
  235. max-width: 100%;
  236. }
  237. .input-btn {
  238. color: #fff;
  239. background-color: #1e3a8e;
  240. border-top: 2px solid rgb(0, 0, 0);
  241. cursor: pointer;
  242. }
  243. .input-btn:hover {
  244. color: #fff;
  245. background: #3260eb;
  246. }
  247. .input-checkbox {
  248. margin: 0 1em 0 0;
  249. }
  250. @media screen and (max-width: 1000px) {
  251. .form-wrapper {
  252. margin-top: 4em;
  253. }
  254. .input-text,
  255. .input-btn {
  256. width: 100%;
  257. max-width: 100%;
  258. min-width: 0;
  259. text-align: center;
  260. }
  261. /* .input-form {
  262. position: absolute;
  263. bottom: 0;
  264. display: flex;
  265. flex-direction: column;
  266. } */
  267. }
  268. .input-text {
  269. width: auto;
  270. flex-grow: 1;
  271. }
  272. .details {
  273. color: #fff;
  274. background-color: #000;
  275. font-size: 10vw;
  276. max-width: 80em;
  277. margin: 3% 3% 200px;
  278. padding: 3%;
  279. }
  280. .share {
  281. max-width: 30em;
  282. width: 80%;
  283. mix-blend-mode: soft-light;
  284. }
  285. .share:hover {
  286. mix-blend-mode: difference;
  287. }
  288. .selection-text {
  289. position: fixed;
  290. z-index: 9999;
  291. font-size: 10vh;
  292. line-height: 1em;
  293. pointer-events: none;
  294. color: #ec4b73;
  295. mix-blend-mode: multiply;
  296. top: 10%;
  297. }
  298. </style>