Merge pull request #88 from KevinMidboe/feat/access-code
Feat/access code
This commit is contained in:
		
							
								
								
									
										8
									
								
								.prettierrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.prettierrc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| { | ||||
|   "printWidth": 100, | ||||
|   "quoteProps": "consistent", | ||||
|   "semi": true, | ||||
|   "singleQuote": false, | ||||
|   "trailingComma": "es5", | ||||
|   "useTabs": true | ||||
| } | ||||
							
								
								
									
										3
									
								
								config/env/lottery.config.example.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								config/env/lottery.config.example.js
									
									
									
									
										vendored
									
									
								
							| @@ -8,5 +8,6 @@ module.exports = { | ||||
|   gatewayToken: undefined, | ||||
|   vinmonopoletToken: undefined, | ||||
|   googleanalytics_trackingId: undefined, | ||||
|   googleanalytics_cookieLifetime: 60 * 60 * 24 * 14 | ||||
|   googleanalytics_cookieLifetime: 60 * 60 * 24 * 14, | ||||
|   sites: [], | ||||
| }; | ||||
| @@ -11,15 +11,15 @@ const webpackConfig = function(isDev) { | ||||
|     resolve: { | ||||
|       extensions: [".js", ".vue"], | ||||
|       alias: { | ||||
|         vue$: "vue/dist/vue.min.js", | ||||
|         "@": helpers.root("frontend") | ||||
|       } | ||||
|         "vue$": "vue/dist/vue.min.js", | ||||
|         "@": helpers.root("frontend"), | ||||
|       }, | ||||
|     }, | ||||
|     entry: { | ||||
|       vinlottis: helpers.root("frontend", "vinlottis-init") | ||||
|       vinlottis: helpers.root("frontend", "vinlottis-init"), | ||||
|     }, | ||||
|     externals: { | ||||
|         moment: 'moment' // comes with chart.js | ||||
|       moment: "moment", // comes with chart.js | ||||
|     }, | ||||
|     module: { | ||||
|       rules: [ | ||||
| @@ -31,45 +31,45 @@ const webpackConfig = function(isDev) { | ||||
|               options: { | ||||
|                 loaders: { | ||||
|                   scss: "vue-style-loader!css-loader!sass-loader", | ||||
|                   sass: "vue-style-loader!css-loader!sass-loader?indentedSyntax" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|                   sass: "vue-style-loader!css-loader!sass-loader?indentedSyntax", | ||||
|                 }, | ||||
|               }, | ||||
|             }, | ||||
|           ], | ||||
|         }, | ||||
|         { | ||||
|           test: /\.js$/, | ||||
|           use: [ "babel-loader" ], | ||||
|           include: [helpers.root("frontend")] | ||||
|           use: ["babel-loader"], | ||||
|           include: [helpers.root("frontend")], | ||||
|         }, | ||||
|         { | ||||
|           test: /\.css$/, | ||||
|           use: [ | ||||
|             MiniCSSExtractPlugin.loader, | ||||
|             { loader: "css-loader", options: { sourceMap: isDev } } | ||||
|           ] | ||||
|             { loader: "css-loader", options: { sourceMap: isDev } }, | ||||
|           ], | ||||
|         }, | ||||
|         { | ||||
|           test: /\.scss$/, | ||||
|           use: [ | ||||
|             MiniCSSExtractPlugin.loader, | ||||
|             { loader: "css-loader", options: { sourceMap: isDev } }, | ||||
|             { loader: "sass-loader", options: { sourceMap: isDev } } | ||||
|           ] | ||||
|             { loader: "sass-loader", options: { sourceMap: isDev } }, | ||||
|           ], | ||||
|         }, | ||||
|         { | ||||
|           test: /\.woff(2)?(\?[a-z0-9]+)?$/, | ||||
|           loader: "url-loader", | ||||
|           options: { | ||||
|             limit: 10000, | ||||
|             mimetype: "application/font-woff" | ||||
|           } | ||||
|             mimetype: "application/font-woff", | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           test: /\.(ttf|eot|svg)(\?[a-z0-9]+)?$/, | ||||
|           loader: "file-loader" | ||||
|         } | ||||
|       ] | ||||
|           loader: "file-loader", | ||||
|         }, | ||||
|       ], | ||||
|     }, | ||||
|     plugins: [ | ||||
|       new VueLoaderPlugin(), | ||||
| @@ -83,9 +83,10 @@ const webpackConfig = function(isDev) { | ||||
|         __HOURS__: env.hours, | ||||
|         __PUSHENABLED__: JSON.stringify(require("./defaults/push") != false), | ||||
|         __GA_TRACKINGID__: JSON.stringify(env.googleanalytics_trackingId), | ||||
|         __GA_COOKIELIFETIME__: env.googleanalytics_cookieLifetime | ||||
|       }) | ||||
|     ] | ||||
|         __GA_COOKIELIFETIME__: env.googleanalytics_cookieLifetime, | ||||
|         __sites__: JSON.stringify(env.sites), | ||||
|       }), | ||||
|     ], | ||||
|   }; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -15,51 +15,52 @@ let webpackConfig = merge(commonConfig(true), { | ||||
|   output: { | ||||
|     path: helpers.root("dist"), | ||||
|     publicPath: "/", | ||||
|     filename: "js/[name].bundle.js" | ||||
|     filename: "js/[name].bundle.js", | ||||
|   }, | ||||
|   optimization: { | ||||
|     concatenateModules: true, | ||||
|     splitChunks: { | ||||
|       chunks: "initial" | ||||
|     } | ||||
|       chunks: "initial", | ||||
|     }, | ||||
|   }, | ||||
|   plugins: [ | ||||
|     new webpack.EnvironmentPlugin(environment), | ||||
|     new FriendlyErrorsPlugin(), | ||||
|     new MiniCSSExtractPlugin({ | ||||
|       filename: "css/[name].css" | ||||
|     }) | ||||
|       filename: "css/[name].css", | ||||
|     }), | ||||
|   ], | ||||
|   devServer: { | ||||
|     compress: true, | ||||
|     historyApiFallback: true, | ||||
|     host: "0.0.0.0", | ||||
|     disableHostCheck: true, | ||||
|     hot: true, | ||||
|     overlay: true, | ||||
|     stats: { | ||||
|       normal: true | ||||
|       normal: true, | ||||
|     }, | ||||
|     proxy: { | ||||
|       "/api": { | ||||
|         target: "http://localhost:30030", | ||||
|         changeOrigin: true | ||||
|         changeOrigin: true, | ||||
|       }, | ||||
|       "/socket.io": { | ||||
|         target: "ws://localhost:30030", | ||||
|         changeOrigin: false, | ||||
|         ws: true | ||||
|       } | ||||
|         ws: true, | ||||
|       }, | ||||
|     }, | ||||
|     writeToDisk: false, | ||||
|   }, | ||||
|     writeToDisk: false | ||||
|   } | ||||
| }); | ||||
|  | ||||
| webpackConfig = merge(webpackConfig, { | ||||
|   plugins: [ | ||||
|     new HtmlWebpackPlugin({ | ||||
|       template: "frontend/templates/Index.html" | ||||
|     }) | ||||
|   ] | ||||
|       template: "frontend/templates/Index.html", | ||||
|     }), | ||||
|   ], | ||||
| }); | ||||
|  | ||||
| module.exports = webpackConfig; | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <template> | ||||
|   <div class="app-container"> | ||||
|     <banner :routes="routes"/> | ||||
|     <banner :routes="routes" /> | ||||
|     <router-view /> | ||||
|     <Footer /> | ||||
|     <UpdateToast | ||||
| @@ -30,33 +30,33 @@ export default { | ||||
|       routes: [ | ||||
|         { | ||||
|           name: "Virtuelt lotteri", | ||||
|           route: "/lottery" | ||||
|           route: "/lottery", | ||||
|         }, | ||||
|         { | ||||
|           name: "Dagens viner", | ||||
|           route: "/dagens/" | ||||
|           route: "/dagens/", | ||||
|         }, | ||||
|         { | ||||
|           name: "Highscore", | ||||
|           route: "/highscore" | ||||
|           route: "/highscore", | ||||
|         }, | ||||
|         { | ||||
|           name: "Historie", | ||||
|           route: "/history/" | ||||
|           route: "/history/", | ||||
|         }, | ||||
|         { | ||||
|           name: "Foreslå vin", | ||||
|           route: "/request" | ||||
|           route: "/request", | ||||
|         }, | ||||
|         { | ||||
|           name: "Foreslåtte viner", | ||||
|           route: "/requested-wines" | ||||
|           route: "/requested-wines", | ||||
|         }, | ||||
|         { | ||||
|           name: "Login", | ||||
|           route: "/login" | ||||
|         } | ||||
|       ] | ||||
|           route: "/login", | ||||
|         }, | ||||
|       ], | ||||
|     }; | ||||
|   }, | ||||
|   mounted() { | ||||
| @@ -78,7 +78,7 @@ export default { | ||||
|     closeToast: function() { | ||||
|       this.showToast = false; | ||||
|     }, | ||||
|   } | ||||
|   }, | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| @@ -99,7 +99,7 @@ body { | ||||
|   display: grid; | ||||
|   grid-template-rows: 80px auto 100px; | ||||
|  | ||||
|   .main-container{ | ||||
|   .main-container { | ||||
|     height: 100%; | ||||
|     width: 100%; | ||||
|   } | ||||
|   | ||||
							
								
								
									
										208
									
								
								frontend/components/AccessCodePage.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								frontend/components/AccessCodePage.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,208 @@ | ||||
| <template> | ||||
|   <div> | ||||
|     <div class="floating-video"> | ||||
|       <video autoplay loop muted id="office-party" ref="video"> | ||||
|         <source src="/public/assets/videos/office-party.mp4" type="video/mp4" /> | ||||
|       </video> | ||||
|     </div> | ||||
|  | ||||
|     <div class="container"> | ||||
|       <div class="container--code label-div row"> | ||||
|         <label>Din vinlottis kode:</label> | ||||
|       </div> | ||||
|  | ||||
|       <div class="codeinput-container"> | ||||
|         <input v-model="code" placeholder="KODE" @keyup.enter="submit" /> | ||||
|         <button class="vin-button" @click="submit">ENTER</button> | ||||
|       </div> | ||||
|  | ||||
|       <button class="mute-button" @click="toggleMute"> | ||||
|         {{ muted ? "🔇" : "🔈" }} | ||||
|       </button> | ||||
|     </div> | ||||
|  | ||||
|     <Footer></Footer> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import Footer from "@/ui/FooterUnbranded"; | ||||
| import { createCookie } from "@/utils"; | ||||
|  | ||||
| export default { | ||||
|   components: { Footer }, | ||||
|   data() { | ||||
|     return { | ||||
|       muted: true, | ||||
|       code: undefined, | ||||
|       // volume: 50, | ||||
|     }; | ||||
|   }, | ||||
|   created() { | ||||
|     const site = __sites__.find(site => site.code == this.code); | ||||
|   }, | ||||
|   // watch: { | ||||
|   //   volume(newValue) { | ||||
|   //     this.$refs.video.volume = newValue / 100; | ||||
|   //   }, | ||||
|   // }, | ||||
|   methods: { | ||||
|     toggleMute() { | ||||
|       const { video } = this.$refs; | ||||
|       this.muted = !this.muted; | ||||
|       video.muted = this.muted; | ||||
|     }, | ||||
|     togglePlayback() { | ||||
|       const { video } = this.$refs; | ||||
|       video.paused ? video.play() : video.pause(); | ||||
|     }, | ||||
|     submit() { | ||||
|       const site = __sites__.find(site => site.code == this.code); | ||||
|  | ||||
|       if (site) { | ||||
|         createCookie("accesscode", site.code, 14); | ||||
|         window.location.href = `${window.location.protocol}//${site.domain}`; | ||||
|       } | ||||
|  | ||||
|       return; | ||||
|     }, | ||||
|   }, | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| @import "@/styles/media-queries"; | ||||
|  | ||||
| .floating-video { | ||||
|   position: absolute; | ||||
|   height: 100vh; | ||||
|   width: 100vw; | ||||
|   overflow-x: hidden; | ||||
|   display: grid; | ||||
|   place-items: center; | ||||
|   background-color: var(--primary); | ||||
|   z-index: -1; | ||||
| } | ||||
|  | ||||
| .mute-button { | ||||
|   z-index: 10; | ||||
|   -webkit-appearance: unset; | ||||
|   border: none; | ||||
|   background-color: transparent; | ||||
|   font-size: 1.5rem; | ||||
|   position: absolute; | ||||
|   right: 1rem; | ||||
|   bottom: calc(75px + 1rem); | ||||
|   cursor: pointer; | ||||
|  | ||||
|   input[type="range"] { | ||||
|     transform: rotate(90deg); | ||||
|     background-color: red; | ||||
|   } | ||||
| } | ||||
|  | ||||
| video { | ||||
|   position: absolute; | ||||
|   display: block; | ||||
|   // left: 0; | ||||
|   height: 100%; | ||||
|  | ||||
|   // -o-filter: blur(1px); | ||||
|   filter: blur(5px); | ||||
|   object-fit: cover; | ||||
|   transform: scale(1.02); | ||||
|  | ||||
|   @include mobile { | ||||
|     top: 0; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .codeinput-container { | ||||
|   display: flex; | ||||
|   flex-direction: row; | ||||
|   justify-content: center; | ||||
|   align-items: center; | ||||
|  | ||||
|   @include mobile { | ||||
|     width: 80%; | ||||
|   } | ||||
|  | ||||
|   input { | ||||
|     max-width: 24rem; | ||||
|     width: 100%; | ||||
|     padding: 0.5rem; | ||||
|  | ||||
|     font-size: 4rem; | ||||
|     text-align: center; | ||||
|     z-index: 2; | ||||
|     background-color: white; | ||||
|  | ||||
|     @include mobile { | ||||
|       font-size: 3rem; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   button { | ||||
|     height: 100%; | ||||
|     max-height: unset; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .container { | ||||
|   width: 100%; | ||||
|   height: calc(100vh - 80px); | ||||
|   margin: auto; | ||||
|   display: flex; | ||||
|  | ||||
|   align-items: center; | ||||
|   flex-direction: column; | ||||
|   justify-content: flex-end; | ||||
|   justify-content: center; | ||||
|  | ||||
|   @include desktop { | ||||
|     justify-content: center; | ||||
|   } | ||||
|  | ||||
|   h1 { | ||||
|     position: relative; | ||||
|     // text-align: center; | ||||
|     font-weight: 600; | ||||
|     // color: white; | ||||
|  | ||||
|     @include desktop { | ||||
|       font-size: 3rem; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   &--code { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|  | ||||
|     label { | ||||
|       color: rgba(255, 255, 255, 0.82); | ||||
|       font-size: 1.5rem; | ||||
|       font-weight: 500; | ||||
|     } | ||||
|  | ||||
|     @include desktop { | ||||
|       width: 40%; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| .input-line { | ||||
|   margin: auto; | ||||
|   display: flex; | ||||
|   justify-content: space-around; | ||||
|   align-items: center; | ||||
|   margin-top: 2.4rem; | ||||
|  | ||||
|   @include mobile { | ||||
|     margin-top: 1.2rem; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .button-container { | ||||
|   margin-top: 4rem; | ||||
| } | ||||
| </style> | ||||
| @@ -1,142 +1,172 @@ | ||||
| const VinlottisPage = () => import( | ||||
| const VinlottisPage = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "landing-page" */ | ||||
|   "@/components/VinlottisPage"); | ||||
| const VirtualLotteryPage = () => import( | ||||
|     "@/components/VinlottisPage" | ||||
|   ); | ||||
| const VirtualLotteryPage = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "landing-page" */ | ||||
|   "@/components/VirtualLotteryPage"); | ||||
| const GeneratePage = () => import( | ||||
|     "@/components/VirtualLotteryPage" | ||||
|   ); | ||||
| const GeneratePage = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "landing-page" */ | ||||
|   "@/components/GeneratePage"); | ||||
|     "@/components/GeneratePage" | ||||
|   ); | ||||
|  | ||||
| const TodaysPage = () => import( | ||||
| const TodaysPage = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "sub-pages" */ | ||||
|   "@/components/TodaysPage"); | ||||
| const AllWinesPage = () => import( | ||||
|     "@/components/TodaysPage" | ||||
|   ); | ||||
| const AllWinesPage = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "sub-pages" */ | ||||
|   "@/components/AllWinesPage"); | ||||
| const HistoryPage = () => import( | ||||
|     "@/components/AllWinesPage" | ||||
|   ); | ||||
| const HistoryPage = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "sub-pages" */ | ||||
|   "@/components/HistoryPage"); | ||||
| const WinnerPage = () => import( | ||||
|     "@/components/HistoryPage" | ||||
|   ); | ||||
| const WinnerPage = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "sub-pages" */ | ||||
|   "@/components/WinnerPage"); | ||||
| const SalgsbetingelserPage = () => import( | ||||
|     "@/components/WinnerPage" | ||||
|   ); | ||||
| const SalgsbetingelserPage = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "sub-pages" */ | ||||
|   "@/components/SalgsbetingelserPage"); | ||||
|     "@/components/SalgsbetingelserPage" | ||||
|   ); | ||||
|  | ||||
| const LoginPage = () => import( | ||||
| const LoginPage = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "user" */ | ||||
|   "@/components/LoginPage"); | ||||
| const CreatePage = () => import( | ||||
|     "@/components/LoginPage" | ||||
|   ); | ||||
| const CreatePage = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "user" */ | ||||
|   "@/components/CreatePage"); | ||||
| const AdminPage = () => import( | ||||
|     "@/components/CreatePage" | ||||
|   ); | ||||
| const AdminPage = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "admin" */ | ||||
|   "@/components/AdminPage"); | ||||
|     "@/components/AdminPage" | ||||
|   ); | ||||
|  | ||||
| const PersonalHighscorePage = () => import( | ||||
| const PersonalHighscorePage = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "highscore" */ | ||||
|   "@/components/PersonalHighscorePage"); | ||||
| const HighscorePage = () => import( | ||||
|     "@/components/PersonalHighscorePage" | ||||
|   ); | ||||
| const HighscorePage = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "highscore" */ | ||||
|   "@/components/HighscorePage"); | ||||
|     "@/components/HighscorePage" | ||||
|   ); | ||||
|  | ||||
| const RequestWine = () => import( | ||||
| const RequestWine = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "request" */ | ||||
|   "@/components/RequestWine"); | ||||
| const AllRequestedWines = () => import( | ||||
|     "@/components/RequestWine" | ||||
|   ); | ||||
| const AllRequestedWines = () => | ||||
|   import( | ||||
|     /* webpackChunkName: "request" */ | ||||
|   "@/components/AllRequestedWines"); | ||||
|     "@/components/AllRequestedWines" | ||||
|   ); | ||||
|  | ||||
| const routes = [ | ||||
|   { | ||||
|     path: "*", | ||||
|     name: "Hjem", | ||||
|     component: VinlottisPage | ||||
|     component: VinlottisPage, | ||||
|   }, | ||||
|   { | ||||
|     path: "/lottery", | ||||
|     name: "Lotteri", | ||||
|     component: VirtualLotteryPage | ||||
|     component: VirtualLotteryPage, | ||||
|   }, | ||||
|   { | ||||
|     path: "/dagens", | ||||
|     name: "Dagens vin", | ||||
|     component: TodaysPage | ||||
|     component: TodaysPage, | ||||
|   }, | ||||
|   { | ||||
|     path: "/viner", | ||||
|     name: "All viner", | ||||
|     component: AllWinesPage | ||||
|     component: AllWinesPage, | ||||
|   }, | ||||
|   { | ||||
|     path: "/login", | ||||
|     name: "Login", | ||||
|     component: LoginPage | ||||
|     component: LoginPage, | ||||
|   }, | ||||
|   { | ||||
|     path: "/create", | ||||
|     name: "Registrer", | ||||
|     component: CreatePage | ||||
|     component: CreatePage, | ||||
|   }, | ||||
|   { | ||||
|     path: "/admin", | ||||
|     name: "Admin side", | ||||
|     component: AdminPage | ||||
|     component: AdminPage, | ||||
|   }, | ||||
|   { | ||||
|     path: "/generate/", | ||||
|     component: GeneratePage | ||||
|     component: GeneratePage, | ||||
|   }, | ||||
|   { | ||||
|     path: "/winner/:id", | ||||
|     component: WinnerPage | ||||
|     component: WinnerPage, | ||||
|   }, | ||||
|   { | ||||
|     path: "/history/:date", | ||||
|     name: "Historie for dato", | ||||
|     component: HistoryPage | ||||
|     component: HistoryPage, | ||||
|   }, | ||||
|   { | ||||
|     path: "/history", | ||||
|     name: "Historie", | ||||
|     component: HistoryPage | ||||
|     component: HistoryPage, | ||||
|   }, | ||||
|   { | ||||
|     path: "/highscore/:name", | ||||
|     name: "Personlig topplisten", | ||||
|     component: PersonalHighscorePage | ||||
|     component: PersonalHighscorePage, | ||||
|   }, | ||||
|   { | ||||
|     path: "/highscore", | ||||
|     name: "Topplisten", | ||||
|     component: HighscorePage | ||||
|     component: HighscorePage, | ||||
|   }, | ||||
|   { | ||||
|     path: "/anbefal", | ||||
|     name: "Anbefal ny vin", | ||||
|     component: RequestWine | ||||
|     component: RequestWine, | ||||
|   }, | ||||
|   { | ||||
|     path: "/request", | ||||
|     name: "Etterspør vin", | ||||
|     component: RequestWine | ||||
|     component: RequestWine, | ||||
|   }, | ||||
|   { | ||||
|     path: "/anbefalte", | ||||
|     name: "Anbefalte viner", | ||||
|     component: AllRequestedWines | ||||
|     component: AllRequestedWines, | ||||
|   }, | ||||
|   { | ||||
|     path: "/requested-wines", | ||||
|     name: "Etterspurte vin", | ||||
|     component: AllRequestedWines | ||||
|     component: AllRequestedWines, | ||||
|   }, | ||||
|   { | ||||
|     path: "/salgsbetingelser", | ||||
|     name: "Salgsbetingelser", | ||||
|     component: SalgsbetingelserPage | ||||
|   } | ||||
|     component: SalgsbetingelserPage, | ||||
|   }, | ||||
| ]; | ||||
|  | ||||
| export { routes }; | ||||
|   | ||||
| @@ -5,15 +5,27 @@ | ||||
|       <img src="/public/assets/images/knowit.svg" alt="knowit logo" /> | ||||
|     </router-link> | ||||
|  | ||||
|     <a class="menu-toggle-container" aria-label="show-menu" @click="toggleMenu" :class="isOpen ? 'open' : 'collapsed'"> | ||||
|     <a | ||||
|       class="menu-toggle-container" | ||||
|       aria-label="show-menu" | ||||
|       @click="toggleMenu" | ||||
|       :class="isOpen ? 'open' : 'collapsed'" | ||||
|     > | ||||
|       <span class="menu-toggle"></span> | ||||
|       <span class="menu-toggle"></span> | ||||
|       <span class="menu-toggle"></span> | ||||
|     </a> | ||||
|  | ||||
|     <nav class="menu" :class="isOpen ? 'open' : 'collapsed'"> | ||||
|       <router-link v-for="(route, index) in routes" :key="index" :to="route.route" class="menu-item-link"> | ||||
|         <a @click="toggleMenu" class="single-route" :class="isOpen ? 'open' : 'collapsed'">{{ route.name }}</a> | ||||
|       <router-link | ||||
|         v-for="(route, index) in routes" | ||||
|         :key="index" | ||||
|         :to="route.route" | ||||
|         class="menu-item-link" | ||||
|       > | ||||
|         <a @click="toggleMenu" class="single-route" :class="isOpen ? 'open' : 'collapsed'">{{ | ||||
|           route.name | ||||
|         }}</a> | ||||
|         <i class="icon icon--arrow-right"></i> | ||||
|       </router-link> | ||||
|     </nav> | ||||
| @@ -42,14 +54,14 @@ export default { | ||||
|       minutes: 0, | ||||
|       seconds: 0, | ||||
|       distance: 0, | ||||
|       interval: null | ||||
|       interval: null, | ||||
|     }; | ||||
|   }, | ||||
|   props: { | ||||
|     routes: { | ||||
|       required: true, | ||||
|       type: Array | ||||
|     } | ||||
|       type: Array, | ||||
|     }, | ||||
|   }, | ||||
|   mounted() { | ||||
|     this.initialize(), this.countdown(); | ||||
| @@ -66,7 +78,7 @@ export default { | ||||
|         return true; | ||||
|       } | ||||
|       return false; | ||||
|     } | ||||
|     }, | ||||
|   }, | ||||
|   methods: { | ||||
|     toggleMenu() { | ||||
| @@ -118,8 +130,8 @@ export default { | ||||
|         this.initialize(); | ||||
|       } | ||||
|       this.interval = setTimeout(this.countdown, 500); | ||||
|     } | ||||
|   } | ||||
|     }, | ||||
|   }, | ||||
| }; | ||||
| </script> | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|       <li> | ||||
|         <a href="https://github.com/KevinMidboe/vinlottis" class="github"> | ||||
|           <span>Utforsk koden på github</span> | ||||
|           <img src="/public/assets/images/logo-github.png" alt="github logo"> | ||||
|           <img src="/public/assets/images/logo-github.png" alt="github logo" /> | ||||
|         </a> | ||||
|       </li> | ||||
|  | ||||
| @@ -16,15 +16,15 @@ | ||||
|     </ul> | ||||
|  | ||||
|     <router-link to="/" class="company-logo"> | ||||
|       <img src="/public/assets/images/knowit.svg" alt="knowit logo"> | ||||
|       <img src="/public/assets/images/knowit.svg" alt="knowit logo" /> | ||||
|     </router-link> | ||||
|   </footer> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: 'WineFooter' | ||||
| } | ||||
|   name: "WineFooter", | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| @@ -57,7 +57,6 @@ footer { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|  | ||||
|  | ||||
|     img { | ||||
|       margin-left: 0.5rem; | ||||
|       height: 30px; | ||||
| @@ -74,7 +73,7 @@ footer { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .company-logo{ | ||||
|   .company-logo { | ||||
|     margin-right: 5em; | ||||
|  | ||||
|     img { | ||||
| @@ -93,5 +92,4 @@ footer { | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| </style> | ||||
							
								
								
									
										103
									
								
								frontend/ui/FooterUnbranded.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								frontend/ui/FooterUnbranded.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| <template> | ||||
|   <footer> | ||||
|     <a href="https://github.com/KevinMidboe/vinlottis" class="github"> | ||||
|       <span>Utforsk koden på github</span> | ||||
|       <img src="/public/assets/images/logo-github.png" alt="github logo" /> | ||||
|     </a> | ||||
|  | ||||
|     <a href="mailto:questions@vinlottis.no" class="mail"> | ||||
|       <span class="vin-link">questions@vinlottis.no</span> | ||||
|     </a> | ||||
|   </footer> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "WineFooter", | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| @import "@/styles/variables.scss"; | ||||
| @import "@/styles/media-queries.scss"; | ||||
|  | ||||
| footer { | ||||
|   width: 100%; | ||||
|   height: 75px; | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
|   background: #f4f4f4; | ||||
|   position: fixed; | ||||
|   bottom: 0; | ||||
|  | ||||
|   > *:first-of-type { | ||||
|     margin-left: 0.5rem; | ||||
|   } | ||||
|   > *:last-of-type { | ||||
|     margin-right: 0.5rem; | ||||
|   } | ||||
|  | ||||
|   @include desktop { | ||||
|     > *:first-of-type { | ||||
|       margin-left: 4rem; | ||||
|     } | ||||
|     > *:last-of-type { | ||||
|       margin-right: 4rem; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ul { | ||||
|     list-style-type: none; | ||||
|     padding: 0; | ||||
|     margin-left: 5rem; | ||||
|  | ||||
|     li:not(:first-of-type) { | ||||
|       margin-top: 0.75rem; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   a { | ||||
|     color: $matte-text-color; | ||||
|   } | ||||
|  | ||||
|   .github { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|  | ||||
|     img { | ||||
|       margin-left: 0.5rem; | ||||
|       height: 30px; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .mail { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|  | ||||
|     img { | ||||
|       margin-left: 0.5rem; | ||||
|       height: 23px; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .company-logo { | ||||
|     margin-right: 5em; | ||||
|  | ||||
|     img { | ||||
|       width: 100px; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @include mobile { | ||||
|     $margin: 1rem; | ||||
|     ul { | ||||
|       margin-left: $margin; | ||||
|     } | ||||
|  | ||||
|     .company-logo { | ||||
|       margin-right: $margin; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -19,4 +19,31 @@ function daysAgo(date) { | ||||
|   return Math.round(Math.abs((new Date() - new Date(date)) / day)); | ||||
| } | ||||
|  | ||||
| export function createCookie(name, value, days) { | ||||
|   if (days) { | ||||
|     var date = new Date(); | ||||
|     date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); | ||||
|     var expires = "; expires=" + date.toGMTString(); | ||||
|   } else var expires = ""; | ||||
|  | ||||
|   const domain = `${window.location.hostname}`; | ||||
|   console.log("cookie:", `${name}=${value + expires}; path=/; domain=${domain}`); | ||||
|   document.cookie = `${name}=${value + expires}; path=/; domain=${domain}`; | ||||
| } | ||||
|  | ||||
| export function readCookie(name) { | ||||
|   var nameEQ = name + "="; | ||||
|   var ca = document.cookie.split(";"); | ||||
|   for (var i = 0; i < ca.length; i++) { | ||||
|     var c = ca[i]; | ||||
|     while (c.charAt(0) == " ") c = c.substring(1, c.length); | ||||
|     if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); | ||||
|   } | ||||
|   return null; | ||||
| } | ||||
|  | ||||
| export function eraseCookie(name) { | ||||
|   createCookie(name, "", -1); | ||||
| } | ||||
|  | ||||
| export { dateString, humanReadableDate, daysAgo }; | ||||
|   | ||||
| @@ -2,6 +2,8 @@ import Vue from "vue"; | ||||
| import VueRouter from "vue-router"; | ||||
| import { routes } from "@/router.js"; | ||||
| import Vinlottis from "@/Vinlottis"; | ||||
| import AccessCodePage from "@/components/AccessCodePage"; | ||||
| import { readCookie } from "@/utils"; | ||||
|  | ||||
| import Toast from "@/plugins/Toast"; | ||||
|  | ||||
| @@ -21,7 +23,7 @@ if (ENV !== "development") { | ||||
|     beforeSend: event => { | ||||
|       console.error(event); | ||||
|       return event; | ||||
|     } | ||||
|     }, | ||||
|   }); | ||||
| } | ||||
|  | ||||
| @@ -38,7 +40,7 @@ ga.l = 1 * new Date(); | ||||
| ga("create", __GA_TRACKINGID__, { | ||||
|   allowAnchor: false, | ||||
|   cookieExpires: __GA_COOKIELIFETIME__, // Time in seconds | ||||
|   cookieFlags: "SameSite=Strict; Secure" | ||||
|   cookieFlags: "SameSite=Strict; Secure", | ||||
| }); | ||||
| ga("set", "anonymizeIp", true); // Enable IP Anonymization/IP masking | ||||
| ga("send", "pageview"); | ||||
| @@ -47,13 +49,24 @@ if (ENV == "development") window[`ga-disable-${__GA_TRACKINGID__}`] = true; | ||||
|  | ||||
| const router = new VueRouter({ | ||||
|   routes: routes, | ||||
|   mode: 'history' | ||||
|   mode: "history", | ||||
| }); | ||||
|  | ||||
| function redirectIfHasAccessCodeAndOnIncorrectDomain(accessCode) { | ||||
|   const site = __sites__.find(site => site.code == accessCode); | ||||
|   if (accessCode && site && !!!site.domain.includes(window.location.hostname)) { | ||||
|     window.location.href = `${window.location.protocol}//${site.domain}`; | ||||
|   } | ||||
| } | ||||
|  | ||||
| const accessCode = readCookie("accesscode"); | ||||
| redirectIfHasAccessCodeAndOnIncorrectDomain(1); | ||||
| const component = accessCode ? Vinlottis : AccessCodePage; | ||||
|  | ||||
| new Vue({ | ||||
|   el: "#app", | ||||
|   router, | ||||
|   components: { Vinlottis }, | ||||
|   template: "<Vinlottis/>", | ||||
|   render: h => h(Vinlottis) | ||||
|   components: { component }, | ||||
|   template: "<Vinlottis />", | ||||
|   render: h => h(component), | ||||
| }); | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								public/assets/videos/office-party.mp4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/assets/videos/office-party.mp4
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user