├── .browserlistrc ├── .eslintrc ├── .gitignore ├── LICENSE ├── README.md ├── babel.config.js ├── bin └── chisel-cms ├── build ├── build.js ├── local.run.js ├── server.js ├── webpack.base.config.js ├── webpack.dev-build.config.js ├── webpack.dev.config.js ├── webpack.prod-electron.config.js └── webpack.prod.config.js ├── dist ├── assets │ ├── fonts │ │ ├── Inter-UI-Bold.76d0e6d.ttf │ │ ├── Inter-UI-Medium.dc85c1d.ttf │ │ ├── Inter-UI-Regular.3c00ca2.ttf │ │ ├── Inter-UI-SemiBold.95afbe2.ttf │ │ ├── OpenSans-Bold-webfont.a70355b.ttf │ │ ├── OpenSans-Light-webfont.0f50ad5.ttf │ │ ├── OpenSans-Regular-webfont.d7553e1.ttf │ │ └── OpenSans-Semibold-webfont.7d4d140.ttf │ └── images │ │ ├── chisel-logo.png │ │ ├── chisel_login_illustration.png │ │ └── logo │ │ ├── apple-touch-icon.png │ │ ├── logo192.png │ │ └── logo512.png ├── favicon.ico ├── index.html ├── main.js ├── main.js.LICENSE.txt ├── main.min.css ├── manifest.json └── robots.txt ├── electron ├── build-resources │ ├── entitlements.mac.plist │ ├── icon.png │ └── license.txt ├── dist │ ├── assets │ │ ├── fonts │ │ │ ├── Inter-UI-Bold.76d0e6d.ttf │ │ │ ├── Inter-UI-Medium.dc85c1d.ttf │ │ │ ├── Inter-UI-Regular.3c00ca2.ttf │ │ │ ├── Inter-UI-SemiBold.95afbe2.ttf │ │ │ ├── OpenSans-Bold-webfont.a70355b.ttf │ │ │ ├── OpenSans-Light-webfont.0f50ad5.ttf │ │ │ ├── OpenSans-Regular-webfont.d7553e1.ttf │ │ │ └── OpenSans-Semibold-webfont.7d4d140.ttf │ │ └── images │ │ │ ├── chisel-logo.png │ │ │ ├── chisel_login_illustration.png │ │ │ └── logo │ │ │ ├── apple-touch-icon.png │ │ │ ├── logo192.png │ │ │ └── logo512.png │ ├── favicon.ico │ ├── index.html │ ├── main.js │ ├── main.js.LICENSE.txt │ ├── main.min.css │ ├── manifest.json │ └── robots.txt ├── electron-builder.js ├── electron.js ├── notarize.js ├── package-lock.json ├── package.json └── server-selector │ ├── build.js │ ├── dist │ ├── assets │ │ └── fonts │ │ │ ├── Inter-UI-Bold.76d0e6d.ttf │ │ │ ├── Inter-UI-Medium.dc85c1d.ttf │ │ │ ├── Inter-UI-Regular.3c00ca2.ttf │ │ │ └── Inter-UI-SemiBold.95afbe2.ttf │ ├── index.html │ ├── main.js │ ├── main.js.LICENSE.txt │ └── main.min.css │ ├── server.js │ ├── src │ ├── app.js │ ├── app.sss │ ├── fonts.css │ ├── index.js │ ├── index.pug │ └── styles.global.sss │ ├── webpack.base.config.js │ ├── webpack.dev.config.js │ └── webpack.prod.config.js ├── forgerc.txt ├── package-lock.json ├── package.json ├── postcss.config.js ├── src ├── ConnectConstants.js ├── assets │ ├── fonts │ │ ├── Inter-UI-Bold.ttf │ │ ├── Inter-UI-Medium.ttf │ │ ├── Inter-UI-Regular.ttf │ │ ├── Inter-UI-SemiBold.ttf │ │ ├── OpenSans-Bold-webfont.ttf │ │ ├── OpenSans-Light-webfont.ttf │ │ ├── OpenSans-Regular-webfont.ttf │ │ └── OpenSans-Semibold-webfont.ttf │ └── images │ │ ├── Checkbox.png │ │ ├── Checkbox.svg │ │ ├── arrow-down-full.svg │ │ ├── arrow-down.svg │ │ ├── arrows.svg │ │ ├── chisel-logo.png │ │ ├── chisel-logo@2x square.png │ │ ├── chisel-logo@2x.png │ │ ├── chisel_login_illustration.png │ │ ├── cross-circle.svg │ │ ├── hammer.svg │ │ ├── icons │ │ ├── cross.svg │ │ ├── delete.svg │ │ ├── edit.svg │ │ ├── link.svg │ │ ├── lock.svg │ │ ├── plus.svg │ │ ├── search.svg │ │ ├── sidebar.svg │ │ └── users.svg │ │ ├── media-types │ │ ├── archive.svg │ │ ├── doc.svg │ │ ├── exe.svg │ │ ├── html.svg │ │ ├── json.svg │ │ ├── md.svg │ │ ├── other.svg │ │ ├── pdf.svg │ │ ├── ppt.svg │ │ ├── rtf.svg │ │ ├── txt.svg │ │ ├── xls.svg │ │ ├── xml.svg │ │ └── zip.svg │ │ ├── okay.png │ │ ├── okay.svg │ │ ├── product-logo-b.svg │ │ ├── product-logo.svg │ │ ├── template-empty.png │ │ └── template-empty.svg ├── components │ ├── elements │ │ ├── ButtonControl │ │ │ ├── ButtonControl.js │ │ │ └── ButtonControl.sss │ │ ├── CheckboxControl │ │ │ ├── CheckboxControl.js │ │ │ └── CheckboxControl.sss │ │ ├── ContainerComponent │ │ │ ├── ContainerComponent.js │ │ │ └── ContainerComponent.sss │ │ ├── DropdownControl │ │ │ ├── DropdownControl.js │ │ │ └── DropdownControl.sss │ │ ├── DynamicListComponent │ │ │ ├── DynamicListComponent.js │ │ │ └── DynamicListComponent.sss │ │ ├── EditableTitleControl │ │ │ ├── EditableTitleControl.js │ │ │ └── EditableTitleControl.sss │ │ ├── IconsComponent │ │ │ └── IconsComponent.js │ │ ├── InputControl │ │ │ ├── InputControl.js │ │ │ └── InputControl.sss │ │ ├── InputNumberControl │ │ │ └── InputNumberControl.js │ │ ├── JSONView │ │ │ ├── JSONView.js │ │ │ └── JSONView.sss │ │ ├── LoaderComponent │ │ │ ├── LoaderComponent.js │ │ │ └── LoaderComponent.sss │ │ ├── MarkdownEditor │ │ │ ├── MarkdownEditor.js │ │ │ └── MarkdownEditor.sss │ │ ├── MediaView │ │ │ ├── MediaView.js │ │ │ └── MediaView.sss │ │ ├── RadioControl │ │ │ ├── RadioControl.js │ │ │ └── RadioControl.sss │ │ └── SwitchControl │ │ │ ├── SwitchControl.js │ │ │ └── SwitchControl.sss │ ├── header │ │ └── Menu │ │ │ ├── Menu.js │ │ │ └── Menu.sss │ ├── mainArea │ │ ├── common │ │ │ ├── NoRights.js │ │ │ └── Notification │ │ │ │ ├── Notification.js │ │ │ │ └── Notification.sss │ │ ├── content │ │ │ ├── ContentEdit │ │ │ │ ├── ContentEdit.js │ │ │ │ ├── ContentEdit.sss │ │ │ │ └── elements │ │ │ │ │ ├── ContentBase.js │ │ │ │ │ ├── ContentBoolean.js │ │ │ │ │ ├── ContentDate.js │ │ │ │ │ ├── ContentMedia.js │ │ │ │ │ ├── ContentNumber.js │ │ │ │ │ ├── ContentReference.js │ │ │ │ │ ├── ContentString.js │ │ │ │ │ └── ContentUser.js │ │ │ └── ContentList │ │ │ │ ├── ContentList.js │ │ │ │ ├── ContentList.sss │ │ │ │ ├── eye-gray.png │ │ │ │ └── eye.png │ │ ├── models │ │ │ ├── Model │ │ │ │ ├── Model.js │ │ │ │ └── Model.sss │ │ │ └── ModelsList │ │ │ │ ├── ModelsList.js │ │ │ │ └── ModelsList.sss │ │ ├── settings │ │ │ ├── Settings.js │ │ │ └── Settings.sss │ │ └── sharing │ │ │ ├── Sharing.js │ │ │ ├── Sharing.sss │ │ │ ├── bitbucket.svg │ │ │ ├── github.svg │ │ │ └── slack.svg │ ├── modals │ │ ├── AlertModal │ │ │ ├── AlertModal.js │ │ │ └── AlertModal.sss │ │ ├── CollabRoleModal │ │ │ ├── CollabRoleModal.js │ │ │ └── CollabRoleModal.sss │ │ ├── FieldModal │ │ │ ├── FieldModal.js │ │ │ ├── FieldModal.sss │ │ │ └── Validations │ │ │ │ ├── ValidationDate.js │ │ │ │ ├── ValidationMedia.js │ │ │ │ ├── ValidationNumber.js │ │ │ │ ├── ValidationReference.js │ │ │ │ └── ValidationString.js │ │ ├── MarkdownModal │ │ │ ├── MarkdownModal.js │ │ │ └── MarkdownModal.sss │ │ ├── MediaModal │ │ │ ├── MediaModal.js │ │ │ └── MediaModal.sss │ │ ├── ModelChooseModal │ │ │ ├── ModelChooseModal.js │ │ │ └── ModelChooseModal.sss │ │ ├── ReferenceModal │ │ │ ├── ReferenceModal.js │ │ │ └── ReferenceModal.sss │ │ ├── SiteCreationModal │ │ │ ├── SiteCreationModal.js │ │ │ └── SiteCreationModal.sss │ │ ├── SiteLoader │ │ │ ├── SiteLoader.js │ │ │ └── SiteLoader.sss │ │ └── WysiwygModal │ │ │ ├── WysiwygModal.js │ │ │ └── WysiwygModal.sss │ └── sidebar │ │ ├── Sites │ │ ├── Sites.js │ │ └── Sites.sss │ │ └── User │ │ ├── User.js │ │ ├── User.sss │ │ ├── arrow-down.svg │ │ ├── avatar.svg │ │ ├── logout.svg │ │ └── settings.svg ├── containers │ ├── Header │ │ ├── Header.js │ │ └── Header.sss │ ├── LinksEmail │ │ ├── EmailVerify │ │ │ ├── EmailVerify.js │ │ │ └── EmailVerify.sss │ │ ├── InvalidLink │ │ │ ├── InvalidLink.js │ │ │ └── InvalidLink.sss │ │ └── PasswordSet │ │ │ ├── PasswordSet.js │ │ │ └── PasswordSet.sss │ ├── MainArea │ │ ├── API │ │ │ ├── APIPage.js │ │ │ └── APIPage.sss │ │ ├── Content │ │ │ ├── ContentEdit │ │ │ │ └── ContentEditContainer.js │ │ │ └── ContentListContainer.js │ │ ├── MainArea.js │ │ ├── MainArea.sss │ │ ├── Models │ │ │ ├── Model │ │ │ │ └── ModelContainer.js │ │ │ └── ModelsListContainer.js │ │ ├── PayPlans │ │ │ ├── PayPlans.js │ │ │ └── PayPlans.sss │ │ ├── PaymentMethods │ │ │ ├── PaymentMethods.js │ │ │ └── PaymentMethods.sss │ │ ├── Settings │ │ │ └── SettingsContainer.js │ │ ├── Sharing │ │ │ └── SharingContainer.js │ │ └── UserProfile │ │ │ ├── UserProfile.js │ │ │ └── UserProfile.sss │ ├── Sidebar │ │ ├── Sidebar.js │ │ └── Sidebar.sss │ ├── Sign │ │ ├── Sign.js │ │ └── Sign.sss │ ├── app.js │ └── app.sss ├── ducks │ ├── content.js │ ├── index.js │ ├── media.js │ ├── models.js │ ├── nav.js │ ├── pay.js │ └── user.js ├── fonts.css ├── index.js ├── index.pug ├── middleware │ ├── initialization.js │ ├── liveUpdates.js │ ├── payments.js │ └── routing.js ├── models │ ├── ContentData.js │ ├── MediaItemData.js │ ├── ModelData.js │ ├── PayPlanData.js │ └── UserData.js ├── store │ └── configureStore.js ├── styles.global.sss └── utils │ ├── common.js │ ├── data.js │ ├── initialize.js │ ├── routing.js │ ├── server.js │ └── strings.js └── static ├── assets └── images │ └── logo │ ├── apple-touch-icon.png │ ├── logo192.png │ └── logo512.png ├── favicon.ico ├── manifest.json └── robots.txt /.browserlistrc: -------------------------------------------------------------------------------- 1 | # default 2 | 3 | > 0.5% 4 | last 2 versions 5 | Firefox ESR 6 | not dead -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "rules": { 4 | "comma-dangle": 0, // dangling commas are ok 5 | "indent": [2, 2, { 6 | "SwitchCase": 1 7 | }], 8 | "jsx-quotes": [2, "prefer-single"], 9 | "linebreak-style": [2, "unix"], 10 | "quotes": [2, "single"], 11 | "react/display-name": 1, 12 | "react/forbid-prop-types": 1, 13 | "react/jsx-boolean-value": 1, 14 | "react/jsx-closing-bracket-location": 1, 15 | "react/jsx-curly-spacing": 0, 16 | "react/jsx-indent-props": [2, 2], 17 | "react/jsx-max-props-per-line": 1, 18 | "react/jsx-no-duplicate-props": 1, 19 | "react/jsx-no-literals": 1, 20 | "react/jsx-no-undef": 1, 21 | "react/jsx-sort-prop-types": 1, 22 | "react/jsx-sort-props": 0, 23 | "react/jsx-uses-react": 1, 24 | "react/jsx-uses-vars": 1, 25 | "react/no-danger": 1, 26 | "react/no-did-mount-set-state": 1, 27 | "react/no-did-update-set-state": 1, 28 | "react/no-direct-mutation-state": 1, 29 | "react/no-multi-comp": 1, 30 | "react/no-set-state": 1, 31 | "react/no-unknown-property": 1, 32 | "react/prefer-es6-class": 1, 33 | "react/prop-types": 1, 34 | "react/react-in-jsx-scope": 1, 35 | "react/require-extension": 1, 36 | "react/self-closing-comp": 1, 37 | "react/sort-comp": 1, 38 | "react/wrap-multilines": 1, 39 | "semi": [2, "never"], 40 | "no-unused-vars": [ 41 | 2, 42 | { "argsIgnorePattern": "^_" } 43 | ] 44 | }, 45 | "env": { 46 | "es6": true, 47 | "browser": true, 48 | "mocha": true, 49 | }, 50 | "extends": "eslint:recommended", 51 | "ecmaFeatures": { 52 | "modules": true, 53 | "jsx": true, 54 | "experimentalObjectRestSpread": true 55 | }, 56 | "plugins": [ 57 | "react" 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | *.zip 4 | 5 | # System 6 | .no-sync 7 | .DS_Store 8 | 9 | # env files 10 | .env 11 | 12 | # Log files 13 | logs 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | pnpm-debug.log* 18 | 19 | # Editor directories and files 20 | .idea 21 | .vscode 22 | 23 | 24 | # Electron app 25 | electron/bin -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, Beach.io 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = ({cache, env}) => { 2 | cache.using(() => process.env.NODE_ENV); 3 | 4 | const res = { 5 | presets: [ 6 | [ 7 | "@babel/preset-env", 8 | { 9 | modules: false, 10 | useBuiltIns: "usage", 11 | corejs: { 12 | version: '3.3', 13 | proposals: true 14 | } 15 | } 16 | ], 17 | "@babel/preset-react" 18 | ], 19 | 20 | plugins: [ 21 | "@babel/plugin-syntax-dynamic-import", 22 | "@babel/plugin-syntax-import-meta", 23 | 24 | ["@babel/plugin-proposal-decorators", {legacy: true}], 25 | 26 | "@babel/plugin-proposal-export-namespace-from", 27 | "@babel/plugin-proposal-numeric-separator", 28 | "@babel/plugin-proposal-throw-expressions", 29 | 30 | ["@babel/plugin-transform-runtime", {useESModules: true}], 31 | 32 | "react-hot-loader/babel" 33 | ] 34 | }; 35 | 36 | if (!env("production")) 37 | res.plugins.push('@babel/plugin-transform-react-jsx-source'); 38 | 39 | return res; 40 | }; 41 | -------------------------------------------------------------------------------- /bin/chisel-cms: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require('../build/local.run'); -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | require('shelljs/global'); 2 | const path = require('path'); 3 | const ora = require('ora'); 4 | const webpack = require('webpack'); 5 | 6 | const webpackConfig = require(process.env.ELECTRON ? './webpack.prod-electron.config' : './webpack.prod.config'); 7 | 8 | let spinner = ora('building for production...'); 9 | spinner.start(); 10 | 11 | let destPath = path.resolve(__dirname, process.env.ELECTRON ? '../electron/dist' : '../dist'); 12 | rm('-rf', destPath); 13 | mkdir('-p', destPath); 14 | cp('-R', 'static/*', destPath); 15 | 16 | webpack(webpackConfig, (err, stats) => { 17 | spinner.stop(); 18 | if (err) 19 | throw err; 20 | process.stdout.write(stats.toString({ 21 | colors: true, 22 | modules: false, 23 | children: false, 24 | chunks: false, 25 | chunkModules: false 26 | }) + '\n'); 27 | }); 28 | -------------------------------------------------------------------------------- /build/local.run.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const path = require('path'); 3 | const program = require('commander'); 4 | 5 | 6 | program.option('--appId [appId]', 'the app Id of the app.'); 7 | program.option('--serverURL [serverURL]', 'the server url.'); 8 | program.option('--JSkey [JSkey]', 'the JS key.'); 9 | program.option('--RESTkey [RESTkey]', 'the REST key.'); 10 | program.option('--port [port]', 'the port to run Chisel'); 11 | 12 | program.parse(process.argv); 13 | const options = program.opts(); 14 | 15 | const port = options.port || process.env.PORT || 9000; 16 | const configServerURL = options.serverURL; 17 | const configAppId = options.appId; 18 | const configJSkey = options.JSkey; 19 | const configRESTkey = options.RESTkey; 20 | 21 | 22 | const server = new express(); 23 | 24 | server.use('/', express.static(path.resolve(__dirname, '../dist'))); 25 | 26 | server.get('/chisel-config.json', (req, res) => { 27 | const response = {configServerURL, configAppId, configJSkey, configRESTkey}; 28 | return res.json(response); 29 | }); 30 | 31 | server.get('*', (req, res) => 32 | res.sendFile(path.resolve(__dirname, '../dist/index.html')) 33 | ); 34 | 35 | server.listen(port, error => { 36 | if (error) 37 | console.error(error); 38 | else 39 | console.info(`==> Listening at http://localhost:${port}/`); 40 | }); 41 | -------------------------------------------------------------------------------- /build/server.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const WebpackDevServer = require('webpack-dev-server'); 3 | const path = require('path'); 4 | const {exec} = require('child_process'); 5 | 6 | const config = require('./webpack.dev.config'); 7 | 8 | 9 | const port = process.env.PORT || 9000; 10 | 11 | const server = new WebpackDevServer( 12 | { 13 | static: path.join(__dirname, '../static/'), 14 | historyApiFallback: true, 15 | devMiddleware: { 16 | publicPath: config.output.publicPath 17 | }, 18 | port, 19 | host: 'localhost', 20 | hot: true 21 | }, 22 | webpack(config) 23 | ); 24 | 25 | try { 26 | server.start(); 27 | } catch (error) { 28 | if (error) { 29 | console.error(error); 30 | return; 31 | } 32 | 33 | if (process.env.RUN_ELECTRON) 34 | exec('electron .', (error, stdout, stderr) => { 35 | if (error) { 36 | console.error(error); 37 | return; 38 | } 39 | 40 | console.log(`stdout: ${stdout}`); 41 | console.warn(`stderr: ${stderr}`); 42 | }); 43 | } 44 | -------------------------------------------------------------------------------- /build/webpack.base.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | 4 | 5 | module.exports = { 6 | entry: ['index'], 7 | output: { 8 | path: path.join(__dirname, '../dist/'), 9 | publicPath: '/' 10 | }, 11 | target: 'web', 12 | resolve: { 13 | modules: ['src', 'node_modules'], 14 | extensions: ['.js'], 15 | fallback: { 16 | crypto: false 17 | } 18 | }, 19 | plugins: [ 20 | new HtmlWebpackPlugin({ 21 | template: 'src/index.pug' 22 | }), 23 | ], 24 | module: { 25 | rules: [ 26 | { 27 | test: /\.js$/, 28 | loader: 'babel-loader', 29 | exclude: /node_modules/ 30 | }, 31 | { 32 | test: /\.pug$/, 33 | loader: 'pug-loader' 34 | }, 35 | { 36 | test: /\.svg$/, 37 | loader: 'svg-inline-loader' 38 | }, 39 | { 40 | test: /\.(png|jpe?g|gif)(\?.*)?$/, 41 | type: 'asset', 42 | parser: { 43 | dataUrlCondition: { 44 | maxSize: 3 * 1024 45 | } 46 | }, 47 | generator: { 48 | filename: 'assets/images/[name][ext]' 49 | } 50 | }, 51 | { 52 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 53 | type: 'asset', 54 | parser: { 55 | dataUrlCondition: { 56 | maxSize: 3 * 1024 57 | } 58 | }, 59 | generator: { 60 | filename: 'assets/fonts/[name].[hash:7][ext]' 61 | } 62 | } 63 | ] 64 | }, 65 | stats: { 66 | colors: true, 67 | chunks: false 68 | } 69 | }; 70 | -------------------------------------------------------------------------------- /build/webpack.dev-build.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const {merge} = require('webpack-merge'); 3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 4 | 5 | 6 | const baseWebpackConfig = require('./webpack.base.config'); 7 | 8 | 9 | process.env.NODE_ENV = 'development'; 10 | 11 | module.exports = merge(baseWebpackConfig, { 12 | mode: 'development', 13 | devtool: 'source-map', 14 | plugins: [ 15 | new MiniCssExtractPlugin({ 16 | filename: '[name].min.css' 17 | }) 18 | ], 19 | module: { 20 | rules: [ 21 | { 22 | test: /\.css$|\.global\.sss$/, 23 | use: [ 24 | { 25 | loader: MiniCssExtractPlugin.loader, 26 | options: {}, 27 | }, 28 | { 29 | loader: 'css-loader', 30 | options: { 31 | importLoaders: 1 32 | } 33 | }, 34 | 'postcss-loader' 35 | ] 36 | }, 37 | { 38 | test: /^((?!\.global).)*\.sss$/, 39 | use: [ 40 | { 41 | loader: MiniCssExtractPlugin.loader, 42 | options: {}, 43 | }, 44 | { 45 | loader: 'css-loader', 46 | options: { 47 | modules: { 48 | localIdentName: "[name]---[local]---[hash:base64:5]" 49 | }, 50 | importLoaders: 1 51 | } 52 | }, 53 | 'postcss-loader' 54 | ] 55 | } 56 | ] 57 | } 58 | }); 59 | -------------------------------------------------------------------------------- /build/webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | const {merge} = require('webpack-merge'); 2 | 3 | const baseWebpackConfig = require('./webpack.base.config'); 4 | 5 | 6 | process.env.NODE_ENV = 'development'; 7 | 8 | module.exports = merge(baseWebpackConfig, { 9 | mode: 'development', 10 | devtool: 'source-map', 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.css$|\.global\.sss$/, 15 | use: [ 16 | 'style-loader', 17 | { 18 | loader: 'css-loader', 19 | options: { 20 | importLoaders: 1 21 | } 22 | }, 23 | 'postcss-loader' 24 | ] 25 | }, 26 | { 27 | test: /^((?!\.global).)*\.sss$/, 28 | use: [ 29 | 'style-loader', 30 | { 31 | loader: 'css-loader', 32 | options: { 33 | modules: { 34 | localIdentName: "[name]---[local]---[hash:base64:5]", 35 | }, 36 | importLoaders: 1 37 | } 38 | }, 39 | 'postcss-loader' 40 | ] 41 | } 42 | ] 43 | } 44 | }); 45 | -------------------------------------------------------------------------------- /build/webpack.prod-electron.config.js: -------------------------------------------------------------------------------- 1 | const {merge} = require('webpack-merge'); 2 | const path = require('path'); 3 | 4 | const prodWebpackConfig = require('./webpack.prod.config'); 5 | 6 | module.exports = merge(prodWebpackConfig, { 7 | output: { 8 | path: path.join(__dirname, '../electron/dist/'), 9 | publicPath: './' 10 | }, 11 | target: 'electron-renderer' 12 | }); -------------------------------------------------------------------------------- /build/webpack.prod.config.js: -------------------------------------------------------------------------------- 1 | const {merge} = require('webpack-merge'); 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 3 | //const StatsPlugin = require('stats-webpack-plugin'); 4 | 5 | const baseWebpackConfig = require('./webpack.base.config'); 6 | 7 | 8 | process.env.NODE_ENV = 'production'; 9 | 10 | module.exports = merge(baseWebpackConfig, { 11 | mode: 'production', 12 | plugins: [ 13 | new MiniCssExtractPlugin({ 14 | filename: '[name].min.css' 15 | }) 16 | /*new StatsPlugin('webpack.stats.json', { 17 | source: false, 18 | modules: false 19 | })*/ 20 | ], 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.css$|\.global\.sss$/, 25 | use: [ 26 | { 27 | loader: MiniCssExtractPlugin.loader, 28 | options: {}, 29 | }, 30 | { 31 | loader: 'css-loader', 32 | options: { 33 | importLoaders: 1 34 | } 35 | }, 36 | 'postcss-loader' 37 | ] 38 | }, 39 | { 40 | test: /^((?!\.global).)*\.sss$/, 41 | use: [ 42 | { 43 | loader: MiniCssExtractPlugin.loader, 44 | options: {}, 45 | }, 46 | { 47 | loader: 'css-loader', 48 | options: { 49 | modules: { 50 | localIdentName: "[name]---[local]---[hash:base64:5]" 51 | }, 52 | importLoaders: 1 53 | } 54 | }, 55 | 'postcss-loader' 56 | ] 57 | } 58 | ] 59 | } 60 | }); 61 | -------------------------------------------------------------------------------- /dist/assets/fonts/Inter-UI-Bold.76d0e6d.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/assets/fonts/Inter-UI-Bold.76d0e6d.ttf -------------------------------------------------------------------------------- /dist/assets/fonts/Inter-UI-Medium.dc85c1d.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/assets/fonts/Inter-UI-Medium.dc85c1d.ttf -------------------------------------------------------------------------------- /dist/assets/fonts/Inter-UI-Regular.3c00ca2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/assets/fonts/Inter-UI-Regular.3c00ca2.ttf -------------------------------------------------------------------------------- /dist/assets/fonts/Inter-UI-SemiBold.95afbe2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/assets/fonts/Inter-UI-SemiBold.95afbe2.ttf -------------------------------------------------------------------------------- /dist/assets/fonts/OpenSans-Bold-webfont.a70355b.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/assets/fonts/OpenSans-Bold-webfont.a70355b.ttf -------------------------------------------------------------------------------- /dist/assets/fonts/OpenSans-Light-webfont.0f50ad5.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/assets/fonts/OpenSans-Light-webfont.0f50ad5.ttf -------------------------------------------------------------------------------- /dist/assets/fonts/OpenSans-Regular-webfont.d7553e1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/assets/fonts/OpenSans-Regular-webfont.d7553e1.ttf -------------------------------------------------------------------------------- /dist/assets/fonts/OpenSans-Semibold-webfont.7d4d140.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/assets/fonts/OpenSans-Semibold-webfont.7d4d140.ttf -------------------------------------------------------------------------------- /dist/assets/images/chisel-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/assets/images/chisel-logo.png -------------------------------------------------------------------------------- /dist/assets/images/chisel_login_illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/assets/images/chisel_login_illustration.png -------------------------------------------------------------------------------- /dist/assets/images/logo/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/assets/images/logo/apple-touch-icon.png -------------------------------------------------------------------------------- /dist/assets/images/logo/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/assets/images/logo/logo192.png -------------------------------------------------------------------------------- /dist/assets/images/logo/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/assets/images/logo/logo512.png -------------------------------------------------------------------------------- /dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/dist/favicon.ico -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | Chisel
-------------------------------------------------------------------------------- /dist/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Chisel", 3 | "name": "Chisel", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "48x48 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "\/assets\/images\/logo\/logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "\/assets\/images\/logo\/logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /dist/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /electron/build-resources/entitlements.mac.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-unsigned-executable-memory 6 | 7 | com.apple.security.cs.disable-library-validation 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /electron/build-resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/build-resources/icon.png -------------------------------------------------------------------------------- /electron/build-resources/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Beach.io 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /electron/dist/assets/fonts/Inter-UI-Bold.76d0e6d.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/assets/fonts/Inter-UI-Bold.76d0e6d.ttf -------------------------------------------------------------------------------- /electron/dist/assets/fonts/Inter-UI-Medium.dc85c1d.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/assets/fonts/Inter-UI-Medium.dc85c1d.ttf -------------------------------------------------------------------------------- /electron/dist/assets/fonts/Inter-UI-Regular.3c00ca2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/assets/fonts/Inter-UI-Regular.3c00ca2.ttf -------------------------------------------------------------------------------- /electron/dist/assets/fonts/Inter-UI-SemiBold.95afbe2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/assets/fonts/Inter-UI-SemiBold.95afbe2.ttf -------------------------------------------------------------------------------- /electron/dist/assets/fonts/OpenSans-Bold-webfont.a70355b.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/assets/fonts/OpenSans-Bold-webfont.a70355b.ttf -------------------------------------------------------------------------------- /electron/dist/assets/fonts/OpenSans-Light-webfont.0f50ad5.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/assets/fonts/OpenSans-Light-webfont.0f50ad5.ttf -------------------------------------------------------------------------------- /electron/dist/assets/fonts/OpenSans-Regular-webfont.d7553e1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/assets/fonts/OpenSans-Regular-webfont.d7553e1.ttf -------------------------------------------------------------------------------- /electron/dist/assets/fonts/OpenSans-Semibold-webfont.7d4d140.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/assets/fonts/OpenSans-Semibold-webfont.7d4d140.ttf -------------------------------------------------------------------------------- /electron/dist/assets/images/chisel-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/assets/images/chisel-logo.png -------------------------------------------------------------------------------- /electron/dist/assets/images/chisel_login_illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/assets/images/chisel_login_illustration.png -------------------------------------------------------------------------------- /electron/dist/assets/images/logo/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/assets/images/logo/apple-touch-icon.png -------------------------------------------------------------------------------- /electron/dist/assets/images/logo/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/assets/images/logo/logo192.png -------------------------------------------------------------------------------- /electron/dist/assets/images/logo/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/assets/images/logo/logo512.png -------------------------------------------------------------------------------- /electron/dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/dist/favicon.ico -------------------------------------------------------------------------------- /electron/dist/index.html: -------------------------------------------------------------------------------- 1 | Chisel
-------------------------------------------------------------------------------- /electron/dist/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Chisel", 3 | "name": "Chisel", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "48x48 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "\/assets\/images\/logo\/logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "\/assets\/images\/logo\/logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /electron/dist/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /electron/electron-builder.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | 3 | const pkgMain = require('../package.json'); 4 | 5 | module.exports = { 6 | appId: "io.beach.chisel-cms", 7 | productName: "Chisel CMS", 8 | copyright: "Copyright © 2021, Beach.io", 9 | extraMetadata: { 10 | name: pkgMain.name, 11 | version: pkgMain.version, 12 | description: pkgMain.description, 13 | author: pkgMain.author, 14 | license: pkgMain.license, 15 | homepage: pkgMain.homepage, 16 | repository: pkgMain.repository, 17 | bugs: pkgMain.bugs, 18 | 19 | main: "electron/electron.js" 20 | }, 21 | directories: { 22 | output: 'electron/bin', 23 | buildResources: 'electron/build-resources', 24 | app: "electron" 25 | }, 26 | files: [ 27 | "package.json", 28 | "dist", 29 | { 30 | filter: "electron.js", 31 | to: "electron" 32 | }, 33 | { 34 | from: "server-selector/dist", 35 | to: "server-selector" 36 | } 37 | ], 38 | mac: { 39 | category: "public.app-category.developer-tools", 40 | hardenedRuntime: true, 41 | gatekeeperAssess: false, 42 | entitlements: "electron/build-resources/entitlements.mac.plist", 43 | entitlementsInherit: "electron/build-resources/entitlements.mac.plist", 44 | extendInfo: { 45 | 'NSUserNotificationAlertStyle': 'alert' 46 | } 47 | }, 48 | dmg: { 49 | sign: false 50 | }, 51 | linux: { 52 | category: "Network" 53 | }, 54 | nsis: { 55 | oneClick: false, 56 | allowToChangeInstallationDirectory: true 57 | }, 58 | publish: { 59 | provider: 'github', 60 | releaseType: 'draft' 61 | }, 62 | asar: true, 63 | afterSign: "electron/notarize.js" 64 | }; -------------------------------------------------------------------------------- /electron/notarize.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | const {notarize} = require('electron-notarize'); 3 | const electronBuilderConfig = require('./electron-builder.js'); 4 | 5 | exports.default = async context => { 6 | const {electronPlatformName, appOutDir} = context; 7 | if (electronPlatformName !== 'darwin') 8 | return; 9 | 10 | const appName = context.packager.appInfo.productFilename; 11 | console.log('STARTING NOTARIZATION'); 12 | 13 | return await notarize({ 14 | appBundleId: electronBuilderConfig.appId, 15 | appPath: `${appOutDir}/${appName}.app`, 16 | appleId: process.env.APPLE_ID, 17 | appleIdPassword: process.env.APPLE_ID_PASS, 18 | ascProvider: process.env.APPLE_PROVIDER 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /electron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@electron/remote": "^2.0.1", 4 | "electron-is-dev": "^2.0.0", 5 | "electron-log": "^4.4.1", 6 | "electron-updater": "^4.6.1" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /electron/server-selector/build.js: -------------------------------------------------------------------------------- 1 | require('shelljs/global'); 2 | const path = require('path'); 3 | const ora = require('ora'); 4 | const webpack = require('webpack'); 5 | 6 | const webpackConfig = require('./webpack.prod.config'); 7 | 8 | 9 | let spinner = ora('building for production...'); 10 | spinner.start(); 11 | 12 | let destPath = path.resolve(__dirname, './dist'); 13 | rm('-rf', destPath); 14 | mkdir('-p', destPath); 15 | 16 | webpack(webpackConfig, (err, stats) => { 17 | spinner.stop(); 18 | if (err) 19 | throw err; 20 | process.stdout.write(stats.toString({ 21 | colors: true, 22 | modules: false, 23 | children: false, 24 | chunks: false, 25 | chunkModules: false 26 | }) + '\n'); 27 | }); 28 | -------------------------------------------------------------------------------- /electron/server-selector/dist/assets/fonts/Inter-UI-Bold.76d0e6d.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/server-selector/dist/assets/fonts/Inter-UI-Bold.76d0e6d.ttf -------------------------------------------------------------------------------- /electron/server-selector/dist/assets/fonts/Inter-UI-Medium.dc85c1d.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/server-selector/dist/assets/fonts/Inter-UI-Medium.dc85c1d.ttf -------------------------------------------------------------------------------- /electron/server-selector/dist/assets/fonts/Inter-UI-Regular.3c00ca2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/server-selector/dist/assets/fonts/Inter-UI-Regular.3c00ca2.ttf -------------------------------------------------------------------------------- /electron/server-selector/dist/assets/fonts/Inter-UI-SemiBold.95afbe2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/electron/server-selector/dist/assets/fonts/Inter-UI-SemiBold.95afbe2.ttf -------------------------------------------------------------------------------- /electron/server-selector/dist/index.html: -------------------------------------------------------------------------------- 1 | Chisel
-------------------------------------------------------------------------------- /electron/server-selector/dist/main.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /** @license React v0.19.1 8 | * scheduler.production.min.js 9 | * 10 | * Copyright (c) Facebook, Inc. and its affiliates. 11 | * 12 | * This source code is licensed under the MIT license found in the 13 | * LICENSE file in the root directory of this source tree. 14 | */ 15 | 16 | /** @license React v16.14.0 17 | * react-dom.production.min.js 18 | * 19 | * Copyright (c) Facebook, Inc. and its affiliates. 20 | * 21 | * This source code is licensed under the MIT license found in the 22 | * LICENSE file in the root directory of this source tree. 23 | */ 24 | 25 | /** @license React v16.14.0 26 | * react.production.min.js 27 | * 28 | * Copyright (c) Facebook, Inc. and its affiliates. 29 | * 30 | * This source code is licensed under the MIT license found in the 31 | * LICENSE file in the root directory of this source tree. 32 | */ 33 | -------------------------------------------------------------------------------- /electron/server-selector/server.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const WebpackDevServer = require('webpack-dev-server'); 3 | const path = require('path'); 4 | 5 | const config = require('./webpack.dev.config'); 6 | 7 | 8 | const port = process.env.PORT || 9900; 9 | 10 | const server = new WebpackDevServer( 11 | { 12 | static: path.join(__dirname, './static/'), 13 | historyApiFallback: true, 14 | devMiddleware: { 15 | publicPath: config.output.publicPath 16 | }, 17 | port, 18 | host: 'localhost', 19 | hot: true 20 | }, 21 | webpack(config) 22 | ); 23 | 24 | 25 | try { 26 | server.start(); 27 | } catch (error) { 28 | console.error(error); 29 | } 30 | -------------------------------------------------------------------------------- /electron/server-selector/src/app.sss: -------------------------------------------------------------------------------- 1 | .content 2 | width: 100% 3 | padding: 30px 4 | padding-right: 50px 5 | 6 | display: flex 7 | flex-flow: row nowrap 8 | justify-content: space-between 9 | 10 | letter-spacing: 0.5px 11 | font-size: 14px 12 | color: #2C2C30 13 | 14 | .side 15 | flex: 0 0 270px 16 | padding-right: 40px 17 | 18 | .server 19 | display: flex 20 | flex-flow: row nowrap 21 | justify-content: space-between 22 | align-items: center 23 | 24 | padding-bottom: 10px 25 | padding-top: 10px 26 | padding-right: 11px 27 | margin-bottom: 10px 28 | border-radius: 20px 29 | 30 | background: #FFFFFF 31 | box-shadow: 0 1px 0 0 rgba(0,0,0,0.05), 0 1px 10px 0 rgba(0,0,0,0.05) 32 | cursor: pointer 33 | 34 | &-checked 35 | background: #eeeeee 36 | 37 | .name 38 | font-size: 14px 39 | color: #313133 40 | line-height: 24px 41 | padding-left: 15px 42 | user-select: none 43 | 44 | &-new 45 | .name 46 | font-weight: 300 47 | 48 | 49 | .main 50 | flex: 1 51 | padding-left: 40px 52 | color: #666666 53 | 54 | .label 55 | user-select: none 56 | 57 | .input-wrapper 58 | margin-bottom: 30px 59 | 60 | .error 61 | margin-top: 40px 62 | color: red 63 | 64 | .buttons 65 | margin-top: 40px 66 | 67 | .button-wrapper 68 | display: inline-block 69 | margin-right: 40px 70 | 71 | &:last-child 72 | margin-right: 0 73 | 74 | .icon-plus 75 | width: 18px 76 | height: 18px -------------------------------------------------------------------------------- /electron/server-selector/src/fonts.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Inter-UI'; 3 | src: url('~assets/fonts/Inter-UI-Regular.ttf'); 4 | font-weight: normal; 5 | font-style: normal; 6 | } 7 | 8 | @font-face { 9 | font-family: 'Inter-UI'; 10 | src: url('~assets/fonts/Inter-UI-Medium.ttf'); 11 | font-weight: 500; 12 | font-style: normal; 13 | } 14 | 15 | @font-face { 16 | font-family: 'Inter-UI'; 17 | src: url('~assets/fonts/Inter-UI-SemiBold.ttf'); 18 | font-weight: 600; 19 | font-style: normal; 20 | } 21 | 22 | @font-face { 23 | font-family: 'Inter-UI'; 24 | src: url('~assets/fonts/Inter-UI-Bold.ttf'); 25 | font-weight: 700; 26 | font-style: normal; 27 | } -------------------------------------------------------------------------------- /electron/server-selector/src/index.js: -------------------------------------------------------------------------------- 1 | import 'whatwg-fetch'; 2 | 3 | import 'normalize.css'; 4 | import './fonts.css'; 5 | import './styles.global.sss'; 6 | 7 | 8 | import React from 'react'; 9 | import ReactDOM from 'react-dom'; 10 | 11 | import App from 'app'; 12 | 13 | 14 | ReactDOM.render( 15 | , 16 | document.getElementById('app-root') 17 | ); 18 | -------------------------------------------------------------------------------- /electron/server-selector/src/index.pug: -------------------------------------------------------------------------------- 1 | html(lang="en") 2 | head 3 | meta(charset="utf-8") 4 | meta(http-equiv="Content-Type" content="text/html") 5 | meta(http-equiv="x-ua-compatible" content="ie=edge") 6 | title Chisel CMS: Server Selection 7 | meta(name="viewport" content="width=device-width, initial-scale=1") 8 | base(href="./") 9 | body 10 | #app-root 11 | -------------------------------------------------------------------------------- /electron/server-selector/src/styles.global.sss: -------------------------------------------------------------------------------- 1 | * 2 | box-sizing: border-box 3 | 4 | body 5 | -webkit-font-smoothing: antialiased 6 | font-family: 'Inter UI', sans-serif 7 | background: #fff 8 | 9 | a 10 | text-decoration: none 11 | outline: none 12 | 13 | fieldset 14 | border: 0 15 | margin: 0 16 | padding: 0 17 | 18 | p 19 | color: inherit 20 | 21 | 22 | input::-webkit-outer-spin-button, 23 | input::-webkit-inner-spin-button 24 | -webkit-appearance: none 25 | margin: 0 26 | -------------------------------------------------------------------------------- /electron/server-selector/webpack.base.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | 4 | 5 | module.exports = { 6 | entry: ['index'], 7 | output: { 8 | path: path.join(__dirname, './dist'), 9 | }, 10 | resolve: { 11 | modules: ['electron/server-selector/src', 'src', 'node_modules'], 12 | extensions: ['.js'] 13 | }, 14 | plugins: [ 15 | new HtmlWebpackPlugin({ 16 | template: 'src/index.pug' 17 | }), 18 | ], 19 | module: { 20 | rules: [ 21 | { 22 | test: /\.js$/, 23 | loader: 'babel-loader', 24 | exclude: /node_modules/ 25 | }, 26 | { 27 | test: /\.pug$/, 28 | loader: 'pug-loader' 29 | }, 30 | { 31 | test: /\.svg$/, 32 | loader: 'svg-inline-loader' 33 | }, 34 | { 35 | test: /\.(png|jpe?g|gif)(\?.*)?$/, 36 | type: 'asset', 37 | parser: { 38 | dataUrlCondition: { 39 | maxSize: 3 * 1024 40 | } 41 | }, 42 | generator: { 43 | filename: 'assets/images/[name][ext]' 44 | } 45 | }, 46 | { 47 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 48 | type: 'asset', 49 | parser: { 50 | dataUrlCondition: { 51 | maxSize: 3 * 1024 52 | } 53 | }, 54 | generator: { 55 | filename: 'assets/fonts/[name].[hash:7][ext]' 56 | } 57 | } 58 | ] 59 | }, 60 | stats: { 61 | colors: true, 62 | chunks: false 63 | } 64 | }; 65 | -------------------------------------------------------------------------------- /electron/server-selector/webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | const {merge} = require('webpack-merge'); 2 | 3 | const baseWebpackConfig = require('./webpack.base.config'); 4 | 5 | 6 | process.env.NODE_ENV = 'development'; 7 | 8 | module.exports = merge(baseWebpackConfig, { 9 | mode: 'development', 10 | devtool: 'source-map', 11 | output: { 12 | publicPath: '/' 13 | }, 14 | module: { 15 | rules: [ 16 | { 17 | test: /\.css$|\.global\.sss$/, 18 | use: [ 19 | 'style-loader', 20 | { 21 | loader: 'css-loader', 22 | options: { 23 | importLoaders: 1 24 | } 25 | }, 26 | 'postcss-loader' 27 | ] 28 | }, 29 | { 30 | test: /^((?!\.global).)*\.sss$/, 31 | use: [ 32 | 'style-loader', 33 | { 34 | loader: 'css-loader', 35 | options: { 36 | modules: { 37 | localIdentName: "[name]---[local]---[hash:base64:5]", 38 | }, 39 | importLoaders: 1 40 | } 41 | }, 42 | 'postcss-loader' 43 | ] 44 | } 45 | ] 46 | } 47 | }); 48 | -------------------------------------------------------------------------------- /electron/server-selector/webpack.prod.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const {merge} = require('webpack-merge'); 3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 4 | //const StatsPlugin = require('stats-webpack-plugin'); 5 | 6 | const baseWebpackConfig = require('./webpack.base.config'); 7 | 8 | 9 | process.env.NODE_ENV = 'production'; 10 | 11 | module.exports = merge(baseWebpackConfig, { 12 | mode: 'production', 13 | plugins: [ 14 | new MiniCssExtractPlugin({ 15 | filename: '[name].min.css' 16 | }) 17 | /*new StatsPlugin('webpack.stats.json', { 18 | source: false, 19 | modules: false 20 | })*/ 21 | ], 22 | output: { 23 | publicPath: './' 24 | }, 25 | module: { 26 | rules: [ 27 | { 28 | test: /\.css$|\.global\.sss$/, 29 | use: [ 30 | { 31 | loader: MiniCssExtractPlugin.loader, 32 | options: {}, 33 | }, 34 | { 35 | loader: 'css-loader', 36 | options: { 37 | importLoaders: 1 38 | } 39 | }, 40 | 'postcss-loader' 41 | ] 42 | }, 43 | { 44 | test: /^((?!\.global).)*\.sss$/, 45 | use: [ 46 | { 47 | loader: MiniCssExtractPlugin.loader, 48 | options: {}, 49 | }, 50 | { 51 | loader: 'css-loader', 52 | options: { 53 | modules: { 54 | localIdentName: "[name]---[local]---[hash:base64:5]" 55 | }, 56 | importLoaders: 1 57 | } 58 | }, 59 | 'postcss-loader' 60 | ] 61 | } 62 | ] 63 | } 64 | }); 65 | -------------------------------------------------------------------------------- /forgerc.txt: -------------------------------------------------------------------------------- 1 | NotFound 2 | Rewrite /index.html 3 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = ({file, options, env}) => { 2 | const res = { 3 | plugins: [] 4 | }; 5 | 6 | let extname; 7 | if (file.extname) 8 | extname = file.extname; 9 | else 10 | extname = file.substring(file.lastIndexOf('.')); 11 | 12 | if (extname === '.sss') { 13 | res.parser = 'sugarss'; 14 | res.plugins.push(require('postcss-nested')); 15 | res.plugins.push(require('postcss-advanced-variables')); 16 | } 17 | 18 | res.plugins.push( 19 | require('postcss-flexbugs-fixes'), 20 | require('autoprefixer') 21 | ); 22 | 23 | if (env == 'production') 24 | res.plugins.push(require('cssnano')({ 25 | preset: ['default', { 26 | discardEmpty: false, 27 | }] 28 | })); 29 | 30 | return res; 31 | }; 32 | -------------------------------------------------------------------------------- /src/ConnectConstants.js: -------------------------------------------------------------------------------- 1 | export let config = { 2 | // Dev local env 3 | serverURL: "http://localhost:1337/parse", 4 | appId: 'SampleAppId', 5 | 6 | // Dev remote env 7 | // serverURL: "https://chisel-parse-server.herokuapp.com/parse", 8 | // appId: 'SampleAppId', 9 | 10 | // Dev remote old env 11 | // serverURL: "https://pg-app-mjx6kfptatphej7zd7ccy9ctlkdtix.scalabl.cloud/1/", 12 | // appId: "7d52447901ab6b8b91e3f2e846256184", 13 | 14 | // Prod env 15 | // serverURL: "http://dockerhost.forge-parse-server.c66.me:99/parse", 16 | // appId: "7d52447901ab6b8b91e3f2e846256184", 17 | 18 | JSkey: `liYLwLfENUIiiD6bz8TerwIZPPnJWP3VVHCSUUOT`, 19 | RESTkey: `AMMaWJMu4u6hSANZfbBFZHLhU83DWOXHXPVnPHJE` 20 | }; 21 | 22 | export const FILE_SIZE_MAX = 10 * 1024 * 1024; 23 | -------------------------------------------------------------------------------- /src/assets/fonts/Inter-UI-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/fonts/Inter-UI-Bold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Inter-UI-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/fonts/Inter-UI-Medium.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Inter-UI-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/fonts/Inter-UI-Regular.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Inter-UI-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/fonts/Inter-UI-SemiBold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/OpenSans-Bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/fonts/OpenSans-Bold-webfont.ttf -------------------------------------------------------------------------------- /src/assets/fonts/OpenSans-Light-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/fonts/OpenSans-Light-webfont.ttf -------------------------------------------------------------------------------- /src/assets/fonts/OpenSans-Regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/fonts/OpenSans-Regular-webfont.ttf -------------------------------------------------------------------------------- /src/assets/fonts/OpenSans-Semibold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/fonts/OpenSans-Semibold-webfont.ttf -------------------------------------------------------------------------------- /src/assets/images/Checkbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/images/Checkbox.png -------------------------------------------------------------------------------- /src/assets/images/Checkbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Checkbox 5 | Created with Sketch. 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 | -------------------------------------------------------------------------------- /src/assets/images/arrow-down-full.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 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 | -------------------------------------------------------------------------------- /src/assets/images/arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Shape 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/assets/images/arrows.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Icon 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/assets/images/chisel-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/images/chisel-logo.png -------------------------------------------------------------------------------- /src/assets/images/chisel-logo@2x square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/images/chisel-logo@2x square.png -------------------------------------------------------------------------------- /src/assets/images/chisel-logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/images/chisel-logo@2x.png -------------------------------------------------------------------------------- /src/assets/images/chisel_login_illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/images/chisel_login_illustration.png -------------------------------------------------------------------------------- /src/assets/images/cross-circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 4 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/assets/images/hammer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-Hammer 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/images/icons/cross.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cross 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/images/icons/delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Icon - Delete 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/assets/images/icons/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Icon - Edit 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/assets/images/icons/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-Popup 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/assets/images/icons/lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Shape 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/images/icons/plus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-Add 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/images/icons/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | search 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/images/icons/sidebar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Created with Sketch. 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/images/icons/users.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Created with Sketch. 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/assets/images/media-types/archive.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 | -------------------------------------------------------------------------------- /src/assets/images/media-types/exe.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 | -------------------------------------------------------------------------------- /src/assets/images/media-types/html.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 | -------------------------------------------------------------------------------- /src/assets/images/media-types/other.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 | -------------------------------------------------------------------------------- /src/assets/images/media-types/xml.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 | -------------------------------------------------------------------------------- /src/assets/images/media-types/zip.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 | -------------------------------------------------------------------------------- /src/assets/images/okay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/images/okay.png -------------------------------------------------------------------------------- /src/assets/images/okay.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/images/product-logo-b.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Product Logo 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/assets/images/product-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Product Logo 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/assets/images/template-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/assets/images/template-empty.png -------------------------------------------------------------------------------- /src/assets/images/template-empty.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/components/elements/ButtonControl/ButtonControl.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import LoaderComponent from "components/elements/LoaderComponent/LoaderComponent"; 4 | 5 | import styles from './ButtonControl.sss'; 6 | 7 | 8 | export default ({value, color, onClick, type, disabled, DOMRef, showLoader, minWidth}) => { 9 | if (!type) 10 | type = 'button'; 11 | 12 | if (!minWidth) 13 | minWidth = 150; 14 | 15 | let buttonControlClasses = styles.ButtonControl; 16 | if (disabled) { 17 | onClick = null; 18 | buttonControlClasses += ' ' + styles[`ButtonControl-disabled`]; 19 | } else if (color) { 20 | buttonControlClasses += ' ' + styles[`ButtonControl-${color}`]; 21 | } 22 | 23 | let ref = React.createRef(); 24 | if (DOMRef) 25 | DOMRef(ref.current); 26 | 27 | return ( 28 | 40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /src/components/elements/ButtonControl/ButtonControl.sss: -------------------------------------------------------------------------------- 1 | .ButtonControl 2 | font-family: 'Inter-UI', sans-serif 3 | border-radius: 20px 4 | border: 0px solid rgba(0,0,0,0) 5 | outline: none 6 | 7 | font-size: 14px 8 | color: #313133 9 | font-weight: 500 10 | 11 | letter-spacing: 0.5px 12 | height: 40px 13 | padding: 0 30px 14 | background: #ffffff 15 | 16 | cursor: pointer 17 | text-align: center 18 | 19 | display: flex 20 | justify-content: center 21 | align-items: center 22 | 23 | box-shadow: 0 1px 0 0 rgba(0,0,0,0.07), 0 1px 10px 0 rgba(0,0,0,0.07) 24 | 25 | transition: transform 0.2s 26 | 27 | &-red 28 | background-image: linear-gradient(-90deg, #c66a6a 0%, #bc5b5b 150%) 29 | box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.15) 30 | color: #ffffff 31 | 32 | &-red-outline 33 | border: 2px solid #c66a6a 34 | box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.15) 35 | 36 | &-green 37 | background-image: linear-gradient(-90deg, #57C95A 0%, #388E3C 150%) 38 | box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.10) 39 | color: #ffffff 40 | 41 | &-gray 42 | background-image: linear-gradient(-180deg, #607D8B 0%, #3E5059 150%) 43 | box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.20) 44 | color: #ffffff 45 | 46 | &-purple 47 | background-image: linear-gradient(-90deg, #8a5ebe 0%, #7b50b2 150%) 48 | box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.15) 49 | color: #ffffff 50 | 51 | &-black 52 | background-image: linear-gradient(-90deg, #434349 0%, #37373c 150%) 53 | box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.15) 54 | color: #ffffff 55 | 56 | &:hover 57 | box-shadow: 0 1px 0 0 rgba(0,0,0,0.05), 0 1px 20px 0 rgba(0,0,0,0.05) 58 | transform: translateY(-3px) 59 | 60 | &:active 61 | box-shadow: 0 1px 0 0 rgba(0,0,0,0.05), 0 1px 15px 0 rgba(0,0,0,0.05) 62 | transform: translateY(-1px) 63 | 64 | &-disabled 65 | color: #A4A4AE 66 | 67 | &:hover 68 | transform: translateY(0px) 69 | 70 | .loader-wrapper 71 | margin-left: 15px 72 | -------------------------------------------------------------------------------- /src/components/elements/CheckboxControl/CheckboxControl.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import CSSModules from 'react-css-modules'; 3 | 4 | import {getUniqueId} from 'utils/common'; 5 | 6 | import styles from './CheckboxControl.sss'; 7 | 8 | 9 | @CSSModules(styles, {allowMultiple: true}) 10 | export default class CheckboxControl extends Component { 11 | id = getUniqueId(); 12 | 13 | onChange = e => { 14 | const {onChange, disabled} = this.props; 15 | if (onChange && !disabled) 16 | onChange(e.target.checked); 17 | }; 18 | 19 | render() { 20 | const {title, checked, disabled} = this.props; 21 | let style = `CheckboxControl`; 22 | if (disabled) 23 | style += ` disabled`; 24 | 25 | return ( 26 |
27 |
28 | 35 | 36 |
37 |
38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/components/elements/CheckboxControl/CheckboxControl.sss: -------------------------------------------------------------------------------- 1 | .CheckboxControl 2 | display: flex 3 | flex-flow: row nowrap 4 | align-items: center 5 | 6 | .checkbox 7 | display: none 8 | 9 | &-button 10 | margin-right: 26px 11 | 12 | &-label 13 | cursor: pointer 14 | position: relative 15 | padding-left: 30px 16 | 17 | font-size: 14px 18 | color: #2C2C30 19 | letter-spacing: 0.5px 20 | user-select: none 21 | 22 | &-label:before 23 | content: '' 24 | position: absolute 25 | left: 0 26 | top: 50% 27 | transform: translateY(-50%) 28 | height: 20px 29 | width: 20px 30 | border-radius: 33% 31 | background: #fff 32 | border: 1px solid #E5E5E5 33 | 34 | &:checked + &-label:before 35 | content: '' 36 | color: #ffffff 37 | font-size: 21px 38 | text-indent: 2px 39 | background: url('assets/images/Checkbox.png') no-repeat center center / contain 40 | 41 | & + &-label:before, 42 | &:checked + &-label:before 43 | transition: background 0.1s ease 44 | 45 | .disabled 46 | 47 | .checkbox-label 48 | color: #999999 49 | 50 | .checkbox-label:before 51 | border: 1px solid #bfbfbf 52 | 53 | .checkbox:checked + .checkbox-label:before 54 | background: #dbdbdb 55 | 56 | -------------------------------------------------------------------------------- /src/components/elements/ContainerComponent/ContainerComponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import LoaderComponent from "components/elements/LoaderComponent/LoaderComponent"; 4 | 5 | import styles from './ContainerComponent.sss'; 6 | 7 | 8 | export default ({haveTitle2, title, titles, children, onClickRlink, rLinkTitle, showLoader}) => { 9 | let headerStyles = styles['header']; 10 | if (haveTitle2) 11 | headerStyles += ' ' + styles['header-double']; 12 | 13 | let titlesCmp = titles; 14 | if (title) 15 | titlesCmp =
{title}
; 16 | 17 | let contentStyles = styles['content']; 18 | if (showLoader) 19 | contentStyles += ' ' + styles['loader-active']; 20 | 21 | return ( 22 |
23 | {showLoader && 24 |
25 | 26 |
27 | } 28 |
29 | {titlesCmp} 30 | {(!!rLinkTitle && !!onClickRlink) && 31 |
32 | {rLinkTitle} 33 |
34 | } 35 |
36 |
37 | {children} 38 |
39 |
40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /src/components/elements/ContainerComponent/ContainerComponent.sss: -------------------------------------------------------------------------------- 1 | .ContainerComponent 2 | width: 90% 3 | position: relative 4 | 5 | .loader-wrapper 6 | position: absolute 7 | z-index: 80 8 | height: 100% 9 | width: 100% 10 | top: 0 11 | left: 0 12 | display: flex 13 | flex-flow: column nowrap 14 | justify-content: center 15 | align-items: center 16 | 17 | .header 18 | position: relative 19 | 20 | display: flex 21 | flex-flow: row nowrap 22 | align-items: center 23 | 24 | text-align: center 25 | 26 | margin-bottom: 20px 27 | 28 | .title 29 | letter-spacing: 0.83px 30 | text-align: left 31 | font-size: 30px 32 | color: #2C2C30 33 | font-weight: 700 34 | font-family: 'Inter-UI', sans-serif 35 | user-select: none 36 | 37 | .json-fields, 38 | .back 39 | font-size: 13px 40 | color: #999999 41 | letter-spacing: 0.5px 42 | 43 | position: absolute 44 | top: 50% 45 | transform: translateY(-50%) 46 | cursor: pointer 47 | user-select: none 48 | 49 | .back 50 | left: 34px 51 | 52 | .json-fields 53 | right: 34px 54 | 55 | .header-double 56 | min-height: 55px 57 | 58 | .content 59 | width: 100% 60 | 61 | .loader-active 62 | opacity: .3 63 | -------------------------------------------------------------------------------- /src/components/elements/DynamicListComponent/DynamicListComponent.sss: -------------------------------------------------------------------------------- 1 | .item 2 | display: flex 3 | align-items: center 4 | margin-bottom: 10px 5 | 6 | &:last-child 7 | margin-bottom: 0 8 | 9 | &:not(:first-child) 10 | input 11 | border-radius: 20px 12 | 13 | &-input 14 | cursor: auto 15 | 16 | &-plus, 17 | &-minus 18 | margin-left: 14px 19 | font-size: 32px 20 | color: #2c2c30 21 | cursor: pointer 22 | 23 | &-minus 24 | padding-bottom: 6px 25 | 26 | &-plus:hover, 27 | &-minus:hover 28 | color: #777777 29 | 30 | 31 | .plus 32 | font-size: 14px 33 | color: #999999 34 | cursor: pointer 35 | -------------------------------------------------------------------------------- /src/components/elements/EditableTitleControl/EditableTitleControl.sss: -------------------------------------------------------------------------------- 1 | .wrapper 2 | /*width: 80%*/ 3 | position: relative 4 | 5 | .input 6 | background: none 7 | border: 1px solid rgba(0,0,0,0) 8 | outline: none 9 | 10 | font-size: 20px 11 | color: #666666 12 | letter-spacing: 0.83px 13 | line-height: 27px 14 | text-align: center 15 | 16 | .input-small 17 | font-size: 12px 18 | letter-spacing: 0.46px 19 | line-height: 17px 20 | 21 | .input-editing 22 | border-bottom: 1px solid #cccccc !important 23 | color: #333333 24 | 25 | .edit 26 | font-size: 12px 27 | color: #b1b1b1 28 | font-weight: 600 29 | display: inline-block 30 | position: absolute 31 | top: 50% 32 | transform: translateY(-50%) 33 | margin-left: 5px 34 | cursor: pointer 35 | opacity: 0.01 36 | transition: opacity 0.2s ease 37 | will-change: opacity 38 | 39 | visibility: hidden 40 | 41 | .wrapper-hover 42 | .edit 43 | visibility: visible 44 | 45 | .wrapper-hover:hover .edit 46 | opacity: 0.99 47 | -------------------------------------------------------------------------------- /src/components/elements/IconsComponent/IconsComponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import InlineSVG from 'svg-inline-react'; 3 | 4 | export default props => 5 | ; 6 | -------------------------------------------------------------------------------- /src/components/elements/InputControl/InputControl.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import CSSModules from 'react-css-modules'; 3 | 4 | import {addElectronContextMenu} from "utils/common"; 5 | 6 | import IconsComponent from 'components/elements/IconsComponent/IconsComponent'; 7 | 8 | import styles from './InputControl.sss'; 9 | 10 | 11 | @CSSModules(styles, {allowMultiple: true}) 12 | export default class InputControl extends Component { 13 | onChange = e => { 14 | const {onChange} = this.props; 15 | if (onChange) 16 | onChange(e.target.value); 17 | }; 18 | 19 | setRef = ref => { 20 | const {readOnly, DOMRef} = this.props; 21 | addElectronContextMenu(ref, readOnly); 22 | if (DOMRef) 23 | DOMRef(ref); 24 | } 25 | 26 | render() { 27 | let {label, type, value, placeholder, onChange, readOnly, autoFocus, onKeyDown, onBlur, icon, 28 | onIconClick, inputType, dropdown, titled, red} = this.props; 29 | 30 | if (!onChange) 31 | readOnly = true; 32 | 33 | if (value == undefined) 34 | value = ``; 35 | 36 | if (!inputType) 37 | inputType = `text`; 38 | 39 | let inputStyles = 'input'; 40 | if (type === 'big') 41 | inputStyles = 'input-big'; 42 | if (readOnly) 43 | inputStyles += ' input-readOnly'; 44 | if (dropdown) 45 | inputStyles += ' input-disabled'; 46 | if (label || titled) 47 | inputStyles += ' input-titled'; 48 | if (red) 49 | inputStyles += ' input-red'; 50 | 51 | let iconEl; 52 | if (icon) 53 | iconEl = ( 54 |
55 | 56 |
); 57 | 58 | return ( 59 |
60 | {!!label && 61 | 62 | } 63 |
64 | {iconEl} 65 | 75 |
76 |
77 | ); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/components/elements/InputControl/InputControl.sss: -------------------------------------------------------------------------------- 1 | .InputControl 2 | width: 100% 3 | 4 | .input-wrapper 5 | width: 100% 6 | text-align: left 7 | display: flex 8 | flex-flow: column nowrap 9 | position: relative 10 | 11 | .label 12 | letter-spacing: 0.5px 13 | line-height: 30px 14 | position: relative 15 | 16 | font-size: 14px 17 | color: #2C2C30 18 | /* margin-left: 3px */ 19 | user-select: none 20 | 21 | transition: color 0.2s ease 22 | will-change: color 23 | 24 | .input-big 25 | background: #FFFFFF 26 | border: 1px solid rgba(0,0,0,0.1) 27 | box-shadow: inset 0 1px 5px 0 rgba(0,0,0,0.05) 28 | border-radius: 20px 29 | 30 | outline: none 31 | font-size: 14px 32 | line-height: 24px 33 | color: #2C2C30 34 | letter-spacing: 0.5px 35 | padding: 8px 16px 36 | 37 | width: 100% 38 | margin-top: 0 39 | order: 2 40 | 41 | .icon 42 | position: absolute 43 | top: 50% 44 | transform: translateY(-50%) 45 | right: 15px 46 | width: 18px 47 | height: 18px 48 | 49 | .lock 50 | right: 12px 51 | height: 24px 52 | width: 16px 53 | 54 | .plus 55 | cursor: pointer 56 | 57 | .users 58 | width: 15px 59 | height: 16px 60 | cursor: pointer 61 | 62 | .search 63 | height: 18px 64 | 65 | .cross 66 | cursor: pointer 67 | 68 | .input 69 | background: #FFFFFF 70 | border: 1px solid rgba(0,0,0,0.1) 71 | box-shadow: inset 0 1px 5px 0 rgba(0,0,0,0.05) 72 | border-radius: 20px 73 | padding: 8px 16px 74 | margin-top: 0px 75 | outline: none 76 | font-size: 14px 77 | color: #2C2C30 78 | line-height: 24px 79 | font-weight: 400 80 | letter-spacing: 0.5px 81 | order: 2 82 | 83 | &-titled 84 | border-radius: 6px 20px 20px 20px 85 | 86 | &::placeholder 87 | color: #bbbbbb 88 | 89 | &-readOnly 90 | background: #f1f1f1 91 | 92 | &-disabled 93 | cursor: default 94 | 95 | &-red 96 | background: #ffd3d5 97 | -------------------------------------------------------------------------------- /src/components/elements/InputNumberControl/InputNumberControl.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | 3 | import InputControl from "components/elements/InputControl/InputControl"; 4 | 5 | 6 | export default class InputNumberControl extends Component { 7 | state = { 8 | value: this.props.value, 9 | valueParsed: InputNumberControl.parseValue(this.props.value, this.props) 10 | }; 11 | 12 | 13 | static getDerivedStateFromProps(props, state) { 14 | const valueParsed = InputNumberControl.parseValue(props.value, props); 15 | if (valueParsed === state.valueParsed) 16 | return null; 17 | return {value: valueParsed, valueParsed}; 18 | } 19 | 20 | static parseValue(value, props) { 21 | const {min, max, isInt} = props; 22 | 23 | const parseFunc = isInt ? parseInt : parseFloat; 24 | let num = parseFunc(value); 25 | if (isNaN(num)) 26 | return undefined; 27 | 28 | if (min !== undefined && min !== null && num < min) 29 | num = min; 30 | if (max !== undefined && max !== null && num > max) 31 | num = max; 32 | 33 | return num; 34 | } 35 | 36 | onChange = value => { 37 | value = value.replace(/[^\d.,]/g, ''); 38 | value = value.replace(/,/g, '.'); 39 | this.setState({value}); 40 | 41 | const valueParsed = InputNumberControl.parseValue(value, this.props); 42 | if (valueParsed === this.state.valueParsed) 43 | return; 44 | this.setState({valueParsed}); 45 | 46 | this.props.onChange(valueParsed); 47 | }; 48 | 49 | onBlur = () => { 50 | this.setState({value: this.state.valueParsed}); 51 | }; 52 | 53 | render() { 54 | let {type, label, placeholder, readOnly, autoFocus, onKeyDown, DOMRef, icon, titled} = this.props; 55 | 56 | return ; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/components/elements/JSONView/JSONView.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import styles from './JSONView.sss'; 4 | 5 | 6 | export default props => ( 7 |
 8 |     {JSON.stringify(props.model, null, 2)}
 9 |   
10 | ); 11 | -------------------------------------------------------------------------------- /src/components/elements/JSONView/JSONView.sss: -------------------------------------------------------------------------------- 1 | .json-wrapper 2 | width: 100% 3 | padding-left: 30px 4 | text-align: left 5 | font-size: 13px 6 | color: #5a5a5a 7 | -------------------------------------------------------------------------------- /src/components/elements/LoaderComponent/LoaderComponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import styles from './LoaderComponent.sss'; 4 | 5 | 6 | export default () => ( 7 |
8 |
9 |
10 | ); 11 | -------------------------------------------------------------------------------- /src/components/elements/LoaderComponent/LoaderComponent.sss: -------------------------------------------------------------------------------- 1 | .loader 2 | display: inline-block 3 | width: 30px 4 | height: 30px 5 | border: 4px solid #666666 6 | animation: loader 2s infinite ease 7 | 8 | .loader-inner 9 | vertical-align: top 10 | display: inline-block 11 | width: 100% 12 | background-color: #666666 13 | animation: loader-inner 2s infinite ease-in 14 | 15 | 16 | @keyframes loader 17 | 0% 18 | transform: rotate(0deg) 19 | 25% 20 | transform: rotate(180deg) 21 | 50% 22 | transform: rotate(180deg) 23 | 75% 24 | transform: rotate(360deg) 25 | 100% 26 | transform: rotate(360deg) 27 | 28 | 29 | @keyframes loader-inner 30 | 0% 31 | height: 0% 32 | 25% 33 | height: 0% 34 | 50% 35 | height: 100% 36 | 75% 37 | height: 100% 38 | 100% 39 | height: 0% 40 | -------------------------------------------------------------------------------- /src/components/elements/MarkdownEditor/MarkdownEditor.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import CSSModules from 'react-css-modules'; 3 | import MdEditor, { Plugins } from 'react-markdown-editor-lite'; 4 | import 'react-markdown-editor-lite/lib/index.css'; 5 | import MarkdownIt from 'markdown-it'; 6 | 7 | import styles from './MarkdownEditor.sss'; 8 | 9 | 10 | 11 | @CSSModules(styles, {allowMultiple: true}) 12 | export default class MarkdownEditor extends Component { 13 | mdParser = new MarkdownIt(); 14 | 15 | constructor(props) { 16 | super(); 17 | 18 | MdEditor.use(Plugins.TabInsert, { 19 | tabMapValue: 2, 20 | }); 21 | 22 | if (props.fullHeight) 23 | MdEditor.unuse(Plugins.AutoResize); 24 | else 25 | MdEditor.use(Plugins.AutoResize, { 26 | min: 200, 27 | max: 400 28 | }); 29 | } 30 | 31 | renderHTML = text => { 32 | return this.mdParser.render(text); 33 | }; 34 | 35 | onChange = ({html, text}) => { 36 | const {onChange} = this.props; 37 | onChange(text); 38 | }; 39 | 40 | onImageUpload = (file) => { 41 | if (file.size > 50000) 42 | return new Promise(resolve => { 43 | setTimeout(() => resolve('THE FILE IS TOO LARGE!'), 10); 44 | }); 45 | 46 | return new Promise(resolve => { 47 | const reader = new FileReader(); 48 | reader.onload = data => { 49 | resolve(data.target.result); 50 | }; 51 | reader.readAsDataURL(file); 52 | }); 53 | }; 54 | 55 | render () { 56 | const {readOnly, value, fullHeight} = this.props; 57 | 58 | const style = {}; 59 | if (fullHeight) 60 | style.height = '100%'; 61 | 62 | const config = { 63 | view: { menu: true, md: true, html: !!fullHeight }, 64 | canView: {fullScreen: false} 65 | }; 66 | 67 | return ( 68 | 77 | ); 78 | } 79 | } -------------------------------------------------------------------------------- /src/components/elements/MarkdownEditor/MarkdownEditor.sss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/components/elements/MarkdownEditor/MarkdownEditor.sss -------------------------------------------------------------------------------- /src/components/elements/MediaView/MediaView.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import InlineSVG from 'svg-inline-react'; 3 | import CSSModules from 'react-css-modules'; 4 | 5 | import { 6 | checkFileType, TYPE_AUDIO, TYPE_IMAGE, TYPE_PDF, TYPE_TEXT, TYPE_F_TEXT, TYPE_VIDEO, TYPE_HTML, TYPE_PRESENT, 7 | TYPE_TABLE, TYPE_JSON, TYPE_XML, TYPE_MARKDOWN, TYPE_ARCHIVE, TYPE_EXE 8 | } from "utils/common"; 9 | 10 | import styles from './MediaView.sss'; 11 | 12 | 13 | @CSSModules(styles, {allowMultiple: true}) 14 | export default class MediaView extends Component { 15 | getIconName (type) { 16 | switch (checkFileType(type)) { 17 | case TYPE_TEXT: return 'txt'; 18 | case TYPE_HTML: return 'html'; 19 | case TYPE_XML: return 'xml'; 20 | case TYPE_MARKDOWN: return 'md'; 21 | case TYPE_JSON: return 'json'; 22 | case TYPE_PDF: return 'pdf'; 23 | case TYPE_F_TEXT: return 'doc'; 24 | case TYPE_TABLE: return 'xls'; 25 | case TYPE_PRESENT: return 'ppt'; 26 | case TYPE_ARCHIVE: return 'archive'; 27 | case TYPE_EXE: return 'exe'; 28 | } 29 | return 'other'; 30 | } 31 | 32 | getIcon (item) { 33 | const iconName = this.getIconName(item.type); 34 | return ( 35 | 38 | 40 | 41 | ); 42 | } 43 | 44 | render() { 45 | const {item} = this.props; 46 | 47 | if (!item || !item.file) 48 | return null; 49 | 50 | switch (checkFileType(item.type)) { 51 | case TYPE_IMAGE: 52 | return ( 53 | 55 |
57 |
58 |
59 | ); 60 | 61 | case TYPE_AUDIO: 62 | return ( 63 | 68 | ); 69 | 70 | case TYPE_VIDEO: 71 | return ( 72 | 77 | ); 78 | 79 | default: 80 | return this.getIcon(item); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/components/elements/MediaView/MediaView.sss: -------------------------------------------------------------------------------- 1 | .link 2 | display: flex 3 | justify-content: center 4 | 5 | .icon 6 | margin: 20px 7 | 8 | svg 9 | height: 70px 10 | 11 | .image 12 | height: 108px 13 | background: no-repeat center center / cover 14 | 15 | .audio 16 | width: 100% 17 | 18 | .video 19 | height: 200px 20 | width: 100% -------------------------------------------------------------------------------- /src/components/elements/RadioControl/RadioControl.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import CSSModules from 'react-css-modules'; 3 | 4 | import {getUniqueId} from 'utils/common'; 5 | 6 | import styles from './RadioControl.sss'; 7 | 8 | 9 | @CSSModules(styles, {allowMultiple: true}) 10 | export default class DropdownControl extends Component { 11 | id = getUniqueId(); 12 | 13 | onChange = e => { 14 | const {onChange, disabled, data} = this.props; 15 | if (onChange && !disabled && e.target.checked) 16 | onChange(data); 17 | }; 18 | 19 | render() { 20 | const {data, name, label, disabled, value} = this.props; 21 | let style = `RadioControl`; 22 | if (disabled) 23 | style += ` disabled`; 24 | 25 | return ( 26 |
27 | 34 | 35 |
36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/components/elements/RadioControl/RadioControl.sss: -------------------------------------------------------------------------------- 1 | .RadioControl 2 | margin-right: 26px 3 | 4 | .input 5 | display: none 6 | 7 | .label 8 | cursor: pointer 9 | position: relative 10 | padding-left: 30px 11 | 12 | font-weight: 600 13 | font-size: 13px 14 | color: #999999 15 | letter-spacing: 0.5px 16 | 17 | .label:before 18 | content: '' 19 | position: absolute 20 | left: 0 21 | top: 50% 22 | transform: translateY(-50%) 23 | height: 20px 24 | width: 20px 25 | border-radius: 50% 26 | background: #fff 27 | border: 1px solid #979797 28 | 29 | .input:checked + .label:before 30 | height: 12px 31 | width: 12px 32 | border: 5px solid #8a5ebe 33 | 34 | .input + .label:before, 35 | .input:checked + .label:before 36 | transition: background 0.1s ease 37 | 38 | 39 | .disabled 40 | .label 41 | color: #bbbbbb 42 | 43 | .input:not(checked) + .label:before 44 | border: 1px solid #bbbbbb 45 | 46 | .input:checked + .label:before 47 | border: 5px solid #bbbbbb 48 | 49 | -------------------------------------------------------------------------------- /src/components/elements/SwitchControl/SwitchControl.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import CSSModules from 'react-css-modules'; 3 | 4 | import {getUniqueId} from 'utils/common'; 5 | 6 | import styles from './SwitchControl.sss'; 7 | 8 | 9 | @CSSModules(styles, {allowMultiple: true}) 10 | export default class SwitchControl extends Component { 11 | id = getUniqueId(); 12 | 13 | onChange = e => { 14 | const {onChange, disabled} = this.props; 15 | if (onChange && !disabled) 16 | onChange(e.target.checked); 17 | }; 18 | 19 | render() { 20 | const {label, disabled, checked} = this.props; 21 | let style = `SwitchControl`; 22 | if (checked === undefined) 23 | style += ` undefined`; 24 | if (disabled) 25 | style += ` disabled`; 26 | 27 | return ( 28 |
29 | 36 | 37 |
38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/components/elements/SwitchControl/SwitchControl.sss: -------------------------------------------------------------------------------- 1 | .SwitchControl 2 | 3 | .checkbox 4 | vertical-align: top 5 | margin: 0 3px 0 0 6 | 7 | .label 8 | font-size: 14px 9 | color: #2C2C30 10 | letter-spacing: 0.5px 11 | user-select: none 12 | 13 | 14 | .checkbox + .label 15 | cursor: pointer 16 | 17 | .checkbox:not(checked) 18 | position: absolute 19 | opacity: 0 20 | 21 | .checkbox:not(checked) + .label 22 | position: relative 23 | padding: 0 0 0 72px 24 | 25 | .checkbox:not(checked) + .label:before 26 | content: '' 27 | position: absolute 28 | top: -5px 29 | left: 0px 30 | width: 50px 31 | height: 24px 32 | background: #CCCCCC 33 | box-shadow: inset 0 10px 20px 0 rgba(0,0,0,0.10) 34 | border-radius: 25px 35 | transition: all .2s 36 | 37 | .checkbox:not(checked) + .label:after 38 | content: '' 39 | position: absolute 40 | top: -4px 41 | left: 1px 42 | width: 22px 43 | height: 22px 44 | border-radius: 100% 45 | background: #FFF 46 | box-shadow: 0px 0px 4px 0px rgba(0,0,0,0.50) 47 | transition: all .2s 48 | 49 | .checkbox:checked + .label:before 50 | background-image: linear-gradient(-180deg, #8a5ebe 0%, #7b50b2 100%) 51 | transition: background-image .2s 52 | 53 | .checkbox:checked + .label:after 54 | left: 27px 55 | 56 | .undefined 57 | .checkbox:not(checked) + .label:after 58 | left: 15px 59 | 60 | .disabled 61 | .label 62 | color: #b1b1b1 63 | 64 | .checkbox:not(checked) + .label:before 65 | background: #e6e6e6 66 | box-shadow: inset 0 10px 20px 0 rgba(0, 0, 0, 0.01) 67 | 68 | .checkbox:not(checked) + .label:after 69 | box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.26) 70 | 71 | .checkbox:checked + .label:before 72 | background-image: linear-gradient(-180deg, #ddc0ff 0%, #cba3ff 100%) 73 | -------------------------------------------------------------------------------- /src/components/header/Menu/Menu.sss: -------------------------------------------------------------------------------- 1 | .menu 2 | flex: 1 3 | display: flex 4 | justify-content: center 5 | position: relative 6 | 7 | .button 8 | font-size: 14px 9 | color: #A4A4AE 10 | letter-spacing: 0.5px 11 | cursor: pointer 12 | user-select: none 13 | min-height: 72px 14 | padding: 0 30px 15 | display: flex 16 | align-items: center 17 | transition: color .2s ease 18 | 19 | &:hover 20 | color: #212121 21 | 22 | &-disabled 23 | color: #A4A4AE !important 24 | cursor: auto 25 | pointer-events: none 26 | 27 | .activeItem 28 | color: #212121 29 | 30 | .caret 31 | position: absolute 32 | bottom: 0 33 | left: 0 34 | height: 2px 35 | background: #212121 36 | transition: transform .2s ease, width .2s ease, opacity .2s ease 37 | will-change: width -------------------------------------------------------------------------------- /src/components/mainArea/common/NoRights.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import InlineSVG from 'svg-inline-react'; 3 | 4 | import ImageHammer from 'assets/images/hammer.svg'; 5 | 6 | 7 | export default () => ( 8 |
9 | 10 | You don't have rights to access this section. 11 |
12 | ); -------------------------------------------------------------------------------- /src/components/mainArea/common/Notification/Notification.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import CSSModules from 'react-css-modules'; 3 | 4 | import styles from './Notification.sss'; 5 | 6 | 7 | @CSSModules(styles, {allowMultiple: true}) 8 | export default class Notification extends Component { 9 | onConfirm = () => { 10 | const {onConfirm} = this.props.notification; 11 | if (onConfirm) 12 | onConfirm(); 13 | this.props.closeNotification(); 14 | }; 15 | 16 | onCancel = () => { 17 | const {onCancel} = this.props.notification; 18 | if (onCancel) 19 | onCancel(); 20 | this.props.closeNotification(); 21 | }; 22 | 23 | render() { 24 | const {notification} = this.props; 25 | const {text, confirmLabel, cancelLabel} = notification; 26 | 27 | return ( 28 |
29 |
{text}
30 | {confirmLabel && 31 | 32 | } 33 | 34 |
35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/components/mainArea/common/Notification/Notification.sss: -------------------------------------------------------------------------------- 1 | .Notification 2 | width: calc(100% - 20px) 3 | display: flex 4 | justify-content: center 5 | background: white 6 | border: 1px solid rgba(0,0,0,0.1) 7 | border-radius: 10px 8 | box-shadow: inset 0 1px 5px 0 rgba(0,0,0,0.05) 9 | padding-top: 15px 10 | padding-bottom: 15px 11 | font-size: 14px 12 | color: #2C2C30 13 | margin: 0 10px 10px 10px 14 | 15 | .button 16 | margin-left: 20px 17 | border: none !important 18 | background: none 19 | font-size: 14px 20 | padding: 0 21 | cursor: pointer 22 | color: #875BBC 23 | -------------------------------------------------------------------------------- /src/components/mainArea/content/ContentEdit/elements/ContentBase.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import CSSModules from 'react-css-modules'; 3 | 4 | import {checkUniqueFieldValue} from 'utils/data'; 5 | 6 | import styles from '../ContentEdit.sss'; 7 | 8 | 9 | @CSSModules(styles, {allowMultiple: true}) 10 | export default class ContentBase extends Component { 11 | state = { 12 | item: this.props.item, 13 | field: this.props.field, 14 | value: this.props.value, 15 | error: null 16 | }; 17 | 18 | 19 | static getDerivedStateFromProps(props, state) { 20 | //if (props.field != state.field || props.item != state.item) 21 | return { 22 | item: props.item, 23 | field: props.field, 24 | value: props.value 25 | }; 26 | return null; 27 | } 28 | 29 | setValue = (value, save) => { 30 | this.setState({ 31 | value, 32 | error: null 33 | }); 34 | this.props.setFieldValue(this.state.field, value, save); 35 | }; 36 | 37 | getError() { 38 | if (this.state.field.isRequired && this.state.value === undefined) 39 | return 'This field is required!'; 40 | 41 | if (this.state.field.isUnique) { 42 | const item = checkUniqueFieldValue(this.state.field, this.props.item); 43 | if (item) { 44 | if (item.title) 45 | return `This field value must be unique! The "${item.title}" item has same value.`; 46 | else 47 | return `This field value must be unique! There is an untitled item with same value.`; 48 | } 49 | } 50 | 51 | return null; 52 | } 53 | 54 | validate () { 55 | let error = this.getError(); 56 | this.setState({error}); 57 | return !error; 58 | } 59 | 60 | getTitle() { 61 | return ( 62 |
63 | {this.state.field.name} 64 |
65 | ); 66 | } 67 | 68 | //must be overriden 69 | getInput() { 70 | return null; 71 | } 72 | 73 | render() { 74 | return ( 75 |
76 | {this.getTitle()} 77 | {this.getInput()} 78 |
79 | {this.state.error} 80 |
81 |
82 | ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/components/mainArea/content/ContentEdit/elements/ContentBoolean.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import CSSModules from 'react-css-modules'; 3 | 4 | import ContentBase from './ContentBase'; 5 | import SwitchControl from 'components/elements/SwitchControl/SwitchControl'; 6 | import RadioControl from 'components/elements/RadioControl/RadioControl'; 7 | 8 | import * as ftps from 'models/ModelData'; 9 | 10 | import styles from '../ContentEdit.sss'; 11 | 12 | 13 | @CSSModules(styles, {allowMultiple: true}) 14 | export default class ContentBoolean extends ContentBase { 15 | getInput() { 16 | const {isEditable} = this.props; 17 | const {value, field} = this.state; 18 | 19 | switch (field.appearance) { 20 | case ftps.FIELD_APPEARANCE__BOOLEAN__RADIO: 21 | const textYes = field.boolTextYes ? field.boolTextYes : 'Yes'; 22 | const textNo = field.boolTextNo ? field.boolTextNo : 'No'; 23 | 24 | return ( 25 |
26 | 32 | 38 | {isEditable && 39 |
this.setValue(undefined)}> 41 | Reset 42 |
43 | } 44 |
45 | ); 46 | 47 | case ftps.FIELD_APPEARANCE__BOOLEAN__SWITCH: 48 | return ( 49 |
50 |
51 | 54 |
55 | {isEditable && 56 |
this.setValue(undefined)}> 58 | Reset 59 |
60 | } 61 |
62 | ); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/components/mainArea/content/ContentList/eye-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/components/mainArea/content/ContentList/eye-gray.png -------------------------------------------------------------------------------- /src/components/mainArea/content/ContentList/eye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/components/mainArea/content/ContentList/eye.png -------------------------------------------------------------------------------- /src/components/mainArea/models/Model/Model.sss: -------------------------------------------------------------------------------- 1 | .input-wrapper 2 | margin-top: 20px 3 | user-select: none 4 | 5 | .input-title 6 | font-size: 14px 7 | color: #2C2C30 8 | line-height: 30px 9 | text-align: left 10 | 11 | .list 12 | display: flex 13 | flex-flow: column nowrap 14 | margin: 0 auto 15 | overflow: hidden 16 | width: 100% 17 | 18 | background: #FFFFFF 19 | box-shadow: 0 1px 0 0 rgba(0,0,0,0.05), 0 1px 10px 0 rgba(0,0,0,0.05) 20 | border-radius: 6px 20px 20px 20px 21 | 22 | user-select: none 23 | 24 | &Item 25 | display: flex 26 | flex-flow: row nowrap 27 | align-items: center 28 | position: relative 29 | cursor: pointer 30 | padding-left: 16px 31 | padding-right: 16px 32 | width: 100% 33 | 34 | &:nth-child(2n) 35 | background: #FCFCFC 36 | 37 | &:hover 38 | .controlIcon 39 | opacity: 1 40 | 41 | &Pointer 42 | cursor: pointer 43 | 44 | &Disabled &Name, 45 | &Disabled &Type, 46 | &Disabled &Color 47 | opacity: 0.5 48 | 49 | &Name, 50 | &Type 51 | padding-top: 16px 52 | padding-bottom: 16px 53 | font-size: 15px 54 | 55 | color: #2C2C30 56 | letter-spacing: 0.5px 57 | text-align: left 58 | 59 | &Name 60 | flex-grow: 1 61 | flex-shrink: 0.6 62 | width: 100% 63 | 64 | &Type 65 | flex-shrink: 0.8 66 | flex-grow: 1 67 | width: 100% 68 | 69 | &Color 70 | margin-right: 10px 71 | height: 20px 72 | width: 20px 73 | min-width: 20px 74 | border-radius: 100% 75 | background: #DCC191 76 | 77 | .head 78 | font-size: 18px 79 | font-weight: 600 80 | font-family: 'Inter-UI', sans-serif 81 | border-bottom: 1px solid #e8e8e8 82 | 83 | div 84 | font-size: 18px 85 | 86 | .listItemType 87 | margin-right: 138px 88 | 89 | .listItemColor 90 | visibility: hidden 91 | 92 | 93 | .listButtons 94 | width: 100px 95 | flex-shrink: 0 96 | 97 | .titleButton, 98 | .requiredButton 99 | margin-right: 10% 100 | 101 | background: #E5E5E5 102 | font-size: 11px 103 | color: #6A6A6A 104 | text-align: center 105 | 106 | box-shadow: 0px 1px 2px 0px rgba(0,0,0,0.20) 107 | border-radius: 20px 108 | letter-spacing: 0.42px 109 | line-height: 24px 110 | padding: 0 15px 111 | text-transform: uppercase 112 | 113 | .controls 114 | display: flex 115 | flex-flow: row nowrap 116 | align-items: center 117 | 118 | .controlIcon 119 | position: relative 120 | z-index: 10 121 | margin-left: 20px 122 | height: 18px 123 | width: 18px 124 | opacity: 0 125 | transition: opacity .2s ease 126 | 127 | 128 | .cross 129 | cursor: pointer 130 | 131 | .edit 132 | cursor: pointer 133 | 134 | .back-link 135 | cursor: pointer 136 | &:hover 137 | border-bottom: 2px solid #2C2C30 138 | 139 | .model-title 140 | user-select: text 141 | -------------------------------------------------------------------------------- /src/components/mainArea/settings/Settings.sss: -------------------------------------------------------------------------------- 1 | .content 2 | display: flex 3 | flex-flow: column nowrap 4 | align-items: flex-start 5 | 6 | width: 100% 7 | 8 | .field 9 | margin-top: 20px 10 | width: 100% 11 | text-align: left 12 | 13 | display: flex 14 | flex-flow: column nowrap 15 | 16 | transition: color 0.2s ease 17 | will-change: color 18 | 19 | &-title, 20 | &-error 21 | font-size: 14px 22 | color: #2C2C30 23 | letter-spacing: 0.5px 24 | line-height: 30px 25 | position: relative 26 | 27 | transition: color 0.2s ease 28 | will-change: color 29 | 30 | &-error 31 | color: #DD5555 32 | 33 | 34 | .input 35 | background: #FFFFFF 36 | border: 1px solid #CCCCCC 37 | box-shadow: inset 0px 1px 2px 0px rgba(0,0,0,0.10) 38 | border-radius: 2px 39 | line-height: 34px 40 | padding: 0 9px 41 | margin-top: 10px 42 | outline: none 43 | 44 | &:first-child 45 | margin-top: 0px 46 | 47 | &-wrapper 48 | display: flex 49 | flex-flow: column nowrap 50 | user-select: none 51 | 52 | .button-wrapper 53 | display: flex 54 | flex-flow: row nowrap 55 | 56 | .buttons 57 | display: flex 58 | flex-flow: row nowrap 59 | margin-top: 30px 60 | width: 100% 61 | 62 | .field 63 | width: auto 64 | 65 | .button-export 66 | margin-left: auto 67 | margin-right: 20px 68 | 69 | .icon-img__wrapper 70 | width: 50px 71 | height: 50px 72 | margin-right: 10px 73 | 74 | background: #D8D8D8 75 | border-radius: 50% 76 | overflow: hidden 77 | 78 | .icon 79 | &-img 80 | height: 50px 81 | background: no-repeat center center / cover 82 | 83 | &-button 84 | background: rgba(255,255,255,0.80) 85 | box-shadow: 0 2px 4px 0 rgba(0,0,0,0.10) 86 | border-radius: 20px 87 | border: 1px solid #DDDDDD 88 | 89 | font-size: 14px 90 | font-family: 'Inter-UI', sans-serif 91 | font-weight: 500 92 | color: #313133 93 | text-align: center 94 | line-height: 24px 95 | letter-spacing: 0.54px 96 | 97 | cursor: pointer 98 | 99 | &-disabled 100 | cursor: auto 101 | color: #b2b2b2 102 | 103 | &:hover 104 | border-color: #DDDDDD 105 | 106 | &-upload 107 | display: flex 108 | flex-flow: row nowrap 109 | justify-content: center 110 | align-items: center 111 | 112 | padding: 0 15px 113 | height: 40px 114 | margin-right: 20px 115 | position: relative 116 | 117 | &-hidden 118 | width: 100% 119 | height: 100% 120 | opacity: 0 121 | position: absolute 122 | left: 0 123 | top: 0 124 | cursor: pointer 125 | 126 | .field-icon 127 | display: flex 128 | flex-flow: row wrap 129 | align-items: center 130 | 131 | .field-title 132 | flex: 1 1 100% 133 | 134 | .button-wrapper 135 | display: flex 136 | align-items: center 137 | -------------------------------------------------------------------------------- /src/components/mainArea/sharing/github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-Github 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/components/modals/AlertModal/AlertModal.sss: -------------------------------------------------------------------------------- 1 | .Modal 2 | position: absolute 3 | height: 100% 4 | width: 100% 5 | top: 0 6 | left: 0 7 | overflow-y: scroll 8 | 9 | z-index: 80 10 | 11 | background: rgba(0, 0, 0, 0.5) 12 | 13 | .modal-inner 14 | position: absolute 15 | left: 50% 16 | transform: translateX(-50%) 17 | margin: 70px 0 18 | background: #F9F9F9 19 | box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.10) 20 | border-radius: 5px 21 | width: 70% 22 | display: flex 23 | flex-flow: column nowrap 24 | align-items: center 25 | 26 | .modal-header 27 | border-bottom: 1px solid #E5E5E5 28 | 29 | width: 100% 30 | line-height: 55px 31 | 32 | display: flex 33 | flex-flow: column nowrap 34 | justify-content: center 35 | align-items: center 36 | 37 | .content 38 | flex: 0 0 30% 39 | padding: 32px 0 40 | 41 | display: flex 42 | flex-flow: column nowrap 43 | justify-content: space-around 44 | align-items: center 45 | 46 | .title 47 | font-size: 20px 48 | color: #666666 49 | letter-spacing: 0.83px 50 | user-select: none 51 | 52 | .description 53 | font-size: 13px 54 | color: #666666 55 | letter-spacing: 0.5px 56 | text-align: center 57 | user-select: none 58 | 59 | .button 60 | margin-top: 30px 61 | 62 | .buttons-wrapper 63 | display: flex 64 | flex-flow: row nowrap 65 | margin-top: 30px 66 | justify-content: center 67 | 68 | .buttons-inner:first-child 69 | margin-right: 25px 70 | 71 | .input-wrapper 72 | width: 50% 73 | margin-top: 30px 74 | -------------------------------------------------------------------------------- /src/components/modals/CollabRoleModal/CollabRoleModal.sss: -------------------------------------------------------------------------------- 1 | .modal 2 | position: absolute 3 | height: 100% 4 | width: 100% 5 | top: 0 6 | left: 0 7 | 8 | z-index: 80 9 | 10 | overflow-y: scroll 11 | 12 | background: rgba(0, 0, 0, 0.5) 13 | 14 | user-select: none 15 | 16 | &-header 17 | border-bottom: 1px solid #E5E5E5 18 | 19 | padding: 4px 0 20 | width: 100% 21 | 22 | display: flex 23 | flex-flow: column nowrap 24 | justify-content: center 25 | align-items: center 26 | 27 | .title 28 | font-size: 20px 29 | color: #666666 30 | letter-spacing: 0.83px 31 | margin-top: 15px 32 | margin-bottom: 15px 33 | 34 | &-inner 35 | position: absolute 36 | left: 50% 37 | transform: translateX(-50%) 38 | background: #F9F9F9 39 | box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.10) 40 | border-radius: 5px 41 | 42 | margin: 30px 0 43 | 44 | width: 70% 45 | display: flex 46 | flex-flow: column nowrap 47 | align-items: center 48 | 49 | .content 50 | width: 100% 51 | padding: 32px 10% 52 | 53 | .buttons-wrapper 54 | margin-bottom: 25px 55 | display: flex 56 | flex-flow: row nowrap 57 | margin-top: 70px 58 | justify-content: center 59 | 60 | .buttons-inner:first-child 61 | margin-right: 25px 62 | 63 | .label 64 | letter-spacing: 0.5px 65 | line-height: 30px 66 | font-size: 14px 67 | color: #2C2C30 68 | padding-bottom: 6px 69 | padding-left: 2px 70 | cursor: default 71 | 72 | 73 | 74 | .RoleControl 75 | cursor: pointer 76 | margin-bottom: 5px 77 | 78 | .role-content 79 | border: 2px solid rgba(0, 0, 0, 0) 80 | border-radius: 5px 81 | padding: 15px 82 | 83 | .title 84 | font-size: 18px 85 | font-weight: 600 86 | color: #666666 87 | margin-bottom: 10px 88 | 89 | .description 90 | font-size: 13px 91 | color: #999999 92 | 93 | .checked 94 | border-color: #6D9EE1 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/components/modals/MarkdownModal/MarkdownModal.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import CSSModules from 'react-css-modules'; 3 | import InlineSVG from 'svg-inline-react'; 4 | 5 | import MarkdownEditor from 'components/elements/MarkdownEditor/MarkdownEditor'; 6 | 7 | import styles from './MarkdownModal.sss'; 8 | 9 | import ImageCrossCircle from 'assets/images/cross-circle.svg'; 10 | 11 | 12 | @CSSModules(styles, {allowMultiple: true}) 13 | export default class MarkdownModal extends Component { 14 | state = { 15 | text: this.props.params.text 16 | }; 17 | 18 | 19 | onClosing = () => { 20 | this.props.params.callback(this.state.text); 21 | this.props.onClose(); 22 | }; 23 | 24 | onChange = text => { 25 | this.setState({text}); 26 | }; 27 | 28 | render() { 29 | const {readOnly} = this.props.params; 30 | 31 | return ( 32 |
33 |
34 | 36 |
37 | 41 |
42 | ); 43 | } 44 | } -------------------------------------------------------------------------------- /src/components/modals/MarkdownModal/MarkdownModal.sss: -------------------------------------------------------------------------------- 1 | .wrapper 2 | position: absolute 3 | top: 0 4 | left: 0 5 | width: 100% 6 | height: 100% 7 | background: white 8 | z-index: 80 9 | padding: 50px 10 | 11 | .return 12 | position: absolute 13 | top: 10px 14 | left: 10px 15 | height: 24px 16 | width: 24px 17 | 18 | .cross 19 | height: 24px 20 | width: 24px 21 | opacity: .6 22 | cursor: pointer 23 | 24 | &:hover 25 | opacity: 1 26 | -------------------------------------------------------------------------------- /src/components/modals/MediaModal/MediaModal.sss: -------------------------------------------------------------------------------- 1 | .modal 2 | position: absolute 3 | height: 100% 4 | width: 100% 5 | top: 0 6 | left: 0 7 | 8 | z-index: 80 9 | 10 | overflow-y: scroll 11 | 12 | background: rgba(0, 0, 0, 0.5) 13 | 14 | &-inner 15 | position: absolute 16 | left: 50% 17 | transform: translateX(-50%) 18 | background: #F9F9F9 19 | box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.10) 20 | border-radius: 5px 21 | 22 | margin: 30px 0 23 | 24 | width: 70% 25 | display: flex 26 | flex-flow: column nowrap 27 | align-items: center 28 | 29 | .content 30 | width: 100% 31 | padding: 32px 6% 32 | 33 | .input-wrapper 34 | width: 100% 35 | margin-bottom: 30px 36 | 37 | .buttons-wrapper 38 | display: flex 39 | flex-flow: row nowrap 40 | width: 100% 41 | margin-top: 30px 42 | justify-content: center 43 | 44 | .buttons-inner:first-child 45 | margin-right: 10px 46 | 47 | .error-same-name 48 | color: red 49 | 50 | 51 | .media 52 | display: flex 53 | flex-flow: row wrap 54 | align-items: flex-start 55 | justify-content: space-between 56 | 57 | overflow-y: auto 58 | min-height: 190px 59 | 60 | &-item 61 | position: relative 62 | overflow: hidden 63 | 64 | display: flex 65 | flex-flow: column nowrap 66 | flex-shrink: 0 67 | width: 200px 68 | 69 | cursor: pointer 70 | margin-right: 25px 71 | margin-bottom: 25px 72 | 73 | background: rgba(255,255,255,0.80) 74 | border: 2px solid #DDDDDD 75 | box-shadow: 0 2px 4px 0 rgba(0,0,0,0.10) 76 | border-radius: 10px 77 | 78 | transition: border-color 0.2s ease 79 | will-change: border-color 80 | 81 | &:last-child 82 | margin-right: 0 83 | 84 | &:hover 85 | border-color: #6D9EE1 86 | 87 | &.media-chosen 88 | border-color: #6D9EE1 89 | 90 | &:after 91 | content: '' 92 | background: url('assets/images/okay.png') no-repeat center center / contain 93 | height: 18px 94 | width: 18px 95 | 96 | position: absolute 97 | top: 8px 98 | right: 8px 99 | 100 | &-header 101 | font-size: 15px 102 | color: #313133 103 | text-align: center 104 | //background-color: #F5F5F5 105 | 106 | padding: 10px 107 | -------------------------------------------------------------------------------- /src/components/modals/ModelChooseModal/ModelChooseModal.sss: -------------------------------------------------------------------------------- 1 | .modal 2 | position: absolute 3 | height: 100% 4 | width: 100% 5 | top: 0 6 | left: 0 7 | 8 | z-index: 80 9 | 10 | overflow-y: scroll 11 | 12 | background: rgba(0, 0, 0, 0.5) 13 | 14 | &-header 15 | border-bottom: 1px solid #E5E5E5 16 | 17 | padding: 4px 0 18 | width: 100% 19 | 20 | display: flex 21 | flex-flow: column nowrap 22 | justify-content: center 23 | align-items: center 24 | user-select: none 25 | 26 | .title 27 | font-size: 20px 28 | color: #666666 29 | letter-spacing: 0.83px 30 | margin-top: 15px 31 | margin-bottom: 15px 32 | 33 | &-inner 34 | position: absolute 35 | left: 50% 36 | transform: translateX(-50%) 37 | background: #F9F9F9 38 | box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.10) 39 | border-radius: 5px 40 | 41 | margin: 30px 0 42 | 43 | width: 70% 44 | display: flex 45 | flex-flow: column nowrap 46 | align-items: center 47 | 48 | .content 49 | width: 100% 50 | padding: 32px 10% 51 | user-select: none 52 | 53 | 54 | .input-wrapper 55 | width: 100% 56 | margin-bottom: 30px 57 | 58 | .buttons-wrapper 59 | display: flex 60 | flex-flow: row nowrap 61 | margin-top: 80px 62 | justify-content: center 63 | 64 | .buttons-inner:first-child 65 | margin-right: 25px 66 | 67 | .error-same-name 68 | color: red 69 | 70 | 71 | .model 72 | display: flex 73 | flex-flow: column nowrap 74 | 75 | &-item 76 | position: relative 77 | padding: 11px 38px 78 | margin-top: 10px 79 | font-size: 24px 80 | color: #666666 81 | letter-spacing: 0.54px 82 | cursor: pointer 83 | 84 | background: rgba(255,255,255,0.80) 85 | border: 2px solid #DDDDDD 86 | box-shadow: 0 2px 4px 0 rgba(0,0,0,0.10) 87 | border-radius: 10px 88 | 89 | transition: border-color 0.2s ease 90 | will-change: border-color 91 | 92 | &:first-child 93 | margin-top: 0 94 | 95 | &:hover 96 | border-color: #6D9EE1 97 | 98 | &.model-chosen 99 | border-color: #6D9EE1 100 | 101 | &:after 102 | content: '' 103 | background: url('assets/images/okay.png') no-repeat center center / contain 104 | height: 30px 105 | width: 30px 106 | 107 | position: absolute 108 | top: 10px 109 | right: 10px 110 | -------------------------------------------------------------------------------- /src/components/modals/ReferenceModal/ReferenceModal.sss: -------------------------------------------------------------------------------- 1 | .modal 2 | position: absolute 3 | height: 100% 4 | width: 100% 5 | top: 0 6 | left: 0 7 | 8 | z-index: 80 9 | 10 | overflow-y: scroll 11 | 12 | background: rgba(0, 0, 0, 0.5) 13 | 14 | &-inner 15 | position: absolute 16 | left: 50% 17 | transform: translateX(-50%) 18 | background: #F9F9F9 19 | box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.10) 20 | border-radius: 5px 21 | 22 | margin: 30px 0 23 | 24 | width: 70% 25 | display: flex 26 | flex-flow: column nowrap 27 | align-items: center 28 | 29 | .content 30 | width: 100% 31 | padding: 32px 10% 32 | 33 | .input-wrapper 34 | width: 100% 35 | margin-bottom: 30px 36 | 37 | .buttons-wrapper 38 | display: flex 39 | flex-flow: row nowrap 40 | margin-top: 80px 41 | justify-content: center 42 | 43 | .buttons-inner:first-child 44 | margin-right: 25px 45 | 46 | .error-same-name 47 | color: red 48 | 49 | 50 | .reference 51 | display: flex 52 | flex-flow: column nowrap 53 | user-select: none 54 | 55 | &-item 56 | position: relative 57 | padding: 11px 38px 58 | margin-top: 10px 59 | font-size: 24px 60 | color: #666666 61 | letter-spacing: 0.54px 62 | cursor: pointer 63 | 64 | background: rgba(255,255,255,0.80) 65 | border: 2px solid #DDDDDD 66 | box-shadow: 0 2px 4px 0 rgba(0,0,0,0.10) 67 | border-radius: 10px 68 | 69 | transition: border-color 0.2s ease 70 | will-change: border-color 71 | 72 | .untitled 73 | color: #a7a7a7 74 | 75 | &:first-child 76 | margin-top: 0 77 | 78 | &:hover 79 | border-color: #6D9EE1 80 | 81 | &.reference-chosen 82 | border-color: #6D9EE1 83 | 84 | &:after 85 | content: '' 86 | background: url('assets/images/okay.png') no-repeat center center / contain 87 | height: 30px 88 | width: 30px 89 | 90 | position: absolute 91 | top: 10px 92 | right: 10px 93 | -------------------------------------------------------------------------------- /src/components/modals/SiteCreationModal/SiteCreationModal.sss: -------------------------------------------------------------------------------- 1 | .modal 2 | position: absolute 3 | height: 100% 4 | width: 100% 5 | top: 0 6 | left: 0 7 | 8 | z-index: 80 9 | 10 | overflow-y: scroll 11 | 12 | background: rgba(0, 0, 0, 0.5) 13 | 14 | &-header 15 | border-bottom: 1px solid #E5E5E5 16 | 17 | padding: 4px 0 18 | width: 100% 19 | 20 | display: flex 21 | flex-flow: column nowrap 22 | justify-content: center 23 | align-items: center 24 | user-select: none 25 | 26 | .title 27 | font-size: 20px 28 | color: #666666 29 | letter-spacing: 0.83px 30 | margin-top: 15px 31 | margin-bottom: 15px 32 | 33 | &-inner 34 | position: absolute 35 | left: 50% 36 | transform: translateX(-50%) 37 | background: #F9F9F9 38 | box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.10) 39 | border-radius: 5px 40 | 41 | margin: 30px 0 42 | 43 | width: 70% 44 | display: flex 45 | flex-flow: column nowrap 46 | align-items: center 47 | 48 | .content 49 | width: 100% 50 | padding: 32px 10% 51 | 52 | .input-wrapper 53 | width: 100% 54 | margin-bottom: 30px 55 | 56 | .buttons-wrapper 57 | display: flex 58 | flex-flow: row nowrap 59 | margin-top: 80px 60 | justify-content: center 61 | 62 | .buttons-inner:first-child 63 | margin-right: 25px 64 | 65 | .error-same-name 66 | color: #DD5555 67 | 68 | .label 69 | letter-spacing: 0.5px 70 | line-height: 30px 71 | font-size: 14px 72 | color: #2C2C30 73 | padding-bottom: 6px 74 | padding-left: 2px 75 | cursor: default 76 | user-select: none 77 | 78 | 79 | 80 | .TemplateControl 81 | width: 100% 82 | cursor: pointer 83 | margin-bottom: 5px 84 | user-select: none 85 | 86 | .template-content 87 | width: 100% 88 | border: 2px solid rgba(0, 0, 0, 0) 89 | border-radius: 5px 90 | display: flex 91 | align-items: center 92 | padding: 15px 93 | 94 | .icon, 95 | .icon-img 96 | width: 80px 97 | margin-right: 25px 98 | 99 | .text 100 | flex-grow: 1 101 | 102 | .title 103 | font-size: 18px 104 | font-weight: 600 105 | color: #666666 106 | margin-bottom: 10px 107 | 108 | .description 109 | font-size: 13px 110 | color: #999999 111 | 112 | .checked 113 | border-color: #8B5FBF 114 | -------------------------------------------------------------------------------- /src/components/modals/SiteLoader/SiteLoader.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import LoaderComponent from 'components/elements/LoaderComponent/LoaderComponent'; 4 | 5 | import styles from './SiteLoader.sss'; 6 | 7 | 8 | export default () => ( 9 |
10 | 11 |
12 | ); 13 | -------------------------------------------------------------------------------- /src/components/modals/SiteLoader/SiteLoader.sss: -------------------------------------------------------------------------------- 1 | .loader-wrapper 2 | position: absolute 3 | top: 0 4 | left: 0 5 | width: 100% 6 | height: 100% 7 | background: rgba(255,255,255,0.5) 8 | display: flex 9 | flex-flow: column nowrap 10 | justify-content: center 11 | align-items: center 12 | z-index: 100 13 | -------------------------------------------------------------------------------- /src/components/modals/WysiwygModal/WysiwygModal.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import CSSModules from 'react-css-modules'; 3 | import InlineSVG from 'svg-inline-react'; 4 | 5 | // load theme styles with webpack 6 | import 'medium-editor/dist/css/medium-editor.css'; 7 | import 'medium-editor/dist/css/themes/default.css'; 8 | 9 | import Editor from 'react-medium-editor'; 10 | 11 | import styles from './WysiwygModal.sss'; 12 | 13 | import ImageCrossCircle from 'assets/images/cross-circle.svg'; 14 | 15 | 16 | @CSSModules(styles, {allowMultiple: true}) 17 | export default class WysiwygModal extends Component { 18 | text = this.props.params.text; 19 | 20 | 21 | onClosing = () => { 22 | this.props.params.callback(this.text); 23 | this.props.onClose(); 24 | }; 25 | 26 | onChange = text => { 27 | this.text = text; 28 | }; 29 | 30 | render() { 31 | return ( 32 |
33 |
34 | 36 |
37 | 40 |
41 | ); 42 | } 43 | } -------------------------------------------------------------------------------- /src/components/modals/WysiwygModal/WysiwygModal.sss: -------------------------------------------------------------------------------- 1 | .wrapper 2 | position: absolute 3 | top: 0 4 | left: 0 5 | width: 100% 6 | height: 100% 7 | background: white 8 | z-index: 80 9 | padding: 50px 10 | 11 | .return 12 | position: absolute 13 | top: 10px 14 | left: 10px 15 | height: 24px 16 | width: 24px 17 | 18 | .cross 19 | height: 24px 20 | width: 24px 21 | opacity: .6 22 | cursor: pointer 23 | 24 | &:hover 25 | opacity: 1 26 | 27 | .editor 28 | width: 100% 29 | height: 100% 30 | -------------------------------------------------------------------------------- /src/components/sidebar/User/User.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import CSSModules from 'react-css-modules'; 3 | import InlineSVG from 'svg-inline-react'; 4 | import Gravatar from 'react-gravatar'; 5 | import {NavLink} from 'react-router-dom'; 6 | 7 | import {URL_USERSPACE, URL_PROFILE} from 'ducks/nav'; 8 | 9 | import styles from './User.sss'; 10 | 11 | import ImageArrowDown from "./arrow-down.svg"; 12 | import ImageAvatar from "./avatar.svg"; 13 | import ImageLogout from "./logout.svg"; 14 | 15 | 16 | 17 | @CSSModules(styles, {allowMultiple: true}) 18 | export default class User extends Component { 19 | state = { 20 | isAccountOpened: false 21 | }; 22 | 23 | toggleAccountMenu = () => this.setState({ 24 | isAccountOpened: !this.state.isAccountOpened 25 | }); 26 | 27 | closeAccountMenu = () => { 28 | if (this.state.isAccountOpened) 29 | setTimeout(() => this.setState({isAccountOpened: false}), 200); 30 | }; 31 | 32 | render() { 33 | const {userData, logoutHandler} = this.props; 34 | 35 | let name = userData.email; 36 | if (userData.firstName || userData.lastName) 37 | name = `${userData.firstName} ${userData.lastName}`; 38 | 39 | return ( 40 |
41 |
42 |
43 |
{name}
44 |
45 | 46 |
47 |
48 | 49 |
50 | 51 |
52 |
53 | 54 | {this.state.isAccountOpened && 55 |
56 | 57 |
58 | 59 | Profile 60 |
61 |
62 |
63 | 64 | Log out 65 |
66 |
67 | } 68 |
69 | 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/components/sidebar/User/User.sss: -------------------------------------------------------------------------------- 1 | .wrapper 2 | position: relative 3 | outline: none 4 | 5 | .logout 6 | font-size: 14px 7 | color: #000 8 | font-weight: 300 9 | cursor: pointer 10 | transition: opacity 0.2s ease 11 | will-change: opacity 12 | user-select: none 13 | 14 | display: flex 15 | flex-flow: row nowrap 16 | align-items: center 17 | 18 | &-icon 19 | margin-right: 10px 20 | 21 | svg 22 | opacity: 0.5 23 | max-width: 12px 24 | height: 13px 25 | 26 | .user 27 | padding: 20px 14px 28 | font-weight: 600 29 | font-size: 12px 30 | color: #666666 31 | 32 | display: flex 33 | justify-content: space-between 34 | align-items: center 35 | 36 | cursor: pointer 37 | 38 | &:hover 39 | background: #ececec 40 | 41 | .profile 42 | display: flex 43 | align-items: center 44 | user-select: none 45 | 46 | .avatar 47 | height: 32px 48 | width: 32px 49 | overflow: hidden 50 | background: #D8D8D8 51 | border: 1px solid #CCCCCC 52 | border-radius: 100% 53 | 54 | 55 | .gravatar 56 | width: 100% 57 | height: 100% 58 | background-size: contain 59 | background-position: center center 60 | 61 | &-name 62 | white-space: nowrap 63 | text-overflow: ellipsis 64 | overflow: hidden 65 | max-width: 180px 66 | color: #666666 67 | margin-right: 10px 68 | 69 | .arrow 70 | margin-top: 3px 71 | margin-left: 5px 72 | 73 | & svg 74 | height: 8px 75 | width: 8px 76 | 77 | .submenu 78 | position: absolute 79 | transform: translateY(100%) 80 | width: 100% 81 | bottom: 0 82 | border-radius: 0 0 6px 6px 83 | 84 | 85 | background: #ffffff 86 | box-shadow: 0px 4px 6px -2px rgba(0,0,0,0.10) 87 | 88 | div 89 | padding: 8px 90 | 91 | &:hover 92 | background: #ececec 93 | 94 | .userActive 95 | background: #ececec 96 | -------------------------------------------------------------------------------- /src/components/sidebar/User/arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Arrow 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/components/sidebar/User/avatar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 13 | 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 | -------------------------------------------------------------------------------- /src/components/sidebar/User/logout.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Shape 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/containers/Header/Header.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {bindActionCreators} from 'redux'; 3 | import {connect} from 'react-redux'; 4 | import CSSModules from 'react-css-modules'; 5 | import InlineSVG from 'svg-inline-react'; 6 | 7 | import Menu from 'components/header/Menu/Menu'; 8 | import User from 'components/sidebar/User/User'; 9 | import {logout} from 'ducks/user'; 10 | import {toggleSidebar} from 'ducks/nav'; 11 | 12 | import styles from './Header.sss'; 13 | 14 | import ImageIconSidebar from 'assets/images/icons/sidebar.svg'; 15 | 16 | 17 | @CSSModules(styles, {allowMultiple: true}) 18 | export class Header extends Component { 19 | render() { 20 | const {models, nav} = this.props; 21 | const {userData} = this.props.user; 22 | const {logout} = this.props.userActions; 23 | const {toggleSidebar} = this.props.sidebarActions; 24 | 25 | let nameId = models.currentSite ? models.currentSite.nameId : null; 26 | 27 | return ( 28 |
29 |
30 | 31 |
32 | 34 | 35 |
36 | ); 37 | } 38 | } 39 | 40 | function mapStateToProps(state) { 41 | return { 42 | models: state.models, 43 | user: state.user, 44 | nav: state.nav, 45 | }; 46 | } 47 | 48 | function mapDispatchToProps(dispatch) { 49 | return { 50 | userActions: bindActionCreators({logout}, dispatch), 51 | sidebarActions: bindActionCreators({toggleSidebar}, dispatch) 52 | }; 53 | } 54 | 55 | export default connect(mapStateToProps, mapDispatchToProps)(Header); 56 | -------------------------------------------------------------------------------- /src/containers/Header/Header.sss: -------------------------------------------------------------------------------- 1 | .header 2 | background: #fff 3 | top: 0 4 | left: 0 5 | width: 100% 6 | min-height: 60px 7 | z-index: 10 8 | 9 | display: flex 10 | justify-content: space-between 11 | align-items: center 12 | 13 | box-shadow: 0px 4px 6px -2px rgba(0,0,0,0.10) 14 | 15 | .sidebar-icon 16 | width: 18px 17 | height: 18px 18 | margin-left: 26px 19 | cursor: pointer 20 | 21 | svg 22 | width: 18px 23 | height: 18px 24 | -------------------------------------------------------------------------------- /src/containers/LinksEmail/EmailVerify/EmailVerify.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {connect} from 'react-redux'; 3 | import CSSModules from 'react-css-modules'; 4 | import {Helmet} from "react-helmet-async"; 5 | 6 | import ButtonControl from 'components/elements/ButtonControl/ButtonControl'; 7 | import {URL_USERSPACE, URL_SIGN} from 'ducks/nav'; 8 | import {withRouter} from 'utils/routing'; 9 | 10 | import styles from './EmailVerify.sss'; 11 | 12 | import ImageChiselLogo from 'assets/images/chisel-logo.png'; 13 | 14 | 15 | @CSSModules(styles, {allowMultiple: true}) 16 | export class EmailVerify extends Component { 17 | onLogin = event => { 18 | event.preventDefault(); 19 | 20 | const {navigate} = this.props.router; 21 | if (this.props.authorized) 22 | navigate(`/${URL_USERSPACE}`, {replace: true}); 23 | else 24 | navigate(`/${URL_SIGN}`, {replace: true}); 25 | 26 | return false; 27 | }; 28 | 29 | render() { 30 | return ( 31 |
32 | 33 | Verifying email - Chisel 34 | 35 |
36 | 37 |
38 |
Your email was verified successfully.
39 |
40 |
41 | 44 |
45 |
46 |
47 | ); 48 | } 49 | } 50 | 51 | function mapStateToProps(state) { 52 | return { 53 | authorized: state.user.authorized 54 | }; 55 | } 56 | 57 | export default withRouter(connect(mapStateToProps)(EmailVerify)); 58 | -------------------------------------------------------------------------------- /src/containers/LinksEmail/EmailVerify/EmailVerify.sss: -------------------------------------------------------------------------------- 1 | .EmailVerify 2 | position: absolute 3 | top: 50% 4 | left: 50% 5 | transform: translate(-50%, -50%) 6 | min-width: 46% 7 | 8 | display: flex 9 | flex-flow: column nowrap 10 | justify-content: center 11 | align-items: center 12 | 13 | .logo 14 | margin-bottom: 15px 15 | text-align: center 16 | 17 | img 18 | height: 35px 19 | 20 | .title 21 | font-size: 20px 22 | color: #666666 23 | letter-spacing: 0.83px 24 | 25 | .form 26 | margin-top: 25px 27 | display: flex 28 | flex-flow: column nowrap 29 | width: 100% 30 | justify-content: space-between 31 | align-items: center 32 | 33 | .description 34 | color: #666666 35 | font-size: 12px 36 | text-align: center 37 | 38 | .button 39 | margin-top: 30px 40 | -------------------------------------------------------------------------------- /src/containers/LinksEmail/InvalidLink/InvalidLink.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import CSSModules from 'react-css-modules'; 3 | import {connect} from 'react-redux'; 4 | import {Helmet} from "react-helmet-async"; 5 | 6 | import ButtonControl from 'components/elements/ButtonControl/ButtonControl'; 7 | import {URL_USERSPACE, URL_SIGN} from 'ducks/nav'; 8 | import {withRouter} from 'utils/routing'; 9 | 10 | import styles from './InvalidLink.sss'; 11 | 12 | import ImageChiselLogo from 'assets/images/chisel-logo.png'; 13 | 14 | 15 | @CSSModules(styles, {allowMultiple: true}) 16 | export class InvalidLink extends Component { 17 | onLogin = event => { 18 | event.preventDefault(); 19 | 20 | const {navigate} = this.props.router; 21 | if (this.props.authorized) 22 | navigate(`/${URL_USERSPACE}`, {replace: true}); 23 | else 24 | navigate(`/${URL_SIGN}`, {replace: true}); 25 | 26 | return false; 27 | }; 28 | 29 | render() { 30 | return ( 31 |
32 | 33 | Invalid link - Chisel 34 | 35 |
36 | 37 |
38 |
The link is invalid.
39 |
40 |
41 | 44 |
45 |
46 |
47 | ); 48 | } 49 | } 50 | 51 | function mapStateToProps(state) { 52 | return { 53 | authorized: state.user.authorized 54 | }; 55 | } 56 | 57 | export default withRouter(connect(mapStateToProps)(InvalidLink)); -------------------------------------------------------------------------------- /src/containers/LinksEmail/InvalidLink/InvalidLink.sss: -------------------------------------------------------------------------------- 1 | .InvalidLink 2 | position: absolute 3 | top: 50% 4 | left: 50% 5 | transform: translate(-50%, -50%) 6 | min-width: 46% 7 | 8 | display: flex 9 | flex-flow: column nowrap 10 | justify-content: center 11 | align-items: center 12 | 13 | .logo 14 | margin-bottom: 15px 15 | text-align: center 16 | 17 | img 18 | height: 35px 19 | 20 | .title 21 | font-size: 20px 22 | color: #666666 23 | letter-spacing: 0.83px 24 | 25 | .form 26 | margin-top: 25px 27 | display: flex 28 | flex-flow: column nowrap 29 | width: 100% 30 | justify-content: space-between 31 | align-items: center 32 | 33 | .description 34 | color: #666666 35 | font-size: 12px 36 | text-align: center 37 | 38 | .button 39 | margin-top: 30px 40 | -------------------------------------------------------------------------------- /src/containers/LinksEmail/PasswordSet/PasswordSet.sss: -------------------------------------------------------------------------------- 1 | .PasswordSet 2 | position: absolute 3 | top: 50% 4 | left: 50% 5 | transform: translate(-50%, -50%) 6 | min-width: 46% 7 | 8 | display: flex 9 | flex-flow: column nowrap 10 | justify-content: center 11 | align-items: center 12 | 13 | .logo 14 | margin-bottom: 15px 15 | text-align: center 16 | 17 | img 18 | height: 35px 19 | 20 | .title 21 | font-size: 20px 22 | color: #666666 23 | letter-spacing: 0.83px 24 | 25 | .form 26 | margin-top: 25px 27 | display: flex 28 | flex-flow: column nowrap 29 | width: 100% 30 | justify-content: space-between 31 | align-items: center 32 | 33 | .description 34 | color: #666666 35 | font-size: 12px 36 | text-align: center 37 | 38 | .input 39 | background: #FFFFFF 40 | border: none 41 | border-bottom: 1px #ccc solid 42 | border-radius: 2px 43 | line-height: 38px 44 | padding: 0 40px 0 9px 45 | outline: none 46 | width: 50% 47 | font-size: 13px 48 | color: #333333 49 | letter-spacing: 0.5px 50 | 51 | margin-top: 20px 52 | 53 | transition: border-color 0.2s ease 54 | will-change: border-color 55 | 56 | &:focus 57 | border-color: #5CA6DC 58 | 59 | &:first-child 60 | margin-top: 0 61 | 62 | .button 63 | margin-top: 30px 64 | 65 | .errors 66 | min-height: 35px 67 | margin-top: 15px 68 | 69 | .error 70 | color: #ff5656 71 | font-size: 12px 72 | text-align: center 73 | -------------------------------------------------------------------------------- /src/containers/MainArea/API/APIPage.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import InlineSVG from 'svg-inline-react'; 3 | import {connect} from 'react-redux'; 4 | import {Helmet} from "react-helmet-async"; 5 | 6 | import {ROLE_EDITOR} from 'models/UserData'; 7 | import NoRights from "components/mainArea/common/NoRights"; 8 | 9 | import ImageHammer from 'assets/images/hammer.svg'; 10 | 11 | 12 | function APIPage() { 13 | return ( 14 |
15 | 16 |
17 | Parse Server has extensive Documentation. Take a look! 18 |
Our Interactive API Docs will be coming soon...
19 |
20 |
21 | ); 22 | } 23 | 24 | function APIPageContainer({models, nav}) { 25 | let title = `Chisel`; 26 | let content = nav.initEnded ? : null; 27 | 28 | const curSite = models.currentSite; 29 | if (curSite) { 30 | title = `API - Site: ${curSite.name} - Chisel`; 31 | 32 | const role = models.role; 33 | if (role != ROLE_EDITOR) 34 | content = ; 35 | } 36 | 37 | return <> 38 | 39 | {title} 40 | 41 | {content} 42 | ; 43 | } 44 | 45 | function mapStateToProps(state) { 46 | return { 47 | models: state.models, 48 | nav: state.nav 49 | }; 50 | } 51 | 52 | export default connect(mapStateToProps)(APIPageContainer); 53 | -------------------------------------------------------------------------------- /src/containers/MainArea/API/APIPage.sss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/src/containers/MainArea/API/APIPage.sss -------------------------------------------------------------------------------- /src/containers/MainArea/MainArea.sss: -------------------------------------------------------------------------------- 1 | .wrapper 2 | display: flex 3 | flex-flow: row nowrap 4 | height: 100% 5 | width: 100% 6 | position: absolute 7 | 8 | .inner 9 | display: flex 10 | flex-flow: column nowrap 11 | flex: 1 1 auto 12 | background: #f9f9f9 13 | 14 | .mainArea 15 | flex: 1 16 | overflow-x: hidden 17 | display: flex 18 | flex-flow: column nowrap 19 | align-items: center 20 | transform: translate3d(0, 0, 0) 21 | padding: 35px 0 22 | -------------------------------------------------------------------------------- /src/containers/MainArea/Models/ModelsListContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {bindActionCreators} from 'redux'; 3 | import {connect} from 'react-redux'; 4 | import {Helmet} from "react-helmet-async"; 5 | import {useNavigate} from 'react-router-dom'; 6 | 7 | import ModelsList from 'components/mainArea/models/ModelsList/ModelsList'; 8 | import {addModel, deleteModel} from 'ducks/models'; 9 | import {showAlert, URL_USERSPACE, URL_SITE, URL_MODELS, URL_MODEL} from 'ducks/nav'; 10 | import {ROLE_ADMIN, ROLE_OWNER} from 'models/UserData'; 11 | import NoRights from "components/mainArea/common/NoRights"; 12 | 13 | 14 | function ModelsListContainer(props) { 15 | const {models, nav} = props; 16 | const {addModel, deleteModel} = props.modelsActions; 17 | const {showAlert} = props.navActions; 18 | const navigate = useNavigate(); 19 | 20 | let title = `Chisel`; 21 | let content = nav.initEnded ? : null; 22 | 23 | const site = models.currentSite; 24 | if (site && (models.role == ROLE_ADMIN || models.role == ROLE_OWNER)) { 25 | title = `Models - Site: ${site.name} - Chisel`; 26 | const gotoModel = model => navigate( 27 | `/${URL_USERSPACE}/${URL_SITE}${site.nameId}/${URL_MODELS}/${URL_MODEL}${model.nameId}`); 28 | content = ( 29 | 36 | ); 37 | } 38 | 39 | return <> 40 | 41 | {title} 42 | 43 | {content} 44 | ; 45 | } 46 | 47 | function mapStateToProps(state) { 48 | return { 49 | models: state.models, 50 | nav: state.nav 51 | }; 52 | } 53 | 54 | function mapDispatchToProps(dispatch) { 55 | return { 56 | modelsActions: bindActionCreators({addModel, deleteModel}, dispatch), 57 | navActions: bindActionCreators({showAlert}, dispatch) 58 | }; 59 | } 60 | 61 | export default connect(mapStateToProps, mapDispatchToProps)(ModelsListContainer); 62 | -------------------------------------------------------------------------------- /src/containers/MainArea/PaymentMethods/PaymentMethods.sss: -------------------------------------------------------------------------------- 1 | .content 2 | width: 100% 3 | margin-top: 30px 4 | display: flex 5 | flex-flow: row nowrap 6 | justify-content: space-between 7 | 8 | .side 9 | flex: 0 0 270px 10 | padding-right: 40px 11 | 12 | .method 13 | display: flex 14 | flex-flow: row nowrap 15 | justify-content: space-between 16 | align-items: center 17 | 18 | padding-bottom: 10px 19 | padding-top: 10px 20 | padding-right: 11px 21 | margin-bottom: 10px 22 | border-radius: 20px 23 | 24 | background: #FFFFFF 25 | box-shadow: 0 1px 0 0 rgba(0,0,0,0.05), 0 1px 10px 0 rgba(0,0,0,0.05) 26 | cursor: pointer 27 | 28 | 29 | &-checked 30 | background: #eeeeee 31 | 32 | .name 33 | font-size: 14px 34 | color: #313133 35 | line-height: 24px 36 | padding-left: 15px 37 | user-select: none 38 | 39 | &-new 40 | .name 41 | font-weight: 300 42 | 43 | 44 | .main 45 | flex: 1 46 | padding-left: 40px 47 | 48 | .payplan-info 49 | padding-bottom: 20px 50 | font-size: 13px 51 | color: #666666 52 | 53 | p 54 | margin-top: 0px 55 | 56 | .method-content 57 | color: #666666 58 | 59 | .label 60 | user-select: none 61 | 62 | .method-name 63 | font-size: 15px 64 | color: #666666 65 | 66 | 67 | .form 68 | padding-bottom: 20px 69 | 70 | .section 71 | font-size: 16px 72 | color: #2C2C30 73 | margin-bottom: 50px 74 | 75 | &-header 76 | user-select: none 77 | 78 | .inputs-inline 79 | display: flex 80 | max-width: 430px 81 | 82 | .input-wrapper 83 | max-width: 430px 84 | margin-top: 15px 85 | flex-grow: 1 86 | 87 | .input-state 88 | width: 80px 89 | margin-left: 15px 90 | 91 | .input-zip 92 | max-width: 140px 93 | margin-left: 15px 94 | flex-grow: 0 95 | 96 | .card-wrapper 97 | margin-top: 15px 98 | max-width: 430px 99 | background: #ffffff 100 | padding: 10px 10px 10px 15px 101 | border-radius: 20px 102 | box-shadow: 0 1px 0 0 rgba(0,0,0,0.05), 0 1px 10px 0 rgba(0,0,0,0.05) 103 | 104 | .error 105 | margin-top: 10px 106 | font-size: 14px 107 | color: #DD5555 108 | 109 | 110 | .label 111 | font-size: 16px 112 | color: #2C2C30 113 | margin-bottom: 20px 114 | 115 | .checkbox-wrapper 116 | margin-bottom: 50px 117 | font-size: 13px 118 | 119 | .button-wrapper 120 | margin-top: 40px 121 | 122 | .icon-plus 123 | width: 18px 124 | height: 18px -------------------------------------------------------------------------------- /src/containers/MainArea/Settings/SettingsContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {bindActionCreators} from 'redux'; 3 | import {connect} from 'react-redux'; 4 | import {Helmet} from "react-helmet-async"; 5 | 6 | import Settings from 'components/mainArea/settings/Settings'; 7 | import {ROLE_OWNER, ROLE_ADMIN} from 'models/UserData'; 8 | import {updateSite, deleteSite} from 'ducks/models'; 9 | import {showAlert} from 'ducks/nav'; 10 | 11 | 12 | function SettingsContainer(props) { 13 | const {models} = props; 14 | const {updateSite, deleteSite} = props.modelsActions; 15 | const {showAlert} = props.navActions; 16 | 17 | const site = models.currentSite; 18 | if (!site) 19 | return null; 20 | 21 | const title = `Settings - Site: ${site.name} - Chisel`; 22 | 23 | return <> 24 | 25 | {title} 26 | 27 | 32 | ; 33 | } 34 | 35 | function mapStateToProps(state) { 36 | return { 37 | models: state.models 38 | }; 39 | } 40 | 41 | function mapDispatchToProps(dispatch) { 42 | return { 43 | modelsActions: bindActionCreators({updateSite, deleteSite}, dispatch), 44 | navActions: bindActionCreators({showAlert}, dispatch) 45 | }; 46 | } 47 | 48 | export default connect(mapStateToProps, mapDispatchToProps)(SettingsContainer); 49 | -------------------------------------------------------------------------------- /src/containers/MainArea/Sharing/SharingContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {bindActionCreators} from 'redux'; 3 | import {connect} from 'react-redux'; 4 | import {Helmet} from "react-helmet-async"; 5 | 6 | import Sharing from 'components/mainArea/sharing/Sharing'; 7 | import {ROLE_OWNER, ROLE_ADMIN} from 'models/UserData'; 8 | import {addCollaboration, addInviteCollaboration, updateCollaboration, deleteCollaboration, deleteSelfCollaboration} 9 | from 'ducks/models'; 10 | import {showAlert, showModal} from 'ducks/nav'; 11 | 12 | 13 | function SharingContainer(props) { 14 | const {models, nav, user} = props; 15 | const {addCollaboration, addInviteCollaboration, updateCollaboration, deleteCollaboration, deleteSelfCollaboration} = 16 | props.modelsActions; 17 | const {showAlert, showModal} = props.navActions; 18 | 19 | let site = models.currentSite; 20 | if (!site) 21 | return null; 22 | 23 | let title = `Sharing - Site: ${site.name} - Chisel`; 24 | 25 | return <> 26 | 27 | {title} 28 | 29 | 42 | ; 43 | } 44 | 45 | function mapStateToProps(state) { 46 | return { 47 | models: state.models, 48 | nav: state.nav, 49 | user: state.user 50 | }; 51 | } 52 | 53 | function mapDispatchToProps(dispatch) { 54 | return { 55 | modelsActions: bindActionCreators({addCollaboration, addInviteCollaboration, updateCollaboration, deleteCollaboration, deleteSelfCollaboration}, dispatch), 56 | navActions: bindActionCreators({showAlert, showModal}, dispatch), 57 | }; 58 | } 59 | 60 | export default connect(mapStateToProps, mapDispatchToProps)(SharingContainer); 61 | -------------------------------------------------------------------------------- /src/containers/MainArea/UserProfile/UserProfile.sss: -------------------------------------------------------------------------------- 1 | .content 2 | display: flex 3 | flex-flow: column nowrap 4 | align-items: flex-start 5 | 6 | width: 100% 7 | 8 | .section 9 | margin-top: 10px 10 | margin-bottom: 35px 11 | width: 100% 12 | 13 | &-header 14 | font-size: 18px 15 | font-family: 'Inter-UI', sans-serif 16 | color: #313133 17 | font-weight: 600 18 | user-select: none 19 | 20 | 21 | .field 22 | margin-top: 15px 23 | width: 100% 24 | text-align: left 25 | 26 | display: flex 27 | flex-flow: column nowrap 28 | 29 | transition: color 0.2s ease 30 | will-change: color 31 | 32 | &-title, 33 | &-error, 34 | &-success 35 | font-size: 14px 36 | color: #2C2C30 37 | letter-spacing: 0.5px 38 | line-height: 30px 39 | text-align: left 40 | flex-grow: 1 41 | 42 | transition: color 0.2s ease 43 | will-change: color 44 | user-select: none 45 | 46 | &-error 47 | color: #DD5555 48 | 49 | &-success 50 | color: #5DAD47 51 | 52 | &-resend 53 | cursor: pointer 54 | text-decoration: underline 55 | 56 | &-value 57 | font-size: 18px 58 | color: #666666 59 | margin-bottom: 10px 60 | 61 | .input-wrapper 62 | display: flex 63 | flex-flow: column nowrap 64 | user-select: none 65 | 66 | .buttons-wrapper 67 | margin-top: 20px 68 | display: flex 69 | flex-flow: row nowrap 70 | justify-content: space-between 71 | align-items: center 72 | 73 | .button 74 | flex-shrink: 0 75 | 76 | .name-wrapper 77 | display: flex 78 | flex-flow: row nowrap 79 | justify-content: space-between 80 | width: 100% 81 | 82 | .field 83 | width: 49% 84 | -------------------------------------------------------------------------------- /src/containers/Sidebar/Sidebar.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {bindActionCreators} from 'redux'; 3 | import {connect} from 'react-redux'; 4 | import CSSModules from 'react-css-modules'; 5 | import {NavLink} from 'react-router-dom'; 6 | 7 | import Sites from 'components/sidebar/Sites/Sites'; 8 | import {showModal, showAlert, URL_USERSPACE, URL_SITE, URL_PAY_PLANS} from 'ducks/nav'; 9 | import {isPayPlanTop} from 'utils/data'; 10 | 11 | import styles from './Sidebar.sss'; 12 | import {useNavigate} from "react-router-dom"; 13 | 14 | 15 | 16 | function Sidebar(props) { 17 | const {models, isSidebarVisible} = props; 18 | const {userData} = props.user; 19 | const {stripeInitError} = props.pay; 20 | const {showModal, showAlert} = props.navActions; 21 | const navigate = useNavigate(); 22 | 23 | const gotoSite = site => { 24 | const nameId = site.nameId; 25 | navigate(`/${URL_USERSPACE}/${URL_SITE}${nameId}`); 26 | }; 27 | 28 | const showPay = !!userData.payPlan; 29 | const showPayUpgrade = showPay && !stripeInitError && !isPayPlanTop(userData.payPlan); 30 | 31 | return ( 32 |
34 | 35 | Chisel 36 | 37 |
38 | 45 |
46 | 47 |
48 | {showPayUpgrade && 49 | 51 | Upgrade your account 52 | 53 | } 54 | 57 | Need help? 58 | 59 |
60 |
61 | ); 62 | } 63 | 64 | function mapStateToProps(state) { 65 | return { 66 | models: state.models, 67 | user: state.user, 68 | pay: state.pay 69 | }; 70 | } 71 | 72 | function mapDispatchToProps(dispatch) { 73 | return { 74 | navActions: bindActionCreators({showModal, showAlert}, dispatch) 75 | }; 76 | } 77 | 78 | export default connect(mapStateToProps, mapDispatchToProps)(CSSModules(Sidebar, styles, {allowMultiple: true})); 79 | -------------------------------------------------------------------------------- /src/containers/Sidebar/Sidebar.sss: -------------------------------------------------------------------------------- 1 | .sidebar 2 | overflow-x: hidden 3 | display: flex 4 | flex-flow: column nowrap 5 | background: #1A1A1C 6 | height: 100vh 7 | max-width: 300px 8 | width: 100% 9 | transform: translate3d(0, 0, 0) 10 | box-shadow: inset -10px 0 30px 0 rgba(0,0,0,0.25) 11 | transition: max-width .2s ease 12 | user-select: none 13 | 14 | .header 15 | height: 72px 16 | border-bottom: 1px solid #313133 17 | font-size: 24px 18 | color: #FFFFFF 19 | flex-shrink: 0 20 | display: flex 21 | align-items: center 22 | padding-left: 21px 23 | width: 300px 24 | 25 | .sites-wrapper 26 | flex: 1 1 auto 27 | display: flex 28 | flex-flow: column nowrap 29 | width: 300px 30 | 31 | .bottom-panel 32 | display: flex 33 | flex-flow: column nowrap 34 | justify-content: space-between 35 | align-items: center 36 | width: 300px 37 | 38 | .bottom-link 39 | margin-bottom: 20px 40 | font-size: 13px 41 | color: #666666 42 | 43 | &:hover 44 | color: #6D9EE1 45 | 46 | .answer-question 47 | height: 32px 48 | width: 32px 49 | margin-bottom: 30px 50 | border-radius: 100% 51 | background: #FFFFFF 52 | border: 1px solid #CCCCCC 53 | box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.10) 54 | transition: box-shadow 0.1s ease 55 | will-change: transition 56 | display: flex 57 | flex-flow: column nowrap 58 | justify-content: center 59 | align-items: center 60 | cursor: pointer 61 | 62 | &:hover 63 | box-shadow: 0px 0px 5px 3px rgba(0,0,0,0.10) 64 | 65 | .icon svg 66 | height: 15px 67 | 68 | .sidebarHidden 69 | max-width: 0 70 | -------------------------------------------------------------------------------- /src/containers/app.sss: -------------------------------------------------------------------------------- 1 | .wrapper 2 | overflow: hidden 3 | height: 100vh 4 | width: 100vw 5 | transform: translate3d(0, 0, 0) 6 | 7 | .modal-enter 8 | opacity: 0.01 9 | 10 | .modal-enter.modal-enter-active 11 | opacity: 1 12 | transition: opacity 200ms ease-in-out 13 | 14 | .modal-exit 15 | opacity: 1 16 | 17 | .modal-exit.modal-exit-active 18 | opacity: 0.01 19 | transition: opacity 200ms ease-in-out 20 | 21 | 22 | .alarm 23 | position: absolute 24 | top: 100vh 25 | left: 100vw 26 | width: 330px 27 | padding: 6px 15px 28 | text-align: right 29 | transform: translate(-100%, -100%) 30 | background: rgba(0, 0, 0, 0.06) 31 | color: #ff5656 32 | z-index: 200 33 | animation-name: blinking 34 | animation-duration: 2s 35 | animation-iteration-count: infinite 36 | animation-timing-function: cubic-bezier(0.1, 0, 1, 1) 37 | animation-direction: alternate 38 | 39 | font-size: 13px 40 | letter-spacing: 0.5px 41 | 42 | 43 | @keyframes blinking 44 | 0% 45 | opacity: 1 46 | 50% 47 | opacity: .31 -------------------------------------------------------------------------------- /src/ducks/index.js: -------------------------------------------------------------------------------- 1 | import {combineReducers} from 'redux'; 2 | 3 | import models from './models'; 4 | import content from './content'; 5 | import nav from './nav'; 6 | import user from './user'; 7 | import media from './media'; 8 | import pay from './pay'; 9 | 10 | 11 | export default combineReducers({ 12 | models, 13 | content, 14 | nav, 15 | user, 16 | media, 17 | pay 18 | }); -------------------------------------------------------------------------------- /src/fonts.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Open Sans'; 3 | src: url('assets/fonts/OpenSans-Light-webfont.ttf'); 4 | font-weight: 300; 5 | font-style: normal; 6 | } 7 | 8 | @font-face { 9 | font-family: 'Open Sans'; 10 | src: url('assets/fonts/OpenSans-Regular-webfont.ttf'); 11 | font-weight: 400; 12 | font-style: normal; 13 | } 14 | 15 | @font-face { 16 | font-family: 'Open Sans'; 17 | src: url('assets/fonts/OpenSans-Regular-webfont.ttf'); 18 | font-weight: normal; 19 | font-style: normal; 20 | } 21 | 22 | @font-face { 23 | font-family: 'Open Sans'; 24 | src: url('assets/fonts/OpenSans-Semibold-webfont.ttf'); 25 | font-weight: 600; 26 | font-style: normal; 27 | } 28 | 29 | @font-face { 30 | font-family: 'Open Sans'; 31 | src: url('assets/fonts/OpenSans-Bold-webfont.ttf'); 32 | font-weight: 700; 33 | font-style: normal; 34 | } 35 | 36 | @font-face { 37 | font-family: 'Inter-UI'; 38 | src: url('assets/fonts/Inter-UI-Regular.ttf'); 39 | font-weight: normal; 40 | font-style: normal; 41 | } 42 | 43 | @font-face { 44 | font-family: 'Inter-UI'; 45 | src: url('assets/fonts/Inter-UI-Medium.ttf'); 46 | font-weight: 500; 47 | font-style: normal; 48 | } 49 | 50 | @font-face { 51 | font-family: 'Inter-UI'; 52 | src: url('assets/fonts/Inter-UI-SemiBold.ttf'); 53 | font-weight: 600; 54 | font-style: normal; 55 | } 56 | 57 | @font-face { 58 | font-family: 'Inter-UI'; 59 | src: url('assets/fonts/Inter-UI-Bold.ttf'); 60 | font-weight: 700; 61 | font-style: normal; 62 | } 63 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import 'whatwg-fetch'; 2 | import 'normalize.css'; 3 | 4 | import './fonts.css'; 5 | import './styles.global.sss'; 6 | 7 | import React from 'react'; 8 | import ReactDOM from 'react-dom'; 9 | import {Provider} from 'react-redux'; 10 | import {HashRouter, BrowserRouter, Route, Routes} from "react-router-dom"; 11 | import {HelmetProvider} from 'react-helmet-async'; 12 | 13 | import App from 'containers/app'; 14 | import configureStore from 'store/configureStore'; 15 | import {isElectron} from 'utils/common'; 16 | import {initApp} from 'utils/initialize'; 17 | 18 | 19 | const Router = isElectron() ? HashRouter : BrowserRouter; 20 | 21 | export const store = configureStore(); 22 | 23 | initApp(); 24 | 25 | function Root() { 26 | return ( 27 | // 28 | 29 | 30 | 31 | 32 | } /> 33 | 34 | 35 | 36 | 37 | // 38 | ); 39 | } 40 | 41 | const root = ReactDOM.render( 42 | , 43 | document.getElementById('app-root') 44 | ); 45 | -------------------------------------------------------------------------------- /src/index.pug: -------------------------------------------------------------------------------- 1 | html(lang="en") 2 | head 3 | meta(charset="utf-8") 4 | meta(http-equiv="Content-Type" content="text/html") 5 | meta(http-equiv="x-ua-compatible" content="ie=edge") 6 | title Chisel 7 | meta(name="description" content="Parse CMS") 8 | meta(name="viewport" content="width=device-width, initial-scale=1") 9 | link(rel="apple-touch-icon" sizes="180x180" href="/assets/images/logo/apple-touch-icon.png") 10 | link(rel="icon" type="image/png" sizes="512x512" href="/assets/images/logo/logo512.png") 11 | link(rel="icon" type="image/x-icon" href="/favicon.ico") 12 | link(rel="manifest" href="/manifest.json") 13 | script(defer src="https://use.fontawesome.com/releases/v5.0.6/js/all.js") 14 | script(src="https://js.stripe.com/v3/") 15 | base(href="./") 16 | body 17 | noscript You need to enable JavaScript to run this app. 18 | #app-root 19 | -------------------------------------------------------------------------------- /src/middleware/initialization.js: -------------------------------------------------------------------------------- 1 | import {LOGIN_RESPONSE, REGISTER_RESPONSE, checkPayPlan} from 'ducks/user'; 2 | import {init as init_models, INIT_END as INIT_END_models} from 'ducks/models'; 3 | import {init as init_media, INIT_END as INIT_END_media} from 'ducks/media'; 4 | import {init as init_content, INIT_END as INIT_END_content} from 'ducks/content'; 5 | import {init as init_pay, INIT_END as INIT_END_pay} from 'ducks/pay'; 6 | import {initEnd} from 'ducks/nav'; 7 | 8 | 9 | export const initialization = store => next => action => { 10 | next(action); 11 | 12 | if ((action.type == REGISTER_RESPONSE || action.type == LOGIN_RESPONSE) && 13 | action.authorized) { 14 | next(init_models()); 15 | } 16 | 17 | if (action.type == INIT_END_models) 18 | next(init_media()); 19 | 20 | if (action.type == INIT_END_media) 21 | next(init_content()); 22 | 23 | if (action.type == INIT_END_content) 24 | next(init_pay()); 25 | 26 | if (action.type == INIT_END_pay) { 27 | next(checkPayPlan()); 28 | next(initEnd()); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /src/middleware/payments.js: -------------------------------------------------------------------------------- 1 | import {INIT_END, showAlert, URL_PAYMENT_METHODS, URL_USERSPACE} from "ducks/nav"; 2 | import {ALERT_TYPE_CONFIRM} from "components/modals/AlertModal/AlertModal"; 3 | 4 | export const payments = store => next => action => { 5 | next(action); 6 | 7 | if (action.type == INIT_END) { 8 | if (store.getState().nav.showUnpaidSub) { 9 | const {navigate} = store.getState().nav; 10 | next(showAlert({ 11 | type: ALERT_TYPE_CONFIRM, 12 | title: `Failed payment`, 13 | description: `We can't withdraw money for next payment period. Please, update your payment methods.`, 14 | confirmLabel: 'Open payment methods', 15 | cancelLabel: 'Close', 16 | onConfirm: () => navigate(`/${URL_USERSPACE}/${URL_PAYMENT_METHODS}`) 17 | })); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/models/MediaItemData.js: -------------------------------------------------------------------------------- 1 | import {Parse} from 'parse'; 2 | 3 | 4 | export const MEDIA_TYPE__IMAGE = "MEDIA_TYPE__IMAGE"; 5 | 6 | let keys = []; 7 | 8 | export class MediaItemData { 9 | static get OriginClass() {return Parse.Object.extend("MediaItem");} 10 | 11 | origin = null; 12 | 13 | name = ''; 14 | type = MEDIA_TYPE__IMAGE; 15 | size = 0; 16 | file = null; 17 | assigned = false; 18 | 19 | key = 0; 20 | 21 | //links 22 | site = null; 23 | 24 | constructor() { 25 | while (keys.indexOf(this.key) != -1) 26 | this.key++; 27 | keys.push(this.key); 28 | } 29 | 30 | setOrigin(origin) { 31 | this.origin = origin; 32 | 33 | if (origin.get('name')) this.name = origin.get('name'); 34 | if (origin.get('type')) this.type = origin.get('type'); 35 | if (origin.get('size')) this.size = origin.get('size'); 36 | if (origin.get('file')) this.file = origin.get('file'); 37 | if (origin.get('assigned')) this.assigned = origin.get('assigned'); 38 | 39 | return this; 40 | } 41 | 42 | updateOrigin() { 43 | if (!this.origin) 44 | this.origin = new MediaItemData.OriginClass; 45 | 46 | this.origin.set("name", this.name); 47 | this.origin.set("type", this.type); 48 | this.origin.set("size", this.size); 49 | this.origin.set("file", this.file); 50 | this.origin.set("assigned", this.assigned); 51 | this.origin.set("site", this.site.origin); 52 | } 53 | 54 | clone() { 55 | let item = new MediaItemData(); 56 | item.name = this.name; 57 | item.type = this.type; 58 | item.size = this.size; 59 | item.file = this.file; 60 | item.assigned = this.assigned; 61 | item.site = this.site; 62 | return item; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/models/PayPlanData.js: -------------------------------------------------------------------------------- 1 | import {Parse} from 'parse'; 2 | 3 | 4 | export class PayPlanData { 5 | static get OriginClass() {return Parse.Object.extend("PayPlan");} 6 | 7 | origin = null; 8 | 9 | name = ''; 10 | limitSites = 0; 11 | priceMonthly = 0; 12 | priceYearly = 0; 13 | StripeIdMonthly = ''; 14 | StripeIdYearly = ''; 15 | 16 | isFree = true; 17 | 18 | 19 | setOrigin(origin) { 20 | this.origin = origin; 21 | 22 | if (origin.get('name')) this.name = origin.get('name'); 23 | if (origin.get('limitSites')) this.limitSites = origin.get('limitSites'); 24 | if (origin.get('priceMonthly')) this.priceMonthly = origin.get('priceMonthly'); 25 | if (origin.get('priceYearly')) this.priceYearly = origin.get('priceYearly'); 26 | if (origin.get('StripeIdMonthly')) this.StripeIdMonthly = origin.get('StripeIdMonthly'); 27 | if (origin.get('StripeIdYearly')) this.StripeIdYearly = origin.get('StripeIdYearly'); 28 | 29 | this.isFree = !this.priceMonthly && !this.priceYearly; 30 | 31 | return this; 32 | } 33 | 34 | greaterThan(payPlan) { 35 | return this.priceMonthly > payPlan.priceMonthly; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/store/configureStore.js: -------------------------------------------------------------------------------- 1 | import {createStore, applyMiddleware} from 'redux'; 2 | import {createLogger} from 'redux-logger'; 3 | import thunk from 'redux-thunk'; 4 | 5 | import rootReducer from 'ducks'; 6 | import {initialization} from 'middleware/initialization'; 7 | import {routing} from 'middleware/routing'; 8 | import liveUpdates from 'middleware/liveUpdates'; 9 | import {payments} from 'middleware/payments'; 10 | 11 | 12 | export default function configureStore(initialState) { 13 | const logger = createLogger(); 14 | 15 | const middleware = [initialization, ...liveUpdates, payments, routing, thunk]; 16 | if (process.env.NODE_ENV == 'development') 17 | middleware.push(logger); 18 | 19 | const store = createStore(rootReducer, initialState, applyMiddleware(...middleware)); 20 | 21 | if (module.hot) 22 | module.hot.accept('../ducks', () => { 23 | const nextRootReducer = require('../ducks'); 24 | store.replaceReducer(nextRootReducer); 25 | }); 26 | 27 | return store; 28 | } 29 | -------------------------------------------------------------------------------- /src/styles.global.sss: -------------------------------------------------------------------------------- 1 | * 2 | box-sizing: border-box 3 | 4 | body 5 | -webkit-font-smoothing: antialiased 6 | font-family: 'Open Sans', sans-serif 7 | background: #fff 8 | 9 | a 10 | text-decoration: none 11 | outline: none 12 | 13 | fieldset 14 | border: 0 15 | margin: 0 16 | padding: 0 17 | 18 | textarea 19 | line-height: 1.6 20 | resize: vertical 21 | 22 | p 23 | color: inherit 24 | 25 | 26 | input::-webkit-outer-spin-button, 27 | input::-webkit-inner-spin-button 28 | -webkit-appearance: none 29 | margin: 0 30 | 31 | ::-webkit-file-upload-button 32 | cursor: pointer 33 | 34 | .medium-editor-element 35 | outline: none !important 36 | 37 | .start-working 38 | display: flex 39 | flex-flow: column nowrap 40 | justify-content: center 41 | align-items: center 42 | height: 100% 43 | font-size: 18px 44 | color: rgba(0,0,0,0.5) 45 | font-weight: 300 46 | user-select: none 47 | 48 | .hammer 49 | margin-right: 15px 50 | margin-bottom: 15px 51 | svg 52 | height: 47px 53 | 54 | .docs 55 | color: rgba(0,0,0,0.5) 56 | 57 | &-link 58 | color: #6D9EE1 59 | border-bottom: 1px #6D9EE1 solid 60 | 61 | .hint 62 | font-size: 14px 63 | margin-top: 14px 64 | 65 | .fade-exit 66 | position: absolute 67 | width: 100% 68 | 69 | .fade-enter 70 | position: relative 71 | width: 100% 72 | transform: translateX(50%) 73 | opacity: 0 74 | 75 | .fade-enter-active 76 | position: relative 77 | transition: transform .3s ease, opacity .3s ease 78 | transform: translateX(0) 79 | opacity: 1 80 | 81 | .fade-exit-active 82 | position: absolute 83 | top: 0 84 | transition: transform .3s ease, opacity .25s ease 85 | transform: translateX(-50%) 86 | opacity: 0 87 | -------------------------------------------------------------------------------- /src/utils/initialize.js: -------------------------------------------------------------------------------- 1 | import {Parse} from 'parse'; 2 | import {loadStripe} from '@stripe/stripe-js'; 3 | 4 | import {store} from 'index'; 5 | import {getLocalStorage} from 'ducks/user'; 6 | import {setStripePromise} from 'ducks/pay'; 7 | import {config as _config} from 'ConnectConstants'; 8 | import {send} from 'utils/server'; 9 | 10 | 11 | // loading config from ConnectConstants 12 | export const config = {..._config}; 13 | 14 | 15 | async function requestConfig() { 16 | //try to load config from process.env 17 | if (typeof process !== 'undefined' && process) { 18 | config.serverURL = process.env.REACT_APP_SERVER_URL || config.serverURL; 19 | config.appId = process.env.REACT_APP_APP_ID || config.appId; 20 | config.JSkey = process.env.JS_KEY || config.JSkey; 21 | config.RESTkey = process.env.REST_KEY || config.RESTkey; 22 | } 23 | 24 | //try to load config from local running 25 | try { 26 | const response = await fetch('/chisel-config.json'); 27 | const result = await response.json(); 28 | config.serverURL = result.configServerURL || config.serverURL; 29 | config.appId = result.configAppId || config.appId; 30 | config.JSkey = result.configJSkey || config.JSkey; 31 | config.RESTkey = result.configRESTkey || config.RESTkey; 32 | } catch (e) {} 33 | 34 | //try to load config from Electron 35 | try { 36 | const prefix = '--chisel-server='; 37 | const {argv} = window.process; 38 | for (let arg of argv) { 39 | if (arg.indexOf(prefix) == 0) { 40 | const result = JSON.parse(arg.substr(prefix.length)); 41 | 42 | config.serverURL = result.URL || config.serverURL; 43 | config.appId = result.appId || config.appId; 44 | config.JSkey = result.JSkey || config.JSkey; 45 | config.RESTkey = result.RESTkey || config.RESTkey; 46 | } 47 | } 48 | } catch (e) {} 49 | } 50 | 51 | async function initParse() { 52 | Parse.initialize(config.appId, config.JSkey); 53 | Parse.serverURL = config.serverURL; 54 | 55 | const appConfig = await send(Parse.Config.get()); 56 | if (appConfig) { 57 | const key = appConfig.get('StripeKeyPublic'); 58 | if (key) { 59 | config.stripeKeyExists = true; 60 | const stripePromise = loadStripe(key); 61 | store.dispatch(setStripePromise(stripePromise)); 62 | } 63 | } 64 | } 65 | 66 | export async function initApp() { 67 | await requestConfig(); 68 | await initParse(); 69 | store.dispatch(getLocalStorage()); 70 | } 71 | 72 | export function changeServerURL(URL) { 73 | if (!URL) 74 | return; 75 | 76 | config.serverURL = URL; 77 | localStorage.setItem('parseServerURL', URL); 78 | Parse.serverURL = URL; 79 | } 80 | -------------------------------------------------------------------------------- /src/utils/routing.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | useLocation, 4 | useNavigate, 5 | useNavigationType, 6 | useParams 7 | } from "react-router-dom"; 8 | 9 | 10 | export function withRouter(Component) { 11 | return props => { 12 | let location = useLocation(); 13 | let navigate = useNavigate(); 14 | let navigationType = useNavigationType(); 15 | let params = useParams(); 16 | return ( 17 | 21 | ); 22 | }; 23 | } -------------------------------------------------------------------------------- /static/assets/images/logo/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/static/assets/images/logo/apple-touch-icon.png -------------------------------------------------------------------------------- /static/assets/images/logo/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/static/assets/images/logo/logo192.png -------------------------------------------------------------------------------- /static/assets/images/logo/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/static/assets/images/logo/logo512.png -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beachio/chisel/113f33fe2fba0a9b0ffe9f9e45b164d5236408ff/static/favicon.ico -------------------------------------------------------------------------------- /static/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Chisel", 3 | "name": "Chisel", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "48x48 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "\/assets\/images\/logo\/logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "\/assets\/images\/logo\/logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /static/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | --------------------------------------------------------------------------------