├── .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 |
--------------------------------------------------------------------------------
/src/assets/images/arrow-down-full.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
45 |
--------------------------------------------------------------------------------
/src/assets/images/arrow-down.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/images/arrows.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/src/assets/images/hammer.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/images/icons/cross.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/images/icons/delete.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/images/icons/edit.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/images/icons/link.svg:
--------------------------------------------------------------------------------
1 |
2 |
13 |
--------------------------------------------------------------------------------
/src/assets/images/icons/lock.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/images/icons/plus.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/images/icons/search.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/images/icons/sidebar.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/images/icons/users.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/images/media-types/archive.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
37 |
--------------------------------------------------------------------------------
/src/assets/images/media-types/exe.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
46 |
--------------------------------------------------------------------------------
/src/assets/images/media-types/html.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
45 |
--------------------------------------------------------------------------------
/src/assets/images/media-types/other.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
42 |
--------------------------------------------------------------------------------
/src/assets/images/media-types/xml.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
45 |
--------------------------------------------------------------------------------
/src/assets/images/media-types/zip.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
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 |
8 |
--------------------------------------------------------------------------------
/src/assets/images/product-logo-b.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/images/product-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
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 |
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 |
--------------------------------------------------------------------------------
/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 |
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 |
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 |
--------------------------------------------------------------------------------
/src/components/sidebar/User/avatar.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
54 |
--------------------------------------------------------------------------------
/src/components/sidebar/User/logout.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
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 |
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 |
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 |
--------------------------------------------------------------------------------