├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── config.yml ├── .gitignore ├── CHANGELOG.md ├── README.md ├── app.html ├── assets ├── README.md ├── css │ ├── app.scss │ ├── bulma.scss │ ├── buttons.scss │ ├── components.scss │ ├── components │ │ ├── forms │ │ │ └── RichText.scss │ │ ├── global │ │ │ ├── MainNav.scss │ │ │ └── Toolbar.scss │ │ └── hub │ │ │ ├── FileUpload.scss │ │ │ ├── MediaManager.scss │ │ │ ├── QuickViewPanel.scss │ │ │ └── SearchTable.scss │ ├── fonts.scss │ ├── form_elements.scss │ ├── layouts.scss │ ├── layouts │ │ ├── default.scss │ │ └── product.scss │ ├── mixins.scss │ ├── tables.scss │ ├── tabs.scss │ ├── tailwind.css │ └── utils.scss ├── fonts │ └── Inter │ │ ├── Inter-Black.woff │ │ ├── Inter-Black.woff2 │ │ ├── Inter-BlackItalic.woff │ │ ├── Inter-BlackItalic.woff2 │ │ ├── Inter-Bold.woff │ │ ├── Inter-Bold.woff2 │ │ ├── Inter-BoldItalic.woff │ │ ├── Inter-BoldItalic.woff2 │ │ ├── Inter-ExtraBold.woff │ │ ├── Inter-ExtraBold.woff2 │ │ ├── Inter-ExtraBoldItalic.woff │ │ ├── Inter-ExtraBoldItalic.woff2 │ │ ├── Inter-ExtraLight-BETA.woff │ │ ├── Inter-ExtraLight-BETA.woff2 │ │ ├── Inter-ExtraLightItalic-BETA.woff │ │ ├── Inter-ExtraLightItalic-BETA.woff2 │ │ ├── Inter-Italic.woff │ │ ├── Inter-Italic.woff2 │ │ ├── Inter-Light-BETA.woff │ │ ├── Inter-Light-BETA.woff2 │ │ ├── Inter-LightItalic-BETA.woff │ │ ├── Inter-LightItalic-BETA.woff2 │ │ ├── Inter-Medium.woff │ │ ├── Inter-Medium.woff2 │ │ ├── Inter-MediumItalic.woff │ │ ├── Inter-MediumItalic.woff2 │ │ ├── Inter-Regular.woff │ │ ├── Inter-Regular.woff2 │ │ ├── Inter-SemiBold.woff │ │ ├── Inter-SemiBold.woff2 │ │ ├── Inter-SemiBoldItalic.woff │ │ ├── Inter-SemiBoldItalic.woff2 │ │ ├── Inter-Thin-BETA.woff │ │ ├── Inter-Thin-BETA.woff2 │ │ ├── Inter-ThinItalic-BETA.woff │ │ ├── Inter-ThinItalic-BETA.woff2 │ │ ├── Inter-italic.var.woff2 │ │ ├── Inter-roman.var.woff2 │ │ ├── Inter.var.woff2 │ │ └── inter.css └── images │ └── sweet-jar.jpg ├── components └── README.md ├── env.example ├── getcandy.config.js ├── jest.config.js ├── locales ├── de.json ├── en.json └── fr.json ├── middleware ├── README.md ├── acl.js └── hub.js ├── nuxt.config.js ├── package.json ├── pages └── unauthorized.vue ├── plugins ├── README.md └── acl.js ├── static ├── README.md ├── favicon.png ├── getcandy-icon.svg ├── getcandy-logo.svg └── icon-sprite.svg ├── store ├── README.md └── index.js ├── tailwind.config.js └── test └── setup.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: getcandy 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Screenshots** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | **Additional context** 23 | Add any other context about the problem here. 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Feature Request 4 | url: https://github.com/getcandy/hub/discussions/categories/ideas 5 | about: 'Suggest any ideas you have using our discussion forums.' 6 | - name: Help 7 | url: https://github.com/getcandy/hub/discussions/categories/help 8 | about: 'If you have a question or need help, ask a question on the discussion forums.' 9 | - name: Documentation Issue 10 | url: https://github.com/getcandy/docs 11 | about: 'For documentation issues, suggest changes on our documentation repository.' 12 | - name: Kind Words 13 | url: https://github.com/getcandy/hub/discussions/categories/kind-words 14 | about: "Have something nice to say about GetCandy? We'd love to hear it!" 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /dist 2 | .DS_Store 3 | /node_modules 4 | /public/hot 5 | /.idea 6 | /.vscode 7 | /.vagrant 8 | /dist 9 | npm-debug.log 10 | yarn-error.log 11 | .env 12 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | # 0.12.0 3 | 4 | ### Upgrading 5 | 6 | **This release contains high impact changes. Please make sure you follow the upgrade guide carefully.** 7 | 8 | In `middleware/hub.js` 9 | 10 | Remove 11 | 12 | ``` 13 | app.$getcandy.setHttp(app.$axios) 14 | ``` 15 | 16 | Replace line `31` with: 17 | ``` 18 | --- store.commit('setLocale', find(languages.data.data, l => l.default).lang) 19 | +++ store.commit('setLocale', find(languages.data.data, l => l.default).code) 20 | ``` 21 | 22 | Replace line `47` with: 23 | 24 | ``` 25 | --- const customerGroups = await app.$getcandy.on('CustomerGroups').getCustomerGroups() 26 | +++ const customerGroups = await app.$getcandy.on('customer-groups', 'getCustomerGroups') 27 | ``` 28 | 29 | Update the `@getcandy` packages version constraint to `~0.12.0` except for `@getcandy/node-client` that should stay as it is. 30 | 31 | Update these other packages: 32 | 33 | - `@tailwindcss/ui` to `^0.7.0` 34 | - `@nuxtjs/tailwindcss` to `^3.4.2` 35 | 36 | Add `"@tailwindcss/forms": "^0.1.4"` to your dependencies. 37 | 38 | Replace your `tailwind.config.js` with the config below. Bear in mind to migrate any changes you may have done yourself. 39 | 40 | ```javascript 41 | module.exports = { 42 | theme: {}, 43 | variants: { 44 | extend: { 45 | opacity: ['disabled'] 46 | } 47 | }, 48 | plugins: [ 49 | require('@tailwindcss/ui') 50 | ], 51 | purge: { 52 | enabled: process.env.NODE_ENV === 'production', 53 | content: [ 54 | 'components/**/*.vue', 55 | 'layouts/**/*.vue', 56 | 'pages/**/*.vue', 57 | 'plugins/**/*.js', 58 | 'nuxt.config.js', 59 | // TypeScript 60 | 'plugins/**/*.ts', 61 | 'nuxt.config.ts', 62 | './node_modules/@getcandy/**/src/**/*.vue' 63 | ] 64 | } 65 | } 66 | ``` 67 | 68 | In `nuxt.config.js` 69 | 70 | - Replace the `@getcandy/js-client-nuxt` package with `@getcandy/nuxt-client` at the same version constraint 71 | - Remove `@getcandy/js-client-nuxt` fully from `buildModules` 72 | 73 | At the top of `modules` include the new package.. 74 | 75 | ```javascript 76 | modules: [ 77 | '@getcandy/nuxt-client', 78 | // ... 79 | ] 80 | ``` 81 | 82 | Save this icon sprite under `static/icon-sprite.svg` 83 | [https://github.com/tabler/tabler-icons/blob/master/tabler-sprite.svg](https://github.com/tabler/tabler-icons/blob/master/tabler-sprite.svg) 84 | 85 | ## Laravel Sanctum Users 86 | 87 | Replace `@nuxtjs/auth` with the updated Nuxt Auth module. 88 | 89 | ``` 90 | -- "@nuxtjs/auth": "^4.4" 91 | ++ "@nuxtjs/auth-next": "^5.0.0-1611574754.9020f2a", 92 | ``` 93 | 94 | Add the updated auth module to your modules: 95 | 96 | ```javascript 97 | modules: [ 98 | '@nuxtjs/auth-next' // Add below @nuxtjs/axios 99 | ] 100 | ``` 101 | 102 | Update your `middleware/acl.js` file as follows: 103 | 104 | ```javascript 105 | import HubUser from '@getcandy/hub-core/src/modules/HubUser.js' 106 | 107 | export default async function ({ store, route, redirect, $auth }) { 108 | if (!$auth.user) { 109 | await $auth.logout() 110 | } 111 | 112 | if (!($auth.user instanceof HubUser)) { 113 | const hubUser = new HubUser($auth.user.data) 114 | await $auth.setUser(hubUser) 115 | } 116 | 117 | const meta = route.meta[0] 118 | const permissions = meta ? meta.permissions : null 119 | 120 | if (permissions && !$auth.user.hasRole('admin')) { 121 | const result = user.can(permissions) 122 | if (!result) { 123 | await $auth.logout 124 | } 125 | } 126 | } 127 | ``` 128 | 129 | Update the auth section in your `nuxt.config.js` to: 130 | 131 | ```javascript 132 | auth: { 133 | strategies: { 134 | hub: { 135 | provider: 'laravel/sanctum', 136 | url: `http://localhost:8000/api`, 137 | endpoints: { 138 | user: { url: '/v1/users/current?include=customer.customerGroups', method: 'get', propertyName: 'data' } 139 | } 140 | } 141 | } 142 | } 143 | ``` 144 | 145 | ### 🐞 Fixes 146 | - Fixed an issue where the account section wouldn't load 147 | - Fixed an issue where `formErrors` would return undefined, causing some pages to crash. 148 | - Search has been fixed on products page 149 | - Fixed an issue where media uploads would not trigger and then be added to a draft. 150 | - Fixed an issue which stopped the attribute groups page from loading 151 | - Fixed an issue that prevented a user from updating their password on their account 152 | 153 | ### ⭐ Improvements 154 | 155 | - We're now using the updated Nuxt Auth module for authentication. 156 | - Improvements have been made to shipping method editing (although still under review) 157 | - Improvements to product drafting and attaching media files. 158 | - Updated to Tailwind 2.0, progressed with removing Buefy and adding ESlint 159 | - Changed icons to a linked SVG 160 | - Redesigned the hub navigation 161 | - Stability improvements to Product and Category editing. 162 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # getcandy-hub 2 | 3 | > GetCandy Hub prototype 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | $ npm install 10 | 11 | # serve with hot reload at localhost:3000 12 | $ npm run dev 13 | 14 | # build for production and launch server 15 | $ npm run build 16 | $ npm run start 17 | 18 | # generate static project 19 | $ npm run generate 20 | ``` 21 | 22 | For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org). 23 | -------------------------------------------------------------------------------- /app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ HEAD }} 5 | 6 | 7 | 8 | {{ APP }} 9 | 10 | 11 | -------------------------------------------------------------------------------- /assets/README.md: -------------------------------------------------------------------------------- 1 | # ASSETS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your un-compiled assets such as LESS, SASS, or JavaScript. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked). 8 | -------------------------------------------------------------------------------- /assets/css/app.scss: -------------------------------------------------------------------------------- 1 | // Import Bulma's core 2 | @import "~bulma/sass/utilities/_all"; 3 | @import '~bulma-timeline'; 4 | @import '~bulma-quickview'; 5 | 6 | // Custom Bulma Styles 7 | @import "./fonts.scss"; 8 | @import "./bulma.scss"; 9 | @import "./utils.scss"; 10 | 11 | // Import Bulma and Buefy styles 12 | @import "~bulma"; 13 | @import "~buefy/src/scss/buefy"; 14 | 15 | @import "./mixins.scss"; 16 | @import "./layouts.scss"; 17 | @import "./buttons.scss"; 18 | @import "./form_elements.scss"; 19 | @import "./components.scss"; 20 | @import "./tables.scss"; 21 | @import "./tabs.scss"; 22 | -------------------------------------------------------------------------------- /assets/css/bulma.scss: -------------------------------------------------------------------------------- 1 | // Custom Variables for Bulma 2 | 3 | $family-primary: 'Inter', sans-serif; 4 | 5 | 6 | // App Color Palette 7 | $color_primary: #6100C9; // Purple 8 | $color_secondary: #8D00BE; // Pink 9 | $color_success: #40C12C; // Green 10 | 11 | $block-spacing: 0; 12 | // Bulma Overrides 13 | $primary: $color_success; 14 | 15 | 16 | $colors: ( 17 | "white": ($white, $black), 18 | "black": ($black, $white), 19 | "light": ($light, $light-invert), 20 | "dark": ($dark, $dark-invert), 21 | "primary": ($primary, $primary-invert), 22 | "info": ($info, $info-invert), 23 | "success": ($success, $success-invert), 24 | "warning": ($warning, $warning-invert), 25 | "danger": ($danger, $danger-invert) 26 | ); 27 | 28 | // Links 29 | $link: $color_primary; 30 | $link-invert: $primary-invert; 31 | $link-focus-border: $primary; 32 | 33 | $label-weight: $weight-medium; 34 | 35 | // Large Tabs 36 | .tabs.tabs-large { 37 | background-color: #F4F5F8; 38 | &--flush { 39 | margin-bottom:0!important; 40 | } 41 | ul { 42 | padding-left: 30px; 43 | border: none; 44 | 45 | li { 46 | a { 47 | color: #A1A3B9; 48 | text-transform: uppercase; 49 | font-size: 12px; 50 | font-weight: bold; 51 | padding: 30px 40px; 52 | border-bottom-width: 0; 53 | 54 | &:hover { 55 | color: $color_primary; 56 | } 57 | } 58 | 59 | &.is-active { 60 | a { 61 | color: $color_primary; 62 | border-bottom-width: 3px; 63 | } 64 | } 65 | } 66 | } 67 | } 68 | 69 | .column.is-0p5 { 70 | -webkit-box-flex: 0; 71 | flex: none; 72 | width: 4.33333%; 73 | } 74 | 75 | 76 | .padded { 77 | padding: 3rem 4%; 78 | } 79 | 80 | .sub-section { 81 | padding:2rem 0; 82 | border-bottom: 1px solid #f5f5f5; 83 | > .column { 84 | margin-right:40px; 85 | } 86 | .subtitle { 87 | font-size:.875em; 88 | font-weight:600; 89 | } 90 | &__heading { 91 | p { 92 | font-size:.8em; 93 | color: #71738B; 94 | } 95 | } 96 | } 97 | 98 | .spin { 99 | animation: spin 1s infinite linear; 100 | } 101 | 102 | .spin-fast { 103 | animation: spin .5s infinite linear; 104 | } 105 | 106 | @keyframes spin { 107 | 0% { 108 | transform: rotate(0deg); 109 | } 110 | 100% { 111 | transform: rotate(360deg); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /assets/css/buttons.scss: -------------------------------------------------------------------------------- 1 | // Buton Styles 2 | 3 | .button { 4 | @include border-radius(4px); 5 | border: 1px solid #C4D0DC; 6 | background-color: #fff; 7 | font-size: 14px; 8 | font-weight: bold; 9 | 10 | span { 11 | color: #9DA3B5; 12 | 13 | .icon:first-child:last-child { 14 | position: relative; 15 | margin-top: -3px; 16 | @include border-radius(4px); 17 | margin-left: -5px; 18 | margin-right: 5px; 19 | font-weight: normal; 20 | } 21 | } 22 | 23 | &.icon-only { 24 | span { 25 | .icon:first-child:last-child { 26 | margin-right: -5px; 27 | } 28 | } 29 | } 30 | } 31 | 32 | .button.is-primary { 33 | border: none; 34 | 35 | span { 36 | color: #fff; 37 | 38 | .icon:first-child:last-child { 39 | background: lighten($primary, 5%); 40 | } 41 | } 42 | } 43 | 44 | button.is-danger { 45 | span { 46 | color: #fff; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /assets/css/components.scss: -------------------------------------------------------------------------------- 1 | // Component Styles 2 | 3 | @import './components/global/MainNav.scss'; 4 | @import './components/global/Toolbar.scss'; 5 | @import './components/hub/SearchTable.scss'; 6 | @import './components/hub/MediaManager.scss'; 7 | @import './components/hub/FileUpload.scss'; 8 | @import './components/hub/QuickViewPanel.scss'; 9 | @import './components/forms/RichText.scss'; 10 | -------------------------------------------------------------------------------- /assets/css/components/forms/RichText.scss: -------------------------------------------------------------------------------- 1 | // ProseMirror 2 | 3 | .ProseMirror { 4 | @apply .p-4; 5 | @apply .border-gray-400; 6 | @apply .border; 7 | @apply .rounded-b; 8 | &:focus { 9 | @apply .outline-none; 10 | @apply .border-blue-500; 11 | } 12 | } 13 | .text-editor-control { 14 | @apply .leading-none; 15 | @apply .text-gray-600; 16 | @apply .px-2; 17 | @apply .py-1; 18 | @apply .block; 19 | :hover { 20 | @apply .text-black; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /assets/css/components/global/MainNav.scss: -------------------------------------------------------------------------------- 1 | $main-nav_width: 90px; 2 | $sub-nav-width: 250px; 3 | 4 | .main-nav { 5 | height: 100%; /* Full-height: remove this if you want "auto" height */ 6 | width: $main-nav_width; /* Set the width of the sidebar */ 7 | position: fixed; /* Fixed Sidebar (stay in place on scroll) */ 8 | z-index: 30; /* Stay on top */ 9 | top: 0; /* Stay at the top */ 10 | left: 0; 11 | background-color: #182C4B; /* Black */ 12 | overflow-x: hidden; /* Disable horizontal scroll */ 13 | 14 | &__icon{ 15 | width: 40px; 16 | height: 40px; 17 | margin: 25px; 18 | margin-top: 30px; 19 | margin-bottom: 60px; 20 | } 21 | 22 | 23 | &__item { 24 | position: relative; 25 | padding-top: 10px; 26 | padding-bottom: 10px; 27 | margin-top: 10px; 28 | margin-bottom: 10px; 29 | cursor: pointer; 30 | button { 31 | cursor: pointer; 32 | } 33 | 34 | &__icon { 35 | width: $main-nav_width / 2; 36 | height: 45px; 37 | display:block; 38 | border:none; 39 | margin: 0 auto; 40 | line-height:1; 41 | text-align: center; 42 | background-color: lighten(#182C4B, 2%); 43 | @include border-radius(3px); 44 | &--danger { 45 | &:hover { 46 | background-color: $danger!important; 47 | } 48 | i { 49 | margin-top:0!important; 50 | } 51 | } 52 | i { 53 | color: #D1DEF2; 54 | margin-top: 21px; 55 | } 56 | 57 | &--active, &--active:hover { 58 | background-color: #0CBCBC; 59 | @include border-radius(3px); 60 | i { 61 | color: #fff; 62 | } 63 | } 64 | 65 | &:hover, &--open { 66 | background-color: #6201C9; 67 | @include border-radius(3px); 68 | 69 | i { 70 | color: #fff; 71 | } 72 | } 73 | } 74 | 75 | &__title { 76 | display: none; 77 | } 78 | } 79 | 80 | &__profile { 81 | position: absolute; 82 | bottom: 30px; 83 | width: 100%; 84 | img { 85 | margin-left: 17px; 86 | width: 56px; 87 | border-radius: 50%; 88 | border: 2px solid darken(#fff, 20%); 89 | cursor: pointer; 90 | 91 | &:hover { 92 | border: 2px solid #fff; 93 | } 94 | } 95 | } 96 | } 97 | 98 | .sub-nav { 99 | margin-left: -($main-nav_width+$sub-nav-width); 100 | @include linear-gradient(#6100C9 40%, #8D00BE); 101 | position: fixed; 102 | top: 0; 103 | left: 0px; 104 | height: 100%; 105 | width: $sub-nav-width; 106 | overflow-x: hidden; 107 | z-index: 10; 108 | 109 | color: white; 110 | 111 | transition: 0.2s linear; 112 | -moz-transition: 0.2s linear; 113 | -webkit-transition: 0.2s linear; 114 | 115 | &.active { 116 | margin-left: $main-nav_width; 117 | } 118 | 119 | &__title { 120 | font-weight: bold; 121 | font-size: .875rem; 122 | background: darken(#6100C9, 6%); 123 | padding:22px; 124 | color: #EDE6F8; 125 | } 126 | 127 | &__items { 128 | padding: 22px; 129 | } 130 | 131 | &__item { 132 | margin-bottom:20px; 133 | a { 134 | color: #DCCDF1; 135 | font-size: 14px; 136 | text-transform: uppercase; 137 | display: block; 138 | width: 100%; 139 | 140 | &:hover { 141 | color: #fff; 142 | } 143 | } 144 | } 145 | } 146 | 147 | .utility-menu { 148 | display: block; 149 | margin-top: 60px; 150 | } 151 | 152 | .main-body { 153 | margin-left: $main-nav_width; /* Same as the width of the sidebar */ 154 | } 155 | 156 | -------------------------------------------------------------------------------- /assets/css/components/global/Toolbar.scss: -------------------------------------------------------------------------------- 1 | .toolbar { 2 | width: 100%; 3 | background: #fff; 4 | border-bottom:1px solid lighten($grey-lighter, 5%); 5 | box-shadow:0px 4px 4px rgba($grey-lighter, .25); 6 | justify-content: space-between; 7 | align-items: center; 8 | padding:0 20px; 9 | &--fixed { 10 | position: fixed; 11 | z-index: 600; 12 | top:0; 13 | } 14 | &__header { 15 | padding: 1rem 0; 16 | } 17 | &__search { 18 | width: 33.33%; 19 | .control { 20 | border-left: 1px solid #ebebeb; 21 | &.has-icons-left { 22 | display: flex; 23 | align-items: center; 24 | flex-direction: row-reverse; 25 | .input { 26 | width:100%; 27 | } 28 | .icon { 29 | &.is-left { 30 | position: static; 31 | } 32 | } 33 | } 34 | input { 35 | border:none; 36 | box-shadow:none; 37 | border-radius:0; 38 | padding: 2rem 0; 39 | padding-left:0!important; 40 | &:focus { 41 | outline:none; 42 | box-shadow:none; 43 | border:none; 44 | } 45 | } 46 | } 47 | } 48 | &__heading { 49 | color: #182C4B; 50 | font-size: 24px; 51 | margin-right: 10px; 52 | display: inline; 53 | } 54 | 55 | &__subheading { 56 | color: #877E8E; 57 | font-size: 18px; 58 | 59 | .icon { 60 | position: relative; 61 | top: 4px; 62 | margin-right: 7px; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /assets/css/components/hub/FileUpload.scss: -------------------------------------------------------------------------------- 1 | 2 | // uppy-Root 3 | // uppy-u-reset 4 | // uppy-DragDrop-container 5 | // uppy-DragDrop--is-dragdrop-supported 6 | 7 | 8 | // require() 9 | // require() 10 | 11 | @import '@uppy/core/dist/style.css'; 12 | @import '@uppy/drag-drop/dist/style.css'; 13 | 14 | .uppy-DragDrop-container { 15 | // height: 100%; 16 | } 17 | 18 | .uppy-DragDrop { 19 | &-container { 20 | background: transparent; 21 | } 22 | &--isDragDropSupported { 23 | border:none; 24 | border-radius: 0; 25 | } 26 | } 27 | 28 | 29 | .uppy-DragDrop-inner { 30 | font-size:.875em; 31 | svg { 32 | display:none; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /assets/css/components/hub/MediaManager.scss: -------------------------------------------------------------------------------- 1 | .media-controls { 2 | padding:1em 30px; 3 | } 4 | 5 | -------------------------------------------------------------------------------- /assets/css/components/hub/QuickViewPanel.scss: -------------------------------------------------------------------------------- 1 | .quickview-header { 2 | border:none; 3 | padding:0 1.5rem; 4 | h3 { 5 | margin-bottom:0; 6 | font-size:.875rem; 7 | font-weight:$weight-semibold; 8 | } 9 | } 10 | 11 | .quickview-overlay { 12 | background:rgba(#111E33, .9); 13 | position:fixed; 14 | top:0; 15 | left:0; 16 | right:0; 17 | bottom:0; 18 | z-index:30; 19 | } 20 | 21 | .quickview-body { 22 | margin-top:1rem; 23 | padding:0 1.5rem; 24 | .field { 25 | margin-bottom:1rem; 26 | .control { 27 | .select { 28 | width:100%; 29 | select { 30 | width: inherit; 31 | } 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /assets/css/components/hub/SearchTable.scss: -------------------------------------------------------------------------------- 1 | .search-table { 2 | .search-field { 3 | padding:10px 30px; 4 | background-color: white; 5 | } 6 | .b-table { 7 | .table-wrapper:not(:last-child) { 8 | margin-bottom: 0; 9 | } 10 | 11 | .table { 12 | border: none; 13 | 14 | thead { 15 | background-color: #F4F5F8; 16 | 17 | th { 18 | color: #A1A3B9; 19 | text-transform: uppercase; 20 | font-size: 12px; 21 | padding-top: 20px; 22 | padding-bottom: 20px; 23 | border: none; 24 | 25 | &:first-child { 26 | padding-left: 30px; 27 | } 28 | 29 | &:last-child { 30 | padding-right: 50px; 31 | } 32 | } 33 | } 34 | 35 | tbody { 36 | tr { 37 | min-height: 50px; 38 | } 39 | 40 | td { 41 | font-size: 14px; 42 | border: none; 43 | vertical-align: middle; 44 | height: 50px; 45 | 46 | &:first-child { 47 | padding-left: 30px; 48 | } 49 | 50 | &:last-child { 51 | padding-right: 50px; 52 | text-align: left; 53 | } 54 | } 55 | } 56 | } 57 | } 58 | 59 | .level:not(.top) { 60 | background-color: #F4F5F8; 61 | padding-bottom: 0; 62 | margin-bottom: 20px; 63 | @include box-shadow(0px,10px,15px,-5px, rgba(0,0,0,0.1)); 64 | 65 | nav { 66 | .pagination-link { 67 | width: 60px; 68 | height: 50px; 69 | border-radius: 0; 70 | font-size: 12px; 71 | margin-left: 0; 72 | margin-right: 0; 73 | border-top: 0; 74 | border-bottom: 0; 75 | border-left: 1px solid #E4E9EE; 76 | border-right: 0; 77 | color: #6A6A6A; 78 | 79 | &:hover { 80 | background-color: $color_primary; 81 | color: #fff; 82 | border-right: inherit; 83 | } 84 | 85 | &.is-current { 86 | border: 0; 87 | font-weight: bold; 88 | background-color: #E4E9EE; 89 | color: #B1B7D3; 90 | } 91 | } 92 | 93 | .pagination-ellipsis { 94 | margin: 0 auto; 95 | height: 50px; 96 | width: 60px; 97 | border-left: 1px solid #E4E9EE; 98 | border-radius: 0; 99 | } 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /assets/css/fonts.scss: -------------------------------------------------------------------------------- 1 | // System Fonts 2 | 3 | @import "../fonts/Inter/inter.css"; -------------------------------------------------------------------------------- /assets/css/form_elements.scss: -------------------------------------------------------------------------------- 1 | // Form Elements 2 | 3 | .input { 4 | border: 1px solid #C4D0DC; 5 | } -------------------------------------------------------------------------------- /assets/css/layouts.scss: -------------------------------------------------------------------------------- 1 | // Component Styles 2 | 3 | @import './layouts/default.scss'; 4 | @import './layouts/product.scss'; 5 | -------------------------------------------------------------------------------- /assets/css/layouts/default.scss: -------------------------------------------------------------------------------- 1 | // Layout 2 | -------------------------------------------------------------------------------- /assets/css/layouts/product.scss: -------------------------------------------------------------------------------- 1 | // Product layout 2 | -------------------------------------------------------------------------------- /assets/css/mixins.scss: -------------------------------------------------------------------------------- 1 | // Useful Mixins 2 | 3 | @mixin border-radius($radius) { 4 | -webkit-border-radius: $radius; 5 | -moz-border-radius: $radius; 6 | -ms-border-radius: $radius; 7 | border-radius: $radius; 8 | } 9 | 10 | /// Mixin printing a linear-gradient 11 | /// as well as a plain color fallback 12 | /// and the `-webkit-` prefixed declaration 13 | /// @access public 14 | /// @param {Keyword | Angle} $direction - Linear gradient direction 15 | /// @param {Arglist} $color-stops - List of color-stops composing the gradient 16 | @mixin linear-gradient($direction, $color-stops...) { 17 | background: nth(nth($color-stops, 1), 1); 18 | background: -webkit-linear-gradient(legacy-direction($direction), $color-stops); 19 | background: linear-gradient($direction, $color-stops); 20 | } 21 | 22 | @mixin box-shadow($h, $v, $blur, $spread, $color) { 23 | -webkit-box-shadow: $h $v $blur $spread $color; 24 | -moz-box-shadow: $h $v $blur $spread $color; 25 | box-shadow: $h $v $blur $spread $color; 26 | } -------------------------------------------------------------------------------- /assets/css/tables.scss: -------------------------------------------------------------------------------- 1 | .table-headers { 2 | border: none; 3 | background-color: #F4F5F8; 4 | 5 | .table-header-cell { 6 | color: #A1A3B9; 7 | text-transform: uppercase; 8 | font-weight:600; 9 | font-size: 12px; 10 | padding-top: 20px; 11 | padding-bottom: 20px; 12 | border: none; 13 | &:first-child { 14 | padding-left:10px; 15 | } 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /assets/css/tabs.scss: -------------------------------------------------------------------------------- 1 | 2 | .secondary-tabs { 3 | .tabs { 4 | padding:0 30px; 5 | font-size: $small-font-size; 6 | background-color:#182C4B; 7 | &.is-toggle { 8 | li { 9 | a { 10 | border-radius:0; 11 | } 12 | &.is-active { 13 | a { 14 | border-radius:0; 15 | } 16 | } 17 | } 18 | } 19 | ul { 20 | border: none; 21 | li { 22 | &.is-active { 23 | border-radius:0; 24 | a { 25 | background-color: white; 26 | color: #252323; 27 | &:hover { 28 | background-color: white; 29 | } 30 | } 31 | } 32 | a { 33 | border: none; 34 | color: white; 35 | padding:1em 20px; 36 | &:hover { 37 | background-color: darken(#F6F8FB, 2%); 38 | color: #252323; 39 | } 40 | } 41 | } 42 | } 43 | } 44 | .tab-content { 45 | background-color: white; 46 | } 47 | } 48 | 49 | .tab-content-tools { 50 | margin-bottom: 1em; 51 | text-align:right; 52 | } 53 | -------------------------------------------------------------------------------- /assets/css/tailwind.css: -------------------------------------------------------------------------------- 1 | /* purgecss start ignore */ 2 | @import 'tailwindcss/base'; 3 | @import 'tailwindcss/components'; 4 | /* purgecss end ignore */ 5 | @import 'tailwindcss/utilities'; 6 | -------------------------------------------------------------------------------- /assets/css/utils.scss: -------------------------------------------------------------------------------- 1 | // .flex { 2 | // display:flex; 3 | // } 4 | -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Black.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Black.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-BlackItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-BlackItalic.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-BlackItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-BlackItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Bold.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Bold.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-BoldItalic.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-BoldItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-ExtraBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-ExtraBold.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-ExtraBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-ExtraBold.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-ExtraBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-ExtraBoldItalic.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-ExtraBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-ExtraBoldItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-ExtraLight-BETA.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-ExtraLight-BETA.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-ExtraLight-BETA.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-ExtraLight-BETA.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-ExtraLightItalic-BETA.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-ExtraLightItalic-BETA.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-ExtraLightItalic-BETA.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-ExtraLightItalic-BETA.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Italic.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Italic.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Light-BETA.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Light-BETA.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Light-BETA.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Light-BETA.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-LightItalic-BETA.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-LightItalic-BETA.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-LightItalic-BETA.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-LightItalic-BETA.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Medium.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Medium.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-MediumItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-MediumItalic.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-MediumItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Regular.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-SemiBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-SemiBold.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-SemiBold.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-SemiBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-SemiBoldItalic.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-SemiBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-SemiBoldItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Thin-BETA.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Thin-BETA.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-Thin-BETA.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-Thin-BETA.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-ThinItalic-BETA.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-ThinItalic-BETA.woff -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-ThinItalic-BETA.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-ThinItalic-BETA.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-italic.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-italic.var.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter-roman.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter-roman.var.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/Inter.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/fonts/Inter/Inter.var.woff2 -------------------------------------------------------------------------------- /assets/fonts/Inter/inter.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Inter'; 3 | font-style: normal; 4 | font-weight: 100; 5 | font-display: swap; 6 | src: url("Inter-Thin-BETA.woff2?v=3.11") format("woff2"), 7 | url("Inter-Thin-BETA.woff?v=3.11") format("woff"); 8 | } 9 | @font-face { 10 | font-family: 'Inter'; 11 | font-style: italic; 12 | font-weight: 100; 13 | font-display: swap; 14 | src: url("Inter-ThinItalic-BETA.woff2?v=3.11") format("woff2"), 15 | url("Inter-ThinItalic-BETA.woff?v=3.11") format("woff"); 16 | } 17 | 18 | @font-face { 19 | font-family: 'Inter'; 20 | font-style: normal; 21 | font-weight: 200; 22 | font-display: swap; 23 | src: url("Inter-ExtraLight-BETA.woff2?v=3.11") format("woff2"), 24 | url("Inter-ExtraLight-BETA.woff?v=3.11") format("woff"); 25 | } 26 | @font-face { 27 | font-family: 'Inter'; 28 | font-style: italic; 29 | font-weight: 200; 30 | font-display: swap; 31 | src: url("Inter-ExtraLightItalic-BETA.woff2?v=3.11") format("woff2"), 32 | url("Inter-ExtraLightItalic-BETA.woff?v=3.11") format("woff"); 33 | } 34 | 35 | @font-face { 36 | font-family: 'Inter'; 37 | font-style: normal; 38 | font-weight: 300; 39 | font-display: swap; 40 | src: url("Inter-Light-BETA.woff2?v=3.11") format("woff2"), 41 | url("Inter-Light-BETA.woff?v=3.11") format("woff"); 42 | } 43 | @font-face { 44 | font-family: 'Inter'; 45 | font-style: italic; 46 | font-weight: 300; 47 | font-display: swap; 48 | src: url("Inter-LightItalic-BETA.woff2?v=3.11") format("woff2"), 49 | url("Inter-LightItalic-BETA.woff?v=3.11") format("woff"); 50 | } 51 | 52 | @font-face { 53 | font-family: 'Inter'; 54 | font-style: normal; 55 | font-weight: 400; 56 | font-display: swap; 57 | src: url("Inter-Regular.woff2?v=3.11") format("woff2"), 58 | url("Inter-Regular.woff?v=3.11") format("woff"); 59 | } 60 | @font-face { 61 | font-family: 'Inter'; 62 | font-style: italic; 63 | font-weight: 400; 64 | font-display: swap; 65 | src: url("Inter-Italic.woff2?v=3.11") format("woff2"), 66 | url("Inter-Italic.woff?v=3.11") format("woff"); 67 | } 68 | 69 | @font-face { 70 | font-family: 'Inter'; 71 | font-style: normal; 72 | font-weight: 500; 73 | font-display: swap; 74 | src: url("Inter-Medium.woff2?v=3.11") format("woff2"), 75 | url("Inter-Medium.woff?v=3.11") format("woff"); 76 | } 77 | @font-face { 78 | font-family: 'Inter'; 79 | font-style: italic; 80 | font-weight: 500; 81 | font-display: swap; 82 | src: url("Inter-MediumItalic.woff2?v=3.11") format("woff2"), 83 | url("Inter-MediumItalic.woff?v=3.11") format("woff"); 84 | } 85 | 86 | @font-face { 87 | font-family: 'Inter'; 88 | font-style: normal; 89 | font-weight: 600; 90 | font-display: swap; 91 | src: url("Inter-SemiBold.woff2?v=3.11") format("woff2"), 92 | url("Inter-SemiBold.woff?v=3.11") format("woff"); 93 | } 94 | @font-face { 95 | font-family: 'Inter'; 96 | font-style: italic; 97 | font-weight: 600; 98 | font-display: swap; 99 | src: url("Inter-SemiBoldItalic.woff2?v=3.11") format("woff2"), 100 | url("Inter-SemiBoldItalic.woff?v=3.11") format("woff"); 101 | } 102 | 103 | @font-face { 104 | font-family: 'Inter'; 105 | font-style: normal; 106 | font-weight: 700; 107 | font-display: swap; 108 | src: url("Inter-Bold.woff2?v=3.11") format("woff2"), 109 | url("Inter-Bold.woff?v=3.11") format("woff"); 110 | } 111 | @font-face { 112 | font-family: 'Inter'; 113 | font-style: italic; 114 | font-weight: 700; 115 | font-display: swap; 116 | src: url("Inter-BoldItalic.woff2?v=3.11") format("woff2"), 117 | url("Inter-BoldItalic.woff?v=3.11") format("woff"); 118 | } 119 | 120 | @font-face { 121 | font-family: 'Inter'; 122 | font-style: normal; 123 | font-weight: 800; 124 | font-display: swap; 125 | src: url("Inter-ExtraBold.woff2?v=3.11") format("woff2"), 126 | url("Inter-ExtraBold.woff?v=3.11") format("woff"); 127 | } 128 | @font-face { 129 | font-family: 'Inter'; 130 | font-style: italic; 131 | font-weight: 800; 132 | font-display: swap; 133 | src: url("Inter-ExtraBoldItalic.woff2?v=3.11") format("woff2"), 134 | url("Inter-ExtraBoldItalic.woff?v=3.11") format("woff"); 135 | } 136 | 137 | @font-face { 138 | font-family: 'Inter'; 139 | font-style: normal; 140 | font-weight: 900; 141 | font-display: swap; 142 | src: url("Inter-Black.woff2?v=3.11") format("woff2"), 143 | url("Inter-Black.woff?v=3.11") format("woff"); 144 | } 145 | @font-face { 146 | font-family: 'Inter'; 147 | font-style: italic; 148 | font-weight: 900; 149 | font-display: swap; 150 | src: url("Inter-BlackItalic.woff2?v=3.11") format("woff2"), 151 | url("Inter-BlackItalic.woff?v=3.11") format("woff"); 152 | } 153 | 154 | /* ------------------------------------------------------- 155 | Variable font. 156 | Usage: 157 | 158 | html { font-family: 'Inter', sans-serif; } 159 | @supports (font-variation-settings: normal) { 160 | html { font-family: 'Inter var', sans-serif; } 161 | } 162 | */ 163 | @font-face { 164 | font-family: 'Inter var'; 165 | font-weight: 100 900; 166 | font-display: swap; 167 | font-style: normal; 168 | font-named-instance: 'Regular'; 169 | src: url("Inter-roman.var.woff2?v=3.11") format("woff2"); 170 | } 171 | @font-face { 172 | font-family: 'Inter var'; 173 | font-weight: 100 900; 174 | font-display: swap; 175 | font-style: italic; 176 | font-named-instance: 'Italic'; 177 | src: url("Inter-italic.var.woff2?v=3.11") format("woff2"); 178 | } 179 | 180 | 181 | /* -------------------------------------------------------------------------- 182 | [EXPERIMENTAL] Multi-axis, single variable font. 183 | 184 | Slant axis is not yet widely supported (as of February 2019) and thus this 185 | multi-axis single variable font is opt-in rather than the default. 186 | 187 | When using this, you will probably need to set font-variation-settings 188 | explicitly, e.g. 189 | 190 | * { font-variation-settings: "slnt" 0deg } 191 | .italic { font-variation-settings: "slnt" 10deg } 192 | 193 | */ 194 | @font-face { 195 | font-family: 'Inter var experimental'; 196 | font-weight: 100 900; 197 | font-display: swap; 198 | font-style: oblique 0deg 10deg; 199 | src: url("Inter.var.woff2?v=3.11") format("woff2"); 200 | } 201 | -------------------------------------------------------------------------------- /assets/images/sweet-jar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/assets/images/sweet-jar.jpg -------------------------------------------------------------------------------- /components/README.md: -------------------------------------------------------------------------------- 1 | # COMPONENTS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | The components directory contains your Vue.js Components. 6 | 7 | _Nuxt.js doesn't supercharge these components._ 8 | -------------------------------------------------------------------------------- /env.example: -------------------------------------------------------------------------------- 1 | API_BASE=http://localhost:8000/api/v1 2 | SANCTUM_URL=http://localhost:8000/api 3 | PRODUCT_PREVIEW_URL=http://storefront.test/products/preview/:id 4 | PRODUCT_LIVE_URL=http://storefront.test/products/preview/:slug 5 | CATEGORY_PREVIEW_URL=http://storefront.test/categories/preview/:id 6 | COLLECTION_PREVIEW_URL=http://storefront.test/collections/preview/:id -------------------------------------------------------------------------------- /getcandy.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | storename: 'Example Storefront' 3 | } 4 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleNameMapper: { 3 | '^@/(.*)$': '/$1', 4 | '^~/(.*)$': '/$1', 5 | '^vue$': 'vue/dist/vue.common.js' 6 | }, 7 | setupFiles: [ 8 | '/test/setup.js' 9 | ], 10 | moduleFileExtensions: ['js', 'vue', 'json'], 11 | transform: { 12 | '^.+\\.js$': 'babel-jest', 13 | '.*\\.(vue)$': 'vue-jest' 14 | }, 15 | 'collectCoverage': false, 16 | 'collectCoverageFrom': [ 17 | '/components/**/*.vue', 18 | '/pages/**/*.vue' 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /locales/de.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /locales/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "en" : "English", 3 | "fr" : "Français", 4 | "de" : "Deutch" 5 | } 6 | -------------------------------------------------------------------------------- /locales/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Français" : "Français", 3 | "Name": "Nom" 4 | } 5 | -------------------------------------------------------------------------------- /middleware/README.md: -------------------------------------------------------------------------------- 1 | # MIDDLEWARE 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your application middleware. 6 | Middleware let you define custom functions that can be run before rendering either a page or a group of pages. 7 | 8 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware). 9 | -------------------------------------------------------------------------------- /middleware/acl.js: -------------------------------------------------------------------------------- 1 | import HubUser from '@getcandy/hub-core/src/modules/HubUser.js' 2 | 3 | export default async function ({ store, route, redirect, $auth }) { 4 | if (!$auth.user) { 5 | await $auth.logout() 6 | } 7 | 8 | if (!($auth.user instanceof HubUser)) { 9 | const hubUser = new HubUser($auth.user.data) 10 | await $auth.setUser(hubUser) 11 | } 12 | 13 | 14 | const meta = route.meta[0] 15 | const permissions = meta ? meta.permissions : null 16 | 17 | if (permissions && !$auth.user.hasRole('admin')) { 18 | const result = $auth.user.can(permissions) 19 | if (!result) { 20 | throw Error('Unauthorised') 21 | // await $auth.logout() 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /middleware/hub.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sets the locale from the API if it's not already loaded 3 | * @param {Store} param0 4 | */ 5 | 6 | var find = require('lodash/find') 7 | 8 | export default async function ({ app, store }) { 9 | const state = store.state 10 | 11 | app.$gc.setHttp(app.$axios) 12 | 13 | if (store.$auth.user) { 14 | // If anything isn't loaded, load it all up. 15 | if ( 16 | !state.core.locale || 17 | !state.core.channel || 18 | !state.core.currency 19 | ) { 20 | const response = await app.$gc.root.get() 21 | const data = response.data 22 | 23 | store.commit('setApiVersion', data.version) 24 | store.commit('setChannel', data.channel.handle) 25 | 26 | app.i18n.locale = data.locale 27 | } 28 | 29 | if (!state.core.languages.length) { 30 | const languages = await app.$gc.languages.get() 31 | store.commit('setLocale', find(languages.data.data, l => l.default).code) 32 | store.commit('setLanguages', languages.data.data) 33 | } 34 | 35 | if (!state.core.taxes.length) { 36 | const taxes = await app.$gc.taxes.get() 37 | store.commit('setTaxes', taxes.data.data) 38 | } 39 | 40 | if (!state.core.channels.length) { 41 | const channels = await app.$gc.channels.get() 42 | store.commit('setChannels', channels.data.data) 43 | } 44 | 45 | if (!state.core.customerGroups.length) { 46 | // const customerGroups = await app.$gc.customerGroups.get() 47 | const customerGroups = await app.$getcandy.on('customer-groups', 'getCustomerGroups') 48 | store.commit('setCustomerGroups', customerGroups.data.data) 49 | } 50 | 51 | if (!state.core.currencies.length) { 52 | const currencies = await app.$gc.currencies.get() 53 | store.commit('setCurrencies', currencies.data.data) 54 | } 55 | 56 | if (!state.core.currency) { 57 | store.commit('setCurrency', state.core.currencies.find(currency => currency.default)) 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | import GetCandyConfig from './getcandy.config' 2 | require('dotenv').config() 3 | 4 | export default { 5 | ssr: false, 6 | 7 | /* 8 | ** Headers of the page 9 | */ 10 | head: { 11 | titleTemplate: (titleChunk) => { 12 | // If undefined or blank then we don't need the hyphen 13 | return titleChunk ? `GetCandy // ${titleChunk} ` : 'GetCandy'; 14 | }, 15 | meta: [ 16 | { charset: 'utf-8' }, 17 | { name: 'viewport', content: 'width=device-width, initial-scale=1' }, 18 | { hid: 'description', name: 'description', content: process.env.npm_package_description || '' } 19 | ], 20 | link: [ 21 | { rel: 'shortcut icon', type: 'image/png', href: '/favicon.png' } 22 | ] 23 | }, 24 | 25 | /* 26 | ** Customize the progress-bar color 27 | */ 28 | loading: { color: '#fff' }, 29 | /* 30 | ** Global CSS 31 | */ 32 | css: [ 33 | '@/assets/css/app.scss', 34 | ], 35 | /* 36 | ** Plugins to load before mounting the App 37 | */ 38 | plugins: [ 39 | ], 40 | 41 | /* 42 | ** Nuxt.js dev-modules 43 | */ 44 | buildModules: [ 45 | // Doc: https://github.com/nuxt-community/eslint-module 46 | // '@nuxtjs/eslint-module', 47 | '@nuxtjs/dotenv', 48 | '@nuxtjs/tailwindcss', 49 | ], 50 | 51 | /* 52 | ** Nuxt.js modules 53 | */ 54 | modules: [ 55 | '@getcandy/nuxt-client', 56 | // Doc: https://axios.nuxtjs.org/usage 57 | '@nuxtjs/axios', 58 | '@nuxtjs/auth-next', 59 | ['@getcandy/hub-products', { 60 | 'preview_url': process.env.PRODUCT_PREVIEW_URL, 61 | 'live_url': process.env.PRODUCT_LIVE_URL, 62 | 'allow_variant_options': true 63 | }], 64 | ['@getcandy/hub-categories', { 65 | 'preview_url': process.env.CATEGORY_PREVIEW_URL 66 | }], 67 | ['@getcandy/hub-collections', { 68 | 'preview_url': process.env.COLLECTION_PREVIEW_URL 69 | }], 70 | '@getcandy/hub-orders', 71 | '@getcandy/hub-customers', 72 | '@getcandy/hub-shipping', 73 | '@getcandy/hub-reports', 74 | ['@getcandy/hub-core', { 75 | auth: 'sanctum' 76 | }] 77 | ], 78 | 79 | router: { 80 | middleware: ['auth', 'hub'] 81 | }, 82 | 83 | /* 84 | ** Axios module configuration 85 | ** See https://axios.nuxtjs.org/options 86 | */ 87 | axios: { 88 | baseURL: process.env.API_BASE, 89 | credentials: true, 90 | headers: { 91 | common: { 92 | 'X-CANDY-HUB': true 93 | } 94 | } 95 | }, 96 | 97 | /** 98 | * Auth module configuration 99 | * See https://auth.nuxtjs.org 100 | */ 101 | auth: { 102 | plugins: [ '~/plugins/acl.js' ], 103 | strategies: { 104 | hub: { 105 | provider: 'laravel/sanctum', 106 | url: process.env.SANCTUM_URL, 107 | endpoints: { 108 | user: { url: '/v1/users/current?include=customer.customerGroups,roles.permissions', method: 'get', propertyName: 'data' } 109 | } 110 | } 111 | } 112 | }, 113 | purgeCSS: { 114 | enabled: false 115 | }, 116 | generate: { 117 | fallback: true 118 | }, 119 | tailwindcss: { 120 | exposeConfig: true, 121 | }, 122 | /* 123 | ** Build configuration 124 | */ 125 | build: { 126 | transpile: [ 127 | '@neondigital/vue-draggable-nested-tree', 128 | '@getcandy/node-client', 129 | ], 130 | postcss: { 131 | preset: { 132 | features: { 133 | // Fixes: https://github.com/tailwindcss/tailwindcss/issues/1190#issuecomment-546621554 134 | "focus-within-pseudo-class": false 135 | } 136 | } 137 | }, 138 | extend(config, { isDev, isClient }) { 139 | config.resolve.alias["vue"] = "vue/dist/vue.common"; 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "getcandy-hub", 3 | "version": "0.12.11", 4 | "description": "GetCandy Hub", 5 | "author": "Glenn Jacobs", 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 | "test": "jest --watch" 14 | }, 15 | "dependencies": { 16 | "@getcandy/hub-categories": "^0.12.0", 17 | "@getcandy/hub-collections": "^0.12.0", 18 | "@getcandy/hub-core": "^0.12.0", 19 | "@getcandy/hub-customers": "^0.12.0", 20 | "@getcandy/hub-orders": "^0.12.0", 21 | "@getcandy/hub-products": "^0.12.0", 22 | "@getcandy/hub-reports": "^0.12.0", 23 | "@getcandy/hub-shipping": "^0.12.0", 24 | "@getcandy/js-client": "^0.12.0", 25 | "@getcandy/nuxt-client": "^0.12.0", 26 | "@getcandy/node-client": "^0.11.0", 27 | "@nuxtjs/auth-next": "5.0.0-1612791489.a5d8c28", 28 | "@nuxtjs/axios": "^5.8.0", 29 | "@nuxtjs/dotenv": "^1.4.1", 30 | "@tailwindcss/ui": "^0.7.0", 31 | "moment": "^2.24.0", 32 | "numeral": "^2.0.6", 33 | "nuxt": "^2.14.7", 34 | "vue-i18n": "^8.15.0" 35 | }, 36 | "devDependencies": { 37 | "@nuxtjs/eslint-config": "^1.0.1", 38 | "@nuxtjs/eslint-module": "^1.0.0", 39 | "@nuxtjs/tailwindcss": "^3.4.2", 40 | "@uppy/core": "^1.7.0", 41 | "@uppy/drag-drop": "^1.4.1", 42 | "@uppy/progress-bar": "^1.3.3", 43 | "@uppy/xhr-upload": "^1.4.1", 44 | "@vue/test-utils": "^1.0.0-beta.27", 45 | "babel-eslint": "^10.0.1", 46 | "babel-jest": "^24.1.0", 47 | "browser-env": "^3.3.0", 48 | "bulma-quickview": "^2.0.0", 49 | "bulma-timeline": "^3.0.4", 50 | "color": "^3.1.2", 51 | "currency.js": "^1.2.2", 52 | "eslint": "^6.1.0", 53 | "eslint-plugin-nuxt": ">=0.4.2", 54 | "fs-extra": "^8.1.0", 55 | "jest": "^24.1.0", 56 | "moxios": "^0.4.0", 57 | "nuxt-buefy": "^0.0.2", 58 | "pell": "^1.0.6", 59 | "prismjs": "^1.6.0", 60 | "remixicon": "^2.2.0", 61 | "require-extension-hooks": "^0.3.3", 62 | "require-extension-hooks-babel": "^1.0.0", 63 | "require-extension-hooks-vue": "^3.0.0", 64 | "sinon": "^7.5.0", 65 | "vue-gravatar": "^1.3.1", 66 | "vue-jest": "^4.0.0-0", 67 | "vue-prism-component": "^1.1.1", 68 | "vue-click-outside": "^1.0.7", 69 | "animejs": "^3.2.0" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /pages/unauthorized.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /plugins/README.md: -------------------------------------------------------------------------------- 1 | # PLUGINS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains Javascript plugins that you want to run before mounting the root Vue.js application. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins). 8 | -------------------------------------------------------------------------------- /plugins/acl.js: -------------------------------------------------------------------------------- 1 | import HubUser from '@getcandy/hub-core/src/modules/HubUser.js' 2 | 3 | export default async function ({ $auth }) { 4 | if ($auth.user) { 5 | const hubUser = new HubUser($auth.user.data) 6 | 7 | if (!hubUser.hasRole('admin') && !hubUser.can('access-hub')) { 8 | await $auth.logout() 9 | return 10 | } 11 | 12 | $auth.setUser(hubUser) 13 | } 14 | } -------------------------------------------------------------------------------- /static/README.md: -------------------------------------------------------------------------------- 1 | # STATIC 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your static files. 6 | Each file inside this directory is mapped to `/`. 7 | Thus you'd want to delete this README.md before deploying to production. 8 | 9 | Example: `/static/robots.txt` is mapped as `/robots.txt`. 10 | 11 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static). 12 | -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/static/favicon.png -------------------------------------------------------------------------------- /static/getcandy-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 | 47 | 48 | 49 | 50 | 51 | 53 | 54 | 55 | 56 | 57 | 59 | 60 | 61 | 62 | 63 | 65 | 67 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /static/getcandy-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /store/README.md: -------------------------------------------------------------------------------- 1 | # STORE 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your Vuex Store files. 6 | Vuex Store option is implemented in the Nuxt.js framework. 7 | 8 | Creating a file in this directory automatically activates the option in the framework. 9 | 10 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store). 11 | -------------------------------------------------------------------------------- /store/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getcandy/hub/3e59b01c71476b48262901524ae9b216e15bdf79/store/index.js -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | theme: {}, 3 | variants: { 4 | extend: { 5 | opacity: ['disabled'] 6 | } 7 | }, 8 | plugins: [ 9 | require('@tailwindcss/ui') 10 | ], 11 | purge: { 12 | enabled: process.env.NODE_ENV === 'production', 13 | content: [ 14 | 'components/**/*.vue', 15 | 'layouts/**/*.vue', 16 | 'pages/**/*.vue', 17 | 'plugins/**/*.js', 18 | 'nuxt.config.js', 19 | // TypeScript 20 | 'plugins/**/*.ts', 21 | 'nuxt.config.ts', 22 | './node_modules/@getcandy/**/src/**/*.vue' 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/setup.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Buefy from 'buefy' 3 | Vue.use(Buefy) 4 | Vue.config.productionTip = false 5 | --------------------------------------------------------------------------------