├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── CHANGELOG.md ├── README.md ├── apollo ├── client-configs │ └── default.js ├── mutations │ ├── CreateClick.gql │ ├── CreatePalette.gql │ ├── CreateUser.gql │ ├── CreateVote.gql │ ├── LoginUser.gql │ └── UpdateClick.gql └── queries │ ├── AllPalettes.gql │ └── Palette.gql ├── assets ├── README.md ├── images │ └── clipboard-cursor.png └── scss │ ├── colors.scss │ ├── global.scss │ ├── includes.scss │ ├── mixins.scss │ └── variables.scss ├── components ├── FooterNav.vue ├── README.md ├── color-palette │ ├── CodePreview.vue │ ├── ColorPalette.vue │ ├── ColorPreview.vue │ └── Upvote.vue ├── shared │ ├── Banner.vue │ └── Spinner.vue └── swatch │ ├── AddSwatch.vue │ └── ColorSwatch.vue ├── constants └── settings.js ├── layouts ├── README.md ├── clean.vue └── default.vue ├── middleware ├── README.md ├── auth.js └── no-auth.js ├── nuxt.config.js ├── package.json ├── pages ├── README.md ├── about.vue ├── create.vue ├── image │ └── _id.vue ├── index.vue ├── legal.vue ├── login.vue └── palette │ └── _id.vue ├── plugins └── README.md ├── static ├── README.md ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon-120x120.png ├── apple-touch-icon-152x152.png ├── apple-touch-icon-180x180.png ├── apple-touch-icon-60x60.png ├── apple-touch-icon-76x76.png ├── apple-touch-icon.png ├── browserconfig.xml ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── google3ecbc228f0af15c0.html ├── icon.png ├── images │ ├── colourhunt-intro.png │ └── colourhunt-twitter.png ├── mstile-144x144.png ├── mstile-150x150.png ├── mstile-310x150.png ├── mstile-310x310.png ├── mstile-70x70.png ├── safari-pinned-tab.svg ├── site.webmanifest └── sw.js ├── store ├── README.md ├── getters.js ├── index.js ├── modules │ ├── auth.js │ └── index.js └── types.js ├── utils └── index.js ├── yarn-error.log └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_size = 2 6 | indent_style = space 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true 6 | }, 7 | parserOptions: { 8 | parser: 'babel-eslint' 9 | }, 10 | extends: [ 11 | // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention 12 | // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. 13 | 'plugin:vue/essential' 14 | ], 15 | // required to lint *.vue files 16 | plugins: [ 17 | 'vue' 18 | ], 19 | // add your custom rules here 20 | rules: {} 21 | } 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | 4 | # logs 5 | npm-debug.log 6 | 7 | # Nuxt build 8 | .nuxt 9 | 10 | # Nuxt generate 11 | dist 12 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | 6 | # [1.8.0](https://github.com/apertureless/colourhunt/compare/v1.7.1...v1.8.0) (2018-05-25) 7 | 8 | 9 | ### Features 10 | 11 | * **privacy:** Remove GA ([c3ef6c4](https://github.com/apertureless/colourhunt/commit/c3ef6c4)) 12 | * **privacy:** Remove signup and cookie law plugin ([a8e34ad](https://github.com/apertureless/colourhunt/commit/a8e34ad)) 13 | 14 | 15 | 16 | 17 | ## [1.7.1](https://github.com/apertureless/colourhunt/compare/v1.7.0...v1.7.1) (2018-04-15) 18 | 19 | 20 | ### Bug Fixes 21 | 22 | * **color-preview:** Add active state and prevent color field to shrink on click ([75b4b10](https://github.com/apertureless/colourhunt/commit/75b4b10)) 23 | * **color-preview:** Remove old click handler function ([3a3c919](https://github.com/apertureless/colourhunt/commit/3a3c919)) 24 | * **upvote:** Change inactive color to grayscale to provide better contrast between voted and not voted ([a7fe2a8](https://github.com/apertureless/colourhunt/commit/a7fe2a8)) 25 | 26 | 27 | 28 | 29 | # [1.7.0](https://github.com/apertureless/colourhunt/compare/v1.6.0...v1.7.0) (2018-04-13) 30 | 31 | 32 | ### Bug Fixes 33 | 34 | * **color-preview:** Remove mo-js import ([551f083](https://github.com/apertureless/colourhunt/commit/551f083)) 35 | * **footer:** Add more padding to footer ([2f189d7](https://github.com/apertureless/colourhunt/commit/2f189d7)) 36 | * **palettes:** Increase palettes per page to 21 ([6c51eb8](https://github.com/apertureless/colourhunt/commit/6c51eb8)) 37 | * **remove swatch:** Decrease button size and align to the right ([039d678](https://github.com/apertureless/colourhunt/commit/039d678)) 38 | 39 | 40 | ### Features 41 | 42 | * **clipboard:** Add copy to clipboard function ([fa731db](https://github.com/apertureless/colourhunt/commit/fa731db)) 43 | 44 | 45 | 46 | 47 | # [1.6.0](https://github.com/apertureless/colourhunt/compare/v1.5.0...v1.6.0) (2018-04-09) 48 | 49 | 50 | ### Bug Fixes 51 | 52 | * **auth:** Fix bug where ls was not read properly ([32d0fa3](https://github.com/apertureless/colourhunt/commit/32d0fa3)) 53 | * **build:** Add spa fallback ([f565f36](https://github.com/apertureless/colourhunt/commit/f565f36)) 54 | * **seo:** Change sitemap from middleware to generation ([b7d37b5](https://github.com/apertureless/colourhunt/commit/b7d37b5)) 55 | 56 | 57 | ### Features 58 | 59 | * **palette:** Add tracking for palette views ([1410ced](https://github.com/apertureless/colourhunt/commit/1410ced)) 60 | * **seo:** Add google console confirmation ([e6ddce3](https://github.com/apertureless/colourhunt/commit/e6ddce3)) 61 | * **seo:** Add sitemap module ([01088ac](https://github.com/apertureless/colourhunt/commit/01088ac)) 62 | * **signup:** Update vue-password dependency and add show/hide password button ([c753d68](https://github.com/apertureless/colourhunt/commit/c753d68)) 63 | 64 | 65 | 66 | 67 | # [1.5.0](https://github.com/apertureless/colourhunt/compare/v1.4.0...v1.5.0) (2018-04-02) 68 | 69 | 70 | ### Bug Fixes 71 | 72 | * **about:** Set max-width of text ([355be9e](https://github.com/apertureless/colourhunt/commit/355be9e)) 73 | * **build:** Change mode back to spa ([49971c8](https://github.com/apertureless/colourhunt/commit/49971c8)) 74 | * **build:** Fix failing build ([2a0f68b](https://github.com/apertureless/colourhunt/commit/2a0f68b)) 75 | * **feedback:** Fix label naming ([c79658c](https://github.com/apertureless/colourhunt/commit/c79658c)) 76 | * **feedback:** Fix missing action on feedback form ([5677eaf](https://github.com/apertureless/colourhunt/commit/5677eaf)) 77 | * **feedback:** Rewrite feedback form as nuxt is running in spa mode ([9e0d02e](https://github.com/apertureless/colourhunt/commit/9e0d02e)) 78 | * **feedback-button:** Remove feedback button until its working ([f2c52a8](https://github.com/apertureless/colourhunt/commit/f2c52a8)) 79 | * **seo:** Add new facebook & twitter image ([02f8765](https://github.com/apertureless/colourhunt/commit/02f8765)) 80 | * **seo:** Fix image location for open graph ([0cc207d](https://github.com/apertureless/colourhunt/commit/0cc207d)) 81 | * **seo:** Fix open graph image name. Jesus. Last commit for today... ([4f77f9a](https://github.com/apertureless/colourhunt/commit/4f77f9a)) 82 | * **swatch:** Fix click handling on swatch ([3f426ec](https://github.com/apertureless/colourhunt/commit/3f426ec)) 83 | 84 | 85 | ### Features 86 | 87 | * **build:** Change mode to universial ([618293f](https://github.com/apertureless/colourhunt/commit/618293f)) 88 | * **create:** Add preview header to creation page ([7a9e193](https://github.com/apertureless/colourhunt/commit/7a9e193)) 89 | * **drift:** Add driftjs for feedback as nuxt plugin ([071a825](https://github.com/apertureless/colourhunt/commit/071a825)) 90 | * **feedback:** Add feedback form ([3dff6a8](https://github.com/apertureless/colourhunt/commit/3dff6a8)) 91 | * **feedback-button:** Add feedback button ([e7bd66c](https://github.com/apertureless/colourhunt/commit/e7bd66c)) 92 | * **footer:** Add footer with social links and about page ([f26a75a](https://github.com/apertureless/colourhunt/commit/f26a75a)) 93 | * **lazy-load:** Add pagination and lazy loading ([a34ec9c](https://github.com/apertureless/colourhunt/commit/a34ec9c)) 94 | * **seo:** Add custom page for social media image generation ([8ad268b](https://github.com/apertureless/colourhunt/commit/8ad268b)) 95 | * **seo:** Add GA plugin and cookie-law ([1fac2a6](https://github.com/apertureless/colourhunt/commit/1fac2a6)) 96 | * **upvote:** Add triangle to indicate upvote function ([9e5b99c](https://github.com/apertureless/colourhunt/commit/9e5b99c)) 97 | 98 | 99 | 100 | 101 | # [1.4.0](https://github.com/apertureless/colourhunt/compare/v1.3.0...v1.4.0) (2018-03-27) 102 | 103 | 104 | ### Bug Fixes 105 | 106 | * **auth:** Add middleware for no-auth route and redirect on auth ([c37a3d0](https://github.com/apertureless/colourhunt/commit/c37a3d0)) 107 | * **build:** Fix illegal characters in package.json name ([1e4e2b2](https://github.com/apertureless/colourhunt/commit/1e4e2b2)) 108 | * **seo:** Add better meta description ([a4f8685](https://github.com/apertureless/colourhunt/commit/a4f8685)) 109 | * **seo:** Fix image path and meta information ([6e5bc13](https://github.com/apertureless/colourhunt/commit/6e5bc13)) 110 | * **seo:** Fix ogImage path ([54055e2](https://github.com/apertureless/colourhunt/commit/54055e2)) 111 | 112 | 113 | ### Features 114 | 115 | * **seo:** Add facebook meta tags ([0c91e8f](https://github.com/apertureless/colourhunt/commit/0c91e8f)) 116 | * **seo:** Add twitter card ([ca86a32](https://github.com/apertureless/colourhunt/commit/ca86a32)) 117 | 118 | 119 | 120 | 121 | # [1.3.0](https://github.com/apertureless/colourhunt/compare/v1.2.0...v1.3.0) (2018-03-27) 122 | 123 | 124 | ### Bug Fixes 125 | 126 | * **add-swatch:** Fix line-height to align the plus sign ([36fb4b7](https://github.com/apertureless/colourhunt/commit/36fb4b7)) 127 | * **button:** Remove background color of clean button ([a6c616c](https://github.com/apertureless/colourhunt/commit/a6c616c)) 128 | * **code-preview:** Fix code preview formatting ([7221b87](https://github.com/apertureless/colourhunt/commit/7221b87)) 129 | * **color-preview:** Fix border radius on detail page ([f2c9772](https://github.com/apertureless/colourhunt/commit/f2c9772)) 130 | * **create:** Add character limitation for palette name ([690c6ea](https://github.com/apertureless/colourhunt/commit/690c6ea)) 131 | * **style:** Add normalize css ([c763c7e](https://github.com/apertureless/colourhunt/commit/c763c7e)) 132 | 133 | 134 | ### Features 135 | 136 | * **code-preview:** Add code preview section ([2a881ec](https://github.com/apertureless/colourhunt/commit/2a881ec)) 137 | * **voting:** Add user voting ([0dc95d2](https://github.com/apertureless/colourhunt/commit/0dc95d2)) 138 | 139 | 140 | 141 | 142 | # [1.2.0](https://github.com/apertureless/colourhunt/compare/v1.1.0...v1.2.0) (2018-03-25) 143 | 144 | 145 | ### Bug Fixes 146 | 147 | * **create:** Add validation and error logging ([35bfef2](https://github.com/apertureless/colourhunt/commit/35bfef2)) 148 | 149 | 150 | ### Features 151 | 152 | * **create:** Add user relation to create mutation ([c6803c7](https://github.com/apertureless/colourhunt/commit/c6803c7)) 153 | * **create:** Secure create page with auth middleware ([b5c7221](https://github.com/apertureless/colourhunt/commit/b5c7221)) 154 | * **generation:** Add dynamic routes generation ([8823d48](https://github.com/apertureless/colourhunt/commit/8823d48)) 155 | * **login:** Add login / signup flow ([294bce7](https://github.com/apertureless/colourhunt/commit/294bce7)) 156 | * **pwa:** Add nuxt pwa module and favicons ([0e7e3fd](https://github.com/apertureless/colourhunt/commit/0e7e3fd)) 157 | 158 | 159 | 160 | 161 | # 1.1.0 (2018-03-24) 162 | 163 | 164 | ### Features 165 | 166 | * **structure:** Refactor & move to nuxtjs ([0d7c550](https://github.com/apertureless/colourhunt/commit/0d7c550)) 167 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Buy Me A Coffee 2 | 3 | # Colour Hunt 4 | 5 | This is the official repository of [Colour Hunt](https://www.colourhunt.com). This project is build with Vue.js, Nuxt and Graph.cool 6 | 7 | ## Contribution 8 | 9 | Feel free to contribute. 10 | 11 | ## Build Setup 12 | 13 | ``` bash 14 | # install dependencies 15 | $ npm install # Or yarn install 16 | 17 | # serve with hot reload at localhost:3000 18 | $ npm run dev 19 | 20 | # build for production and launch server 21 | $ npm run build 22 | $ npm start 23 | 24 | # generate static project 25 | $ npm run generate 26 | ``` 27 | 28 | For detailed explanation on how things work, checkout the [Nuxt.js docs](https://github.com/nuxt/nuxt.js). 29 | -------------------------------------------------------------------------------- /apollo/client-configs/default.js: -------------------------------------------------------------------------------- 1 | import { ApolloLink } from 'apollo-link' 2 | import { HttpLink } from 'apollo-link-http' 3 | import { InMemoryCache } from 'apollo-cache-inmemory' 4 | import { GC_AUTH_TOKEN } from '~/constants/settings' 5 | 6 | export default (ctx) => { 7 | const httpLink = new HttpLink({ uri: 'https://api.graph.cool/simple/v1/cj23bdhqjezf401017zjz3w27' }) 8 | 9 | // middleware 10 | const middlewareLink = new ApolloLink((operation, forward) => { 11 | // auth token 12 | const token = process.client ? localStorage.getItem(GC_AUTH_TOKEN) : null 13 | operation.setContext({ 14 | headers: { 15 | Authorization: token ? `Bearer ${token}` : null 16 | } 17 | }) 18 | return forward(operation) 19 | }) 20 | // const link = httpLink 21 | const link = middlewareLink.concat(httpLink) 22 | return { 23 | link, 24 | cache: new InMemoryCache() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /apollo/mutations/CreateClick.gql: -------------------------------------------------------------------------------- 1 | mutation createPaletteStat ($paletteId: ID!, $clicks: Int!) { 2 | createPaletteStat (paletteId: $paletteId, clicks: $clicks) { 3 | id 4 | clicks 5 | palette { 6 | id 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /apollo/mutations/CreatePalette.gql: -------------------------------------------------------------------------------- 1 | mutation createPalette($title: String!, $colors: [String!]!, $userId: ID!) { 2 | createPalette(title: $title, colors: $colors, userId: $userId) { 3 | id 4 | title 5 | colors 6 | user { 7 | id 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apollo/mutations/CreateUser.gql: -------------------------------------------------------------------------------- 1 | mutation CreateUserMutation($email: String!, $password: String!) { 2 | signupUser( 3 | email: $email, 4 | password: $password 5 | ) { 6 | id 7 | } 8 | 9 | authenticateUser( 10 | email: $email, 11 | password: $password 12 | ) { 13 | id 14 | token 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apollo/mutations/CreateVote.gql: -------------------------------------------------------------------------------- 1 | mutation createVote($userId: ID!, $paletteId: ID!) { 2 | createVote(userId: $userId, paletteId: $paletteId) { 3 | id 4 | palette { 5 | votes { 6 | id 7 | user { 8 | id 9 | } 10 | } 11 | } 12 | user { 13 | id 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apollo/mutations/LoginUser.gql: -------------------------------------------------------------------------------- 1 | mutation SigninUserMutation($email: String!, $password: String!) { 2 | authenticateUser( 3 | email: $email, 4 | password: $password 5 | ) { 6 | token, 7 | id 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /apollo/mutations/UpdateClick.gql: -------------------------------------------------------------------------------- 1 | mutation updateClickCount ($id: ID!, $clicks: Int!) { 2 | updatePaletteStat ( 3 | id: $id, 4 | clicks: $clicks 5 | ) { 6 | id 7 | clicks 8 | palette { 9 | id 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apollo/queries/AllPalettes.gql: -------------------------------------------------------------------------------- 1 | query allPalettes ($first: Int, $skip: Int, $orderBy: PaletteOrderBy) { 2 | allPalettes(first: $first, skip: $skip, orderBy: $orderBy) { 3 | id 4 | title 5 | colors 6 | stats { 7 | id 8 | clicks 9 | } 10 | votes { 11 | id 12 | user { 13 | id 14 | } 15 | } 16 | } 17 | totalCount: _allPalettesMeta { 18 | count 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apollo/queries/Palette.gql: -------------------------------------------------------------------------------- 1 | query palette($id: ID!) { 2 | Palette(id: $id) { 3 | id 4 | colors 5 | title 6 | stats { 7 | id 8 | clicks 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /assets/README.md: -------------------------------------------------------------------------------- 1 | # ASSETS 2 | 3 | This directory contains your un-compiled assets such as LESS, SASS, or JavaScript. 4 | 5 | More information about the usage of this directory in the documentation: 6 | https://nuxtjs.org/guide/assets#webpacked 7 | 8 | **This directory is not required, you can delete it if you don't want to use it.** 9 | -------------------------------------------------------------------------------- /assets/images/clipboard-cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/assets/images/clipboard-cursor.png -------------------------------------------------------------------------------- /assets/scss/colors.scss: -------------------------------------------------------------------------------- 1 | $colors: ( 2 | highlight: #FF006C, 3 | background-base: #F4F5F5, 4 | background-light: #fff, 5 | border-color: #EBEBEB, 6 | text-color: #847E80 7 | ); 8 | 9 | @function color($name) { 10 | @if map-has-key(getColors(), $name) { 11 | @return map-get(getColors(), $name); 12 | } @else { 13 | @warn "Color not found: #{$name}"; 14 | @return #000; 15 | } 16 | } 17 | 18 | @function getColors() { 19 | @return $colors; 20 | } 21 | -------------------------------------------------------------------------------- /assets/scss/global.scss: -------------------------------------------------------------------------------- 1 | @import "includes"; 2 | 3 | body { 4 | -ms-text-size-adjust: 100%; 5 | -webkit-text-size-adjust: 100%; 6 | color: color(text-color); 7 | font-family: $base-font-family; 8 | font-feature-settings: "kern", "liga", "pnum"; 9 | font-size: $base-font-size; 10 | line-height: $base-line-height; 11 | -webkit-font-smoothing: antialiased; 12 | margin: 0; 13 | background: color(background-base); 14 | } 15 | 16 | h1, h2, h3, h4 { 17 | font-family: $heading-font-family; 18 | } 19 | 20 | a { 21 | text-decoration: none; 22 | } 23 | 24 | 25 | .button { 26 | font-size: rem(12); 27 | text-transform: uppercase; 28 | font-weight: bold; 29 | color: color(text-color); 30 | border: 1px solid color(border-color); 31 | padding: rem(10) rem(15); 32 | background: color(background-light); 33 | border-radius: $base-border-radius; 34 | appearance: none; 35 | cursor: pointer; 36 | 37 | @include hover-active-states() { 38 | background: color(background-base); 39 | } 40 | 41 | &.is-active { 42 | background: color(background-base); 43 | } 44 | 45 | @include variant(small) { 46 | padding: rem(5) rem(10); 47 | } 48 | 49 | & + .button { 50 | margin-left: rem(8); 51 | } 52 | } 53 | 54 | .button-clean { 55 | appearance: none; 56 | border: none; 57 | display: block; 58 | cursor: pointer; 59 | background: transparent; 60 | font-size: rem(13); 61 | color: lighten(#847E80, 10%); 62 | margin: rem(16) 0; 63 | @include hover-active-states () { 64 | color: color(highlight); 65 | } 66 | } 67 | 68 | 69 | .Content { 70 | @include container(); 71 | 72 | @include has(list) { 73 | margin: rem(50) rem(-10); 74 | display: flex; 75 | flex-flow: row wrap; 76 | } 77 | 78 | @include has(footer) { 79 | > .button { 80 | display: block; 81 | margin: rem(16) auto; 82 | } 83 | } 84 | } 85 | 86 | 87 | label { 88 | display: block; 89 | font-size: rem(16); 90 | font-weight: bold; 91 | margin-bottom: rem(8); 92 | } 93 | 94 | input { 95 | background-color: #f1f1f1; 96 | border: 1px solid #f1f1f1; 97 | border-radius: rem(2); 98 | box-sizing: border-box; 99 | font-size: rem(14); 100 | padding: rem(13); 101 | width: 100%; 102 | margin-bottom: rem(16); 103 | display: block; 104 | } 105 | 106 | textarea { 107 | display: block; 108 | background-color: #f1f1f1; 109 | border: 1px solid #f1f1f1; 110 | border-radius: rem(2); 111 | box-sizing: border-box; 112 | font-size: rem(14); 113 | padding: rem(13); 114 | width: 100%; 115 | margin-bottom: rem(16); 116 | resize: vertical; 117 | } 118 | 119 | .card { 120 | border-radius: $base-border-radius; 121 | background: color(background-light); 122 | padding: rem(15); 123 | } 124 | 125 | fieldset { 126 | border: none; 127 | padding: 0; 128 | margin: 0; 129 | legend { 130 | font-weight: bold; 131 | padding: 0; 132 | margin: 0; 133 | font-size: rem(22); 134 | color: color(highlight); 135 | margin-bottom: rem(32); 136 | display: block; 137 | text-align: center; 138 | } 139 | } 140 | 141 | 142 | .alert { 143 | padding: 0; 144 | list-style: none; 145 | border-left: rem(4) solid currentColor; 146 | 147 | &.is-error { 148 | color: red; 149 | } 150 | } 151 | 152 | .alert-item { 153 | font-weight: bold; 154 | margin-left: rem(8); 155 | } 156 | 157 | 158 | .Color-detail { 159 | background: color(background-light); 160 | border-radius: $base-border-radius; 161 | border: 1px solid color(border-color); 162 | margin: rem(10); 163 | margin-top: rem(50); 164 | 165 | @include has(header) { 166 | 167 | } 168 | 169 | @include has(title) { 170 | color: color(text-color); 171 | font-size: rem(20); 172 | } 173 | 174 | @include has(content) { 175 | padding: rem(30); 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /assets/scss/includes.scss: -------------------------------------------------------------------------------- 1 | @import "~@nextindex/next-scss"; 2 | @import "mixins"; 3 | @import "colors"; 4 | @import "variables.scss"; 5 | -------------------------------------------------------------------------------- /assets/scss/mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin container() { 2 | max-width: $base-container-width; 3 | margin: 0 auto; 4 | padding: 0 20px; 5 | width: 100%; 6 | box-sizing: border-box; 7 | } 8 | 9 | @mixin fill-parent() { 10 | position: absolute; 11 | left: 0; 12 | top: 0; 13 | width: 100%; 14 | height: 100%; 15 | } 16 | 17 | [v-cloak] { 18 | display: none; 19 | } 20 | 21 | @mixin unselectable { 22 | -webkit-user-select: none; 23 | -moz-user-select: none; 24 | user-select: none; 25 | cursor: default; 26 | } 27 | 28 | @mixin unclickable { 29 | @include unselectable; 30 | pointer-events: none; 31 | } 32 | 33 | @mixin hover-active-states() { 34 | &:hover, &:focus, &:active { 35 | @content; 36 | } 37 | } 38 | 39 | @mixin center-vertically() { 40 | position: absolute; 41 | top: 50%; 42 | transform: translateY(-50%); 43 | } 44 | 45 | @mixin center-horizontally() { 46 | position: absolute; 47 | left: 50%; 48 | transform: translateX(-50%); 49 | } 50 | 51 | @mixin center() { 52 | @include center-vertically(); 53 | @include center-horizontally(); 54 | transform: translateX(-50%) translateY(-50%); 55 | } 56 | 57 | @mixin unstyled-list() { 58 | list-style: none; 59 | margin: 0; 60 | padding: 0; 61 | } 62 | -------------------------------------------------------------------------------- /assets/scss/variables.scss: -------------------------------------------------------------------------------- 1 | $base-font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif; 2 | $heading-font-family: $base-font-family; 3 | $base-font-size: rem(16); 4 | $base-line-height: 1.3; 5 | $base-border-radius: rem(5); 6 | $base-container-width: rem(980); 7 | -------------------------------------------------------------------------------- /components/FooterNav.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 33 | 34 | 75 | -------------------------------------------------------------------------------- /components/README.md: -------------------------------------------------------------------------------- 1 | # COMPONENTS 2 | 3 | The components directory contains your Vue.js Components. 4 | Nuxt.js doesn't supercharge these components. 5 | 6 | **This directory is not required, you can delete it if you don't want to use it.** 7 | -------------------------------------------------------------------------------- /components/color-palette/CodePreview.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 36 | 37 | -------------------------------------------------------------------------------- /components/color-palette/ColorPalette.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 45 | 46 | 123 | -------------------------------------------------------------------------------- /components/color-palette/ColorPreview.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 44 | 45 | 89 | -------------------------------------------------------------------------------- /components/color-palette/Upvote.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 88 | 89 | 100 | -------------------------------------------------------------------------------- /components/shared/Banner.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 40 | 41 | 69 | -------------------------------------------------------------------------------- /components/shared/Spinner.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 24 | 25 | 80 | -------------------------------------------------------------------------------- /components/swatch/AddSwatch.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | 19 | 39 | -------------------------------------------------------------------------------- /components/swatch/ColorSwatch.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 34 | 35 | 68 | -------------------------------------------------------------------------------- /constants/settings.js: -------------------------------------------------------------------------------- 1 | export const GC_USER_ID = 'graphcool-user-id' 2 | export const GC_AUTH_TOKEN = 'graphcool-auth-token' 3 | export const PALETTES_PER_PAGE = 21 4 | -------------------------------------------------------------------------------- /layouts/README.md: -------------------------------------------------------------------------------- 1 | # LAYOUTS 2 | 3 | This directory contains your Application Layouts. 4 | 5 | More information about the usage of this directory in the documentation: 6 | https://nuxtjs.org/guide/views#layouts 7 | 8 | **This directory is not required, you can delete it if you don't want to use it.** 9 | -------------------------------------------------------------------------------- /layouts/clean.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 21 | -------------------------------------------------------------------------------- /middleware/README.md: -------------------------------------------------------------------------------- 1 | # MIDDLEWARE 2 | 3 | This directory contains your Application Middleware. 4 | The middleware lets you define custom function to be ran before rendering a page or a group of pages (layouts). 5 | 6 | More information about the usage of this directory in the documentation: 7 | https://nuxtjs.org/guide/routing#middleware 8 | 9 | **This directory is not required, you can delete it if you don't want to use it.** 10 | -------------------------------------------------------------------------------- /middleware/auth.js: -------------------------------------------------------------------------------- 1 | export default function ({ store, redirect }) { 2 | if (!store.state.auth.isLoggedIn) { 3 | return redirect('/login') 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /middleware/no-auth.js: -------------------------------------------------------------------------------- 1 | export default function ({ store, redirect }) { 2 | if (store.state.auth.isLoggedIn) { 3 | return redirect('/') 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | const { createApolloFetch } = require('apollo-fetch') 2 | 3 | module.exports = { 4 | mode: 'spa', 5 | extractCSS: true, 6 | css: [ 7 | 'node_modules/modern-normalize/modern-normalize.css', 8 | '~/assets/scss/global.scss' 9 | ], 10 | modules: [ 11 | '@nuxtjs/apollo', 12 | '@nuxtjs/sitemap', 13 | ['@nuxtjs/pwa', { 14 | meta: false 15 | }] 16 | ], 17 | apollo: { 18 | clientConfigs: { 19 | default: '~/apollo/client-configs/default.js' 20 | } 21 | }, 22 | sitemap: { 23 | generate: true, 24 | hostname: 'https://www.colourhunt.com', 25 | async routes () { 26 | const uri = 'https://api.graph.cool/simple/v1/cj23bdhqjezf401017zjz3w27' 27 | const apolloFetch = createApolloFetch({ uri }) 28 | const query = ` 29 | query allPalettes { 30 | allPalettes { 31 | id 32 | } 33 | } 34 | ` 35 | 36 | try { 37 | const { data } = await apolloFetch({ query }) 38 | const dynamicRoutes = data.allPalettes.map(palette => `/palette/${palette.id}`) 39 | return dynamicRoutes 40 | } catch (err) { 41 | console.error('🔥 Error:', err) 42 | } 43 | } 44 | }, 45 | generate: { 46 | fallback: true, 47 | async routes () { 48 | const uri = 'https://api.graph.cool/simple/v1/cj23bdhqjezf401017zjz3w27' 49 | const apolloFetch = createApolloFetch({ uri }) 50 | const query = ` 51 | query allPalettes { 52 | allPalettes { 53 | id 54 | } 55 | } 56 | ` 57 | const staticRoutes = [ 58 | '/login', 59 | '/create', 60 | '/about' 61 | ] 62 | 63 | try { 64 | const { data } = await apolloFetch({ query }) 65 | const dynamicRoutes = data.allPalettes.map(palette => `/palette/${palette.id}`) 66 | const dynamicImageRoutes = data.allPalettes.map(palette => `/image/${palette.id}`) 67 | return staticRoutes 68 | .concat(dynamicRoutes) 69 | .concat(dynamicImageRoutes) 70 | } catch (err) { 71 | console.error('🔥 Error:', err) 72 | } 73 | } 74 | }, 75 | /* 76 | ** Headers of the page 77 | */ 78 | head: { 79 | title: 'Colour Hunt | Beautiful color palettes for your next project!', 80 | meta: [ 81 | { charset: 'utf-8' }, 82 | { name: 'viewport', content: 'width=device-width, initial-scale=1' }, 83 | { hid: 'description', name: 'description', content: '🎨 Colour Hunt is a community driven color palette collection. Grab beautiful color palettes for your next project.' }, 84 | { name: 'msapplication-TileColor', content: '#fc136d'}, 85 | { name: 'msapplication-TileImage', content: '/mstile-144x144.png'}, 86 | { name: 'theme-color', content: '#fc136d'} 87 | ], 88 | link: [ 89 | { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' }, 90 | { rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon-32x32.png' }, 91 | { rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon-16x16.png' }, 92 | { rel: 'manifest', href: '/site.webmanifest' }, 93 | { rel: 'mask-icon', color: '#fc136d', href: '/safari-pinned-tab.svg' } 94 | ] 95 | }, 96 | /* 97 | ** Customize the progress bar color 98 | */ 99 | loading: { color: '#FC136D' }, 100 | /* 101 | ** Build configuration 102 | */ 103 | build: { 104 | /* 105 | ** Run ESLint on save 106 | */ 107 | extend (config, { isDev, isClient }) { 108 | if (isDev && isClient) { 109 | config.module.rules.push({ 110 | enforce: 'pre', 111 | test: /\.(js|vue)$/, 112 | loader: 'eslint-loader', 113 | exclude: /(node_modules)/ 114 | }) 115 | } 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "colorhunt", 3 | "version": "1.8.0", 4 | "description": "🎨 Colour Hunt is a community driven color palette collection. Grab beautiful color palettes for your next project.", 5 | "author": "Jakub Juszczak ", 6 | "private": true, 7 | "scripts": { 8 | "dev": "nuxt", 9 | "build": "nuxt build", 10 | "start": "nuxt start", 11 | "generate": "nuxt generate", 12 | "lint": "eslint --ext .js,.vue --ignore-path .gitignore .", 13 | "precommit": "npm run lint" 14 | }, 15 | "dependencies": { 16 | "@nuxtjs/apollo": "^3.0.6", 17 | "@nuxtjs/google-analytics": "^2.0.2", 18 | "@nuxtjs/pwa": "^2.0.8", 19 | "@nuxtjs/sitemap": "^0.0.3", 20 | "apollo-cache-inmemory": "^1.1.12", 21 | "apollo-client": "^2.2.8", 22 | "apollo-fetch": "^0.7.0", 23 | "apollo-link": "^1.2.1", 24 | "apollo-link-http": "^1.5.3", 25 | "clipboard": "^2.0.0", 26 | "graphql": "^0.13.2", 27 | "graphql-tag": "^2.8.0", 28 | "nuxt": "^1.0.0", 29 | "prismjs": "^1.13.0", 30 | "vue-apollo": "^3.0.0-beta.5", 31 | "vue-clickaway": "^2.2.1", 32 | "vue-color": "^2.4.6", 33 | "vue-cookie-law": "^1.4.0", 34 | "vue-password-strength-meter": "^1.2.1", 35 | "vue-prism-component": "^1.0.1", 36 | "vue-tabs-component": "^1.4.0", 37 | "zxcvbn": "^4.4.2" 38 | }, 39 | "devDependencies": { 40 | "@nextindex/next-scss": "^1.2.1", 41 | "autoprefixer": "^8.2.0", 42 | "babel-eslint": "^8.2.1", 43 | "eslint": "^4.19.1", 44 | "eslint-friendly-formatter": "^4.0.1", 45 | "eslint-loader": "^2.0.0", 46 | "eslint-plugin-vue": "^4.4.0", 47 | "glob-all": "^3.1.0", 48 | "modern-normalize": "^0.4.0", 49 | "node-sass": "^4.8.3", 50 | "purgecss-webpack-plugin": "^0.22.0", 51 | "sass-loader": "^6.0.7", 52 | "tailwindcss": "^0.5.1" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /pages/README.md: -------------------------------------------------------------------------------- 1 | # PAGES 2 | 3 | This directory contains your Application Views and Routes. 4 | The framework reads all the .vue files inside this directory and creates the router of your application. 5 | 6 | More information about the usage of this directory in the documentation: 7 | https://nuxtjs.org/guide/routing 8 | -------------------------------------------------------------------------------- /pages/about.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 17 | 37 | -------------------------------------------------------------------------------- /pages/create.vue: -------------------------------------------------------------------------------- 1 | 62 | 63 | 212 | 213 | 242 | -------------------------------------------------------------------------------- /pages/image/_id.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 49 | 50 | 109 | -------------------------------------------------------------------------------- /pages/index.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 107 | 108 | 113 | -------------------------------------------------------------------------------- /pages/legal.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /pages/login.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 104 | 105 | 118 | -------------------------------------------------------------------------------- /pages/palette/_id.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 141 | 142 | 236 | -------------------------------------------------------------------------------- /plugins/README.md: -------------------------------------------------------------------------------- 1 | # PLUGINS 2 | 3 | This directory contains your Javascript plugins that you want to run before instantiating the root vue.js application. 4 | 5 | More information about the usage of this directory in the documentation: 6 | https://nuxtjs.org/guide/plugins 7 | 8 | **This directory is not required, you can delete it if you don't want to use it.** 9 | -------------------------------------------------------------------------------- /static/README.md: -------------------------------------------------------------------------------- 1 | # STATIC 2 | 3 | This directory contains your static files. 4 | Each file inside this directory is mapped to /. 5 | 6 | Example: /static/robots.txt is mapped as /robots.txt. 7 | 8 | More information about the usage of this directory in the documentation: 9 | https://nuxtjs.org/guide/assets#static 10 | 11 | **This directory is not required, you can delete it if you don't want to use it.** 12 | -------------------------------------------------------------------------------- /static/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/android-chrome-192x192.png -------------------------------------------------------------------------------- /static/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/android-chrome-512x512.png -------------------------------------------------------------------------------- /static/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /static/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /static/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /static/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /static/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /static/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/apple-touch-icon.png -------------------------------------------------------------------------------- /static/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #fc136d 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/favicon-16x16.png -------------------------------------------------------------------------------- /static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/favicon-32x32.png -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/favicon.ico -------------------------------------------------------------------------------- /static/google3ecbc228f0af15c0.html: -------------------------------------------------------------------------------- 1 | google-site-verification: google3ecbc228f0af15c0.html -------------------------------------------------------------------------------- /static/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/icon.png -------------------------------------------------------------------------------- /static/images/colourhunt-intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/images/colourhunt-intro.png -------------------------------------------------------------------------------- /static/images/colourhunt-twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/images/colourhunt-twitter.png -------------------------------------------------------------------------------- /static/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/mstile-144x144.png -------------------------------------------------------------------------------- /static/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/mstile-150x150.png -------------------------------------------------------------------------------- /static/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/mstile-310x150.png -------------------------------------------------------------------------------- /static/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/mstile-310x310.png -------------------------------------------------------------------------------- /static/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apertureless/colourhunt/48afc10055f86b836174f596e20537faf50ff865/static/mstile-70x70.png -------------------------------------------------------------------------------- /static/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Colour Hunt", 3 | "short_name": "Colour Hunt", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#fc136d", 17 | "background_color": "#fc136d", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /static/sw.js: -------------------------------------------------------------------------------- 1 | importScripts('/_nuxt/workbox.3de3418b.js') 2 | 3 | const workboxSW = new self.WorkboxSW({ 4 | "cacheId": "colorhunt", 5 | "clientsClaim": true, 6 | "directoryIndex": "/" 7 | }) 8 | 9 | workboxSW.precache([ 10 | { 11 | "url": "/_nuxt/18.d50a5e15ae8d099f6c34.js", 12 | "revision": "be2c13a9a65f7f136c7c6bfc6e7c1afb" 13 | }, 14 | { 15 | "url": "/_nuxt/add-swatch.9f888e4a684cc74b1d07.js", 16 | "revision": "d20ca38b37807221c93e72146c4febfd" 17 | }, 18 | { 19 | "url": "/_nuxt/app.32026a9ec1b8a16afd46.js", 20 | "revision": "04ec4c3360c6eb1daea556b15d50b364" 21 | }, 22 | { 23 | "url": "/_nuxt/code-preview.97f392f073809e21d5ef.js", 24 | "revision": "5a87b01f19dd30f24f9ea5fd2e6e6e25" 25 | }, 26 | { 27 | "url": "/_nuxt/color-palette.552d37fe3523e5bd135d.js", 28 | "revision": "457e1b5e2798f0e8ee74ad128e4b4eea" 29 | }, 30 | { 31 | "url": "/_nuxt/color-preview.515d228f902ab96c87dd.js", 32 | "revision": "10a67d7689ceec5f8a70e42fcee7387a" 33 | }, 34 | { 35 | "url": "/_nuxt/layouts/clean.3b9bf43ab5385ffab0e2.js", 36 | "revision": "d7a512b8d0749e2cff14f1bdd4cd1b7b" 37 | }, 38 | { 39 | "url": "/_nuxt/layouts/default.b5a2739398d1dd12bdce.js", 40 | "revision": "63e6f0e1f3fb9d469ae9dece1163b8ff" 41 | }, 42 | { 43 | "url": "/_nuxt/manifest.b6ea59756f1b30d800cf.js", 44 | "revision": "88cd971a69fa7cdb6b5eabf625aee2bc" 45 | }, 46 | { 47 | "url": "/_nuxt/pages/about.7e70fc695b57adc96eb9.js", 48 | "revision": "b91077bcff67d01a84b7e1f068bb76af" 49 | }, 50 | { 51 | "url": "/_nuxt/pages/create.aacddc2488b06369732b.js", 52 | "revision": "35b358a5a1c5f62419da02183d41860d" 53 | }, 54 | { 55 | "url": "/_nuxt/pages/image/_id.15a6b7860b0970caa0c4.js", 56 | "revision": "ee699a09c65ec15ed25330ef3adf77f5" 57 | }, 58 | { 59 | "url": "/_nuxt/pages/index.7df7b4450c072ebdbab6.js", 60 | "revision": "893d7c35c62230ec3462a222ab86f88d" 61 | }, 62 | { 63 | "url": "/_nuxt/pages/legal.165724b3bc43f58a358d.js", 64 | "revision": "5a5e9a06babbdec8a9de9ed55358fd28" 65 | }, 66 | { 67 | "url": "/_nuxt/pages/login.8405b5b7e5de692d83ec.js", 68 | "revision": "b11b4e76eaae105d3efd152a120fa3c0" 69 | }, 70 | { 71 | "url": "/_nuxt/pages/palette/_id.34221f95bb785f258137.js", 72 | "revision": "8df4cab9acb049c878cd37fcbf67ec5e" 73 | }, 74 | { 75 | "url": "/_nuxt/spinner.4189c29c1486227319b6.js", 76 | "revision": "b349e1ed7d3e52eb3094902598e9aae0" 77 | }, 78 | { 79 | "url": "/_nuxt/swatch.3aa36e9551c424b6560d.js", 80 | "revision": "8336a6d4dd821a944500effbccd96b0b" 81 | }, 82 | { 83 | "url": "/_nuxt/vendor.61ad983598342cc64e00.js", 84 | "revision": "4b158ab90a405dbc9881b610e71b581f" 85 | }, 86 | { 87 | "url": "/_nuxt/vue-password.f5becf067202f0a6f514.js", 88 | "revision": "9969dc001777f2203514a8f839a715d1" 89 | } 90 | ]) 91 | 92 | 93 | workboxSW.router.registerRoute(new RegExp('/_nuxt/.*'), workboxSW.strategies.cacheFirst({}), 'GET') 94 | 95 | workboxSW.router.registerRoute(new RegExp('/.*'), workboxSW.strategies.networkFirst({}), 'GET') 96 | 97 | -------------------------------------------------------------------------------- /store/README.md: -------------------------------------------------------------------------------- 1 | # STORE 2 | 3 | This directory contains your Vuex Store files. 4 | Vuex Store option is implemented in the Nuxt.js framework. 5 | Creating a index.js file in this directory activate the option in the framework automatically. 6 | 7 | More information about the usage of this directory in the documentation: 8 | https://nuxtjs.org/guide/vuex-store 9 | 10 | **This directory is not required, you can delete it if you don't want to use it.** 11 | -------------------------------------------------------------------------------- /store/getters.js: -------------------------------------------------------------------------------- 1 | export const isLoggedIn = (state) => state.auth.isLoggedIn 2 | export const userId = (state) => state.auth.userId 3 | export const authErrors = (state) => state.auth.error 4 | -------------------------------------------------------------------------------- /store/index.js: -------------------------------------------------------------------------------- 1 | import Vuex from 'vuex' 2 | import * as getters from './getters' 3 | import modules from './modules' 4 | 5 | const debug = process.env.NODE_ENV !== 'production' 6 | 7 | const createStore = () => { 8 | return new Vuex.Store({ 9 | getters, 10 | modules, 11 | strict: debug, 12 | plugins: [] 13 | }) 14 | } 15 | 16 | export default createStore 17 | -------------------------------------------------------------------------------- /store/modules/auth.js: -------------------------------------------------------------------------------- 1 | import * as types from '../types' 2 | 3 | import CREATE_USER from '~/apollo/mutations/CreateUser.gql' 4 | import LOGIN_USER from '~/apollo/mutations/LoginUser.gql' 5 | 6 | import { GC_USER_ID, GC_AUTH_TOKEN } from '~/constants/settings' 7 | import { graphQLErrorMessages } from '~/utils/' 8 | 9 | const state = { 10 | isLoggedIn: !!localStorage.getItem(GC_USER_ID), 11 | userId: localStorage.getItem(GC_USER_ID), 12 | pending: false, 13 | error: null 14 | } 15 | 16 | const actions = { 17 | async login ({commit}, credentials) { 18 | const { email, password } = credentials 19 | const client = this.app.apolloProvider.defaultClient 20 | commit(types.LOGIN) 21 | try { 22 | const res = await client.mutate({ 23 | mutation: LOGIN_USER, 24 | variables: { 25 | email, 26 | password 27 | } 28 | }) 29 | 30 | const { id, token } = res.data.authenticateUser 31 | localStorage.setItem(GC_USER_ID, id) 32 | localStorage.setItem(GC_AUTH_TOKEN, token) 33 | commit(types.LOGIN_SUCCESS, id) 34 | } catch (err) { 35 | const prettyError = graphQLErrorMessages(err) 36 | commit(types.LOGIN_FAILED, prettyError) 37 | throw new Error(prettyError) 38 | } 39 | }, 40 | async signup ({commit}, credentials) { 41 | const { email, password, name } = credentials 42 | const client = this.app.apolloProvider.defaultClient 43 | commit(types.SIGNUP) 44 | try { 45 | const res = await client.mutate({ 46 | mutation: CREATE_USER, 47 | variables: { 48 | name, 49 | email, 50 | password 51 | } 52 | }) 53 | 54 | const id = res.data.authenticateUser.id 55 | const token = res.data.authenticateUser.token 56 | localStorage.setItem(GC_USER_ID, id) 57 | localStorage.setItem(GC_AUTH_TOKEN, token) 58 | commit(types.SIGNUP_SUCCESS, id) 59 | } catch (err) { 60 | const prettyError = graphQLErrorMessages(err) 61 | commit(types.SIGNUP_FAILED, prettyError) 62 | throw new Error(prettyError) 63 | } 64 | 65 | }, 66 | logout ({commit}) { 67 | localStorage.removeItem(GC_USER_ID) 68 | localStorage.removeItem(GC_AUTH_TOKEN) 69 | commit(types.LOGOUT) 70 | } 71 | } 72 | 73 | const mutations = { 74 | [types.LOGIN] (state) { 75 | state.pending = true 76 | state.error = null 77 | }, 78 | [types.LOGIN_SUCCESS] (state, id) { 79 | state.isLoggedIn = true 80 | state.pending = false 81 | state.userId = id 82 | }, 83 | [types.LOGIN_FAILED] (state, error) { 84 | state.error = error 85 | state.pending = false 86 | }, 87 | [types.LOGOUT] (state) { 88 | state.isLoggedIn = false 89 | }, 90 | [types.SIGNUP] (state) { 91 | state.pending = true 92 | state.error = null 93 | }, 94 | [types.SIGNUP_SUCCESS] (state, id) { 95 | state.isLoggedIn = true 96 | state.pending = false 97 | state.userId = id 98 | }, 99 | [types.SIGNUP_FAILED] (state, error) { 100 | state.error = error 101 | state.pending = false 102 | } 103 | } 104 | 105 | export default { 106 | state, 107 | actions, 108 | mutations 109 | } 110 | -------------------------------------------------------------------------------- /store/modules/index.js: -------------------------------------------------------------------------------- 1 | const files = require.context('.', false, /\.js$/) 2 | const modules = {} 3 | 4 | files.keys().forEach((key) => { 5 | if (key === './index.js') return 6 | modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default 7 | }) 8 | 9 | export default modules 10 | -------------------------------------------------------------------------------- /store/types.js: -------------------------------------------------------------------------------- 1 | export const LOGIN = 'LOGIN' 2 | export const LOGIN_SUCCESS = 'LOGIN_SUCCESS' 3 | export const LOGIN_FAILED = 'LOGIN_FAILED' 4 | export const LOGOUT = 'LOGOUT' 5 | 6 | export const SIGNUP = 'SINGUP' 7 | export const SIGNUP_SUCCESS = 'SINGUP_SUCCESS' 8 | export const SIGNUP_FAILED = 'SINGUP_FAILED' 9 | -------------------------------------------------------------------------------- /utils/index.js: -------------------------------------------------------------------------------- 1 | export const graphQLErrorMessages = (errorsFromCatch) => { 2 | const errors = errorsFromCatch.graphQLErrors[0] 3 | const messages = [] 4 | 5 | if (errors.hasOwnProperty('functionError')) { 6 | const customErrors = errors.functionError 7 | messages.push(customErrors) 8 | } else { 9 | messages.push(errors.message) 10 | } 11 | 12 | return messages 13 | } 14 | 15 | 16 | const scss = (colors) => { 17 | return `${colors.map((color, i) => `$color-${i}: ${color}; 18 | `).join('')}` 19 | } 20 | 21 | const sass = (colors) => { 22 | return `${colors.map((color, i) => `$color-${i}: ${color} 23 | `).join('')}` 24 | } 25 | 26 | const less = (colors) => { 27 | return `${colors.map((color, i) => `@color-${i}: ${color}; 28 | `).join('')}` 29 | } 30 | 31 | const css = (colors) => { 32 | return `:root { 33 | ${colors.map((color, i) => ` --color-${i}: ${color}; 34 | `).join('')}}` 35 | } 36 | 37 | export const colorCode = ({type, colors}) => { 38 | let code 39 | switch (type) { 40 | case 'scss': 41 | code = scss(colors) 42 | break 43 | case 'sass': 44 | code = sass(colors) 45 | break 46 | case 'less': 47 | code = less(colors) 48 | break 49 | case 'css': 50 | code = css(colors) 51 | break 52 | } 53 | 54 | return code 55 | } 56 | --------------------------------------------------------------------------------