You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

322 regels
7.8 KiB

  1. <template>
  2. <div id="gtblank-init">
  3. debug1: {{debug1}}<br>
  4. debug2: {{debug2}}<br>
  5. status: {{status}}
  6. <!-- <video autoplay muted loop class="video-bg">
  7. <source src="/gt-blank-init-bg.mp4" type="video/mp4">
  8. </video> -->
  9. <div class="selection-text">{{selectionText}}</div>
  10. <div class="otf">
  11. <!-- <h1 style="padding-top:1em">Party</h1> -->
  12. <div class="form-wrapper">
  13. </div>
  14. <template v-if="status && status.open">
  15. <form v-if="!success" class="input-form" @submit.prevent="onClickTheButton" style="margin-top: 5vh">
  16. <div class="input-headline">gtblank-init 2022-11-11 rsvp</div>
  17. <input class="input-text" v-model="anzeigename" placeholder="nickname (public)" size="1" />
  18. <input class="input-text" v-model="name" placeholder="full name (for orga reasons)" size="1" />
  19. <input class="input-text" v-model="email" placeholder="email (for self service)" size="1" />
  20. <input class="input-btn" type="submit" :value="(sending ? 'sending ...' : 'join')" :disabled="(sending ? true : false)" />
  21. <div v-if="error">
  22. oh no something went wrong!<br>
  23. {{errorReason.detail}}
  24. </div>
  25. </form>
  26. <div v-if="showHelp" style="margin-bottom: 1em;">
  27. *robot voice* give us your data for the reservation!
  28. </div>
  29. <div v-if="success">
  30. <p style="font-size: 6vw">
  31. Thanks!
  32. </p>
  33. <button @click="resetForm" class="input-btn">✓ see you there!</button>
  34. </div>
  35. </template>
  36. <template v-if="status && !status.open">
  37. {{status.reason}}
  38. </template>
  39. <vue-word-cloud class="wordcloud" style="height: 70vh; width: 80%" :words="words"
  40. font-family="'JetBrains Mono'" />
  41. <div v-if="status && status.open" class="details" ref="details">
  42. official start 21:00<br>
  43. augasse 2-6, 1090 wien<br>
  44. <small>
  45. alte wu -> enter main entrance -> turn right to "ateliers" <br>
  46. <a href="https://www.openstreetmap.org/?mlat=48.23201&mlon=16.35773#map=19/48.23201/16.35773" target="_blank">location pin @ osm.org</a>
  47. </small>
  48. </div>
  49. </div>
  50. <!-- :color="() => { return nameColors[Math.floor(Math.random() * nameColors.length)] }" -->
  51. </div>
  52. </template>
  53. <script>
  54. import VueWordCloud from 'vuewordcloud';
  55. export default {
  56. name: 'Invitation',
  57. data() {
  58. return {
  59. anzeigename: '',
  60. name: '',
  61. email: '',
  62. status: null,
  63. newsletter: false,
  64. guests: [],
  65. sending: false,
  66. showHelp: false,
  67. selection: null,
  68. selectionText: null,
  69. success: false,
  70. error: false,
  71. errorReason: null,
  72. debug1: null,
  73. debug2: null
  74. }
  75. },
  76. components: {
  77. [VueWordCloud.name]: VueWordCloud,
  78. },
  79. computed: {
  80. nameColors() {
  81. return ['White']
  82. },
  83. words() {
  84. const names = this.guests.map(guest => {
  85. return guest.anzeigename
  86. })
  87. const nameLengths = names.map(name => {
  88. return name.length
  89. })
  90. const maxNameLength = Math.max(...nameLengths)
  91. return this.guests.map(guest => {
  92. const nameLength = guest.anzeigename.length
  93. let size = maxNameLength - nameLength + 12
  94. return [` ${guest.anzeigename} `, size]
  95. })
  96. },
  97. // guestlist() {
  98. // return this.guests.map( (g) => {
  99. // g.name = g.anzeigename
  100. // return g
  101. // })
  102. // }
  103. },
  104. methods: {
  105. async fetchStatus() {
  106. const response = await fetch(`${process.env.VUE_APP_API_URL}status`)
  107. this.debug1 = `${process.env.VUE_APP_API_URL}status`
  108. const data = await response.json()
  109. this.debug2 = data
  110. this.status = data
  111. },
  112. async fetchGuests() {
  113. const response = await fetch(`${process.env.VUE_APP_API_URL}guest`)
  114. const data = await response.json()
  115. this.guests = data
  116. },
  117. async onClickTheButton() {
  118. if (this.name.length == 0) {
  119. this.showHelp = true
  120. return false
  121. }
  122. this.showHelp = false
  123. this.sending = true
  124. let data = {
  125. anzeigename: this.anzeigename,
  126. name: this.name,
  127. email: this.email,
  128. newsletter: false,
  129. }
  130. const response = await fetch(
  131. `${process.env.VUE_APP_API_URL}guest`, {
  132. method: 'POST',
  133. headers: {
  134. 'Content-Type': 'application/json',
  135. },
  136. body: JSON.stringify(data),
  137. }
  138. )
  139. if (response.status === 200) {
  140. this.anzeigename = ''
  141. this.name = ''
  142. this.email = ''
  143. this.success = true
  144. this.fetchGuests()
  145. } else {
  146. this.success = false
  147. this.fetchGuests()
  148. this.error = true
  149. this.errorReason = await response.json()
  150. }
  151. this.sending = false
  152. return false
  153. },
  154. resetForm () {
  155. this.anzeigename = ''
  156. this.name = ''
  157. this.email = ''
  158. this.success = false
  159. },
  160. },
  161. mounted() {
  162. this.fetchStatus()
  163. this.fetchGuests()
  164. document.addEventListener('selectionchange', () => {
  165. this.selection = document.getSelection()
  166. // console.log(this.selection)
  167. if (this.selection) {
  168. this.selectionText = this.selection.toString()
  169. }
  170. });
  171. // this.$refs.details.$el
  172. },
  173. }
  174. </script>
  175. <style>
  176. :root {
  177. cursor: url('cursor.png'), auto;
  178. }
  179. #gtblank-init {
  180. background: #999;
  181. }
  182. .video-bg {
  183. position: fixed;
  184. right: 0;
  185. bottom: 0;
  186. min-width: 100%;
  187. min-height: 100%;
  188. }
  189. a {
  190. color: inherit;
  191. cursor: inherit;
  192. }
  193. .otf {
  194. width: 100%;
  195. /* background-color: rgb(167, 204, 247); */
  196. /* background-image: url('bg.gif'); */
  197. background-size: cover;
  198. display: flex;
  199. flex-direction: column;
  200. align-items: center;
  201. min-height: 100vh;
  202. position: relative;
  203. }
  204. .input-headline {
  205. color: #000;
  206. mix-blend-mode: multiply;
  207. font-size: 4vh;
  208. margin-bottom: .8vh;
  209. text-align: center;
  210. }
  211. .input-form {
  212. display: flex;
  213. flex-direction: column;
  214. width: 100%;
  215. max-width: 800px;
  216. mix-blend-mode: hard-light;
  217. margin-top: 4vh;
  218. z-index: 9;
  219. position: relative;
  220. }
  221. .input-text,
  222. .input-btn,
  223. .input-cb {
  224. color: #000;
  225. background: #fff;
  226. font-size: 2.8vh;
  227. font-family: 'JetBrains Mono', monospace;
  228. border: 0;
  229. padding: .5em 1em;
  230. line-height: 1.4;
  231. max-width: 100%;
  232. cursor: inherit;
  233. }
  234. .input-btn {
  235. color: #000;
  236. background-color: #01ffcf;
  237. }
  238. .input-btn:hover {
  239. background: #00d9b1;
  240. }
  241. .input-checkbox {
  242. margin: 0 1em 0 0;
  243. }
  244. @media screen and (max-width: 1000px) {
  245. .form-wrapper {
  246. margin-top: 4em;
  247. }
  248. .input-text,
  249. .input-btn {
  250. width: 100%;
  251. max-width: 100%;
  252. min-width: 0;
  253. text-align: center;
  254. }
  255. /* .input-form {
  256. position: absolute;
  257. bottom: 0;
  258. display: flex;
  259. flex-direction: column;
  260. } */
  261. }
  262. .input-text {
  263. width: auto;
  264. flex-grow: 1;
  265. }
  266. .wordcloud {
  267. mix-blend-mode: overlay;
  268. }
  269. .details {
  270. color: #000;
  271. background-color: #fff;
  272. font-size: 30px;
  273. max-width: 80em;
  274. margin: 3% 3% 200px;
  275. padding: 3%;
  276. mix-blend-mode: lighten;
  277. box-shadow: 10px 10px 0 #000fee, -10px -10px 0 #3400ee;
  278. }
  279. .share {
  280. max-width: 30em;
  281. width: 80%;
  282. mix-blend-mode: soft-light;
  283. }
  284. .share:hover {
  285. mix-blend-mode: difference;
  286. }
  287. .selection-text {
  288. position: fixed;
  289. z-index: 9999;
  290. font-size: 10vh;
  291. line-height: 1em;
  292. pointer-events: none;
  293. color: #fff;
  294. mix-blend-mode: difference;
  295. top: 10%;
  296. }
  297. </style>