├── .github ├── FUNDING.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── snipsnap-templates-frontend.yml │ ├── snipsnap-templates-graphql.yml │ └── snipsnap-templates-vscode.yml ├── .gitignore ├── LICENSE ├── README.md ├── snippets ├── .drone.yml ├── README.md └── collections │ └── javascript │ ├── angular │ └── angular.json │ ├── axios │ └── axios.json │ ├── base │ └── base.json │ ├── classnames │ └── classnames.json │ ├── cypress │ └── cypress.json │ ├── dotenv-safe │ └── dotenv-safe.json │ ├── dotenv │ └── dotenv.json │ ├── framer-motion │ └── framer-motion.json │ ├── gatsby-image │ └── gatsby-image.json │ ├── gatsby │ └── gatsby.json │ ├── graphql-request │ └── graphql-request.json │ ├── jest │ └── jest.json │ ├── lodash │ └── lodash.json │ ├── next │ └── next.json │ ├── nuxt │ └── nuxt.json │ ├── prop-types │ └── prop-types.json │ ├── react-helmet │ └── react-helmet.json │ ├── react-intersection-observer │ └── react-intersection-observer.json │ ├── react-modal │ └── react-modal.json │ ├── react │ └── react.json │ ├── redux-thunk │ └── redux-thunk.json │ ├── redux │ └── redux.json │ ├── styled-components │ └── styled-components.json │ ├── svelte │ └── svelte.json │ ├── vue │ └── vue.json │ ├── vuex │ └── vuex.json │ └── yup │ └── yup.json └── templates ├── ARCHITECTURE.md ├── README.md ├── contributing.md ├── docker-compose.arm64.yml ├── docker-compose.yml ├── docs └── use-cases.md ├── frontend ├── .commitlintrc.json ├── .dockerignore ├── .env.example ├── .eslintrc.js ├── .gitignore ├── .husky │ ├── .gitignore │ ├── commit-msg │ └── pre-commit ├── .lintstagedrc ├── .prettierignore ├── .prettierrc ├── .stylelintrc ├── Dockerfile.prod ├── README.md ├── jsconfig.json ├── next.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.png │ ├── favicon.svg │ ├── fonts │ │ ├── inter-v3-latin-300.woff │ │ ├── inter-v3-latin-300.woff2 │ │ ├── inter-v3-latin-500.woff │ │ ├── inter-v3-latin-500.woff2 │ │ ├── inter-v3-latin-regular.woff │ │ └── inter-v3-latin-regular.woff2 │ ├── images │ │ ├── empty-box-illustration.png │ │ ├── github-illustration.png │ │ ├── marketplace-illustration.png │ │ ├── peace.png │ │ ├── rock.png │ │ └── templates-illustration.png │ ├── logo-white.png │ ├── social-media.jpg │ ├── vercel.svg │ └── videos │ │ └── demo.mp4 ├── sentry.client.config.js ├── sentry.server.config.js └── src │ ├── api │ ├── graphql.js │ ├── mutations.js │ └── queries.js │ ├── components │ ├── pages │ │ ├── collection │ │ │ ├── collection.jsx │ │ │ ├── collection.module.scss │ │ │ ├── images │ │ │ │ └── reactjs.inline.svg │ │ │ └── index.js │ │ ├── create-template │ │ │ ├── create-template.jsx │ │ │ └── index.js │ │ ├── edit-template │ │ │ ├── edit-template.jsx │ │ │ └── index.js │ │ ├── home │ │ │ ├── home.jsx │ │ │ ├── home.module.scss │ │ │ ├── index.js │ │ │ └── steps │ │ │ │ ├── index.js │ │ │ │ ├── steps.jsx │ │ │ │ └── steps.module.scss │ │ ├── login │ │ │ ├── images │ │ │ │ ├── github.inline.svg │ │ │ │ ├── logo-text.inline.svg │ │ │ │ └── play.inline.svg │ │ │ ├── index.js │ │ │ ├── login.jsx │ │ │ └── login.module.scss │ │ ├── marketplace │ │ │ ├── community-templates │ │ │ │ ├── community-templates.jsx │ │ │ │ ├── community-templates.module.scss │ │ │ │ ├── index.js │ │ │ │ ├── items │ │ │ │ │ ├── empty-items │ │ │ │ │ │ ├── empty-items.jsx │ │ │ │ │ │ ├── empty-items.module.scss │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── items.jsx │ │ │ │ │ └── items.module.scss │ │ │ │ └── search │ │ │ │ │ ├── index.js │ │ │ │ │ ├── search.jsx │ │ │ │ │ └── search.module.scss │ │ │ ├── curated-collections │ │ │ │ ├── curated-collections.jsx │ │ │ │ ├── curated-collections.module.scss │ │ │ │ ├── index.js │ │ │ │ └── items │ │ │ │ │ ├── images │ │ │ │ │ ├── docker.inline.svg │ │ │ │ │ ├── kubernetes.inline.svg │ │ │ │ │ ├── nodejs.inline.svg │ │ │ │ │ ├── reactjs.inline.svg │ │ │ │ │ └── tailwindui.inline.svg │ │ │ │ │ ├── index.js │ │ │ │ │ ├── items.jsx │ │ │ │ │ └── items.module.scss │ │ │ ├── index.js │ │ │ ├── marketplace.jsx │ │ │ └── marketplace.module.scss │ │ ├── preview-template │ │ │ ├── images │ │ │ │ ├── cursor.inline.svg │ │ │ │ ├── download.inline.svg │ │ │ │ └── vscode.inline.svg │ │ │ ├── index.js │ │ │ ├── preview-template.jsx │ │ │ ├── preview-template.module.scss │ │ │ └── vscode-animation │ │ │ │ ├── folder-menu │ │ │ │ ├── folder-menu.jsx │ │ │ │ ├── folder-menu.module.scss │ │ │ │ └── index.js │ │ │ │ ├── index.js │ │ │ │ ├── prompt-input │ │ │ │ ├── index.js │ │ │ │ ├── prompt-input.jsx │ │ │ │ └── prompt-input.module.scss │ │ │ │ ├── template-select │ │ │ │ ├── index.js │ │ │ │ ├── template-select.jsx │ │ │ │ └── template-select.module.scss │ │ │ │ ├── vscode-animation.jsx │ │ │ │ ├── vscode-animation.module.scss │ │ │ │ └── vscode-layout │ │ │ │ ├── images │ │ │ │ ├── activity-bar-bottom.inline.svg │ │ │ │ ├── activity-bar-top.inline.svg │ │ │ │ ├── empty-editor.inline.svg │ │ │ │ ├── footer-left.inline.svg │ │ │ │ ├── footer-right.inline.svg │ │ │ │ ├── showcase.inline.svg │ │ │ │ └── top-left-icons.inline.svg │ │ │ │ ├── index.js │ │ │ │ ├── vscode-layout.jsx │ │ │ │ ├── vscode-layout.module.scss │ │ │ │ └── vscode-sidebar │ │ │ │ ├── index.js │ │ │ │ ├── vscode-sidebar.jsx │ │ │ │ └── vscode-sidebar.module.scss │ │ └── view-template │ │ │ ├── index.js │ │ │ └── view-template.jsx │ └── shared │ │ ├── async-button │ │ ├── async-button.jsx │ │ ├── async-button.module.scss │ │ └── index.js │ │ ├── avatar │ │ ├── avatar.jsx │ │ ├── avatar.module.scss │ │ └── index.js │ │ ├── button │ │ ├── button.jsx │ │ ├── button.module.scss │ │ ├── images │ │ │ ├── loader.inline.svg │ │ │ └── success.inline.svg │ │ └── index.js │ │ ├── create-template-group-modal │ │ ├── create-template-group-modal.jsx │ │ ├── create-template-group-modal.module.scss │ │ └── index.js │ │ ├── delete-group-modal │ │ ├── delete-group-modal.jsx │ │ ├── delete-group-modal.module.scss │ │ └── index.js │ │ ├── delete-template-modal │ │ ├── delete-template-modal.jsx │ │ ├── delete-template-modal.module.scss │ │ └── index.js │ │ ├── dropdown │ │ ├── dropdown.jsx │ │ ├── dropdown.module.scss │ │ ├── index.js │ │ └── menu │ │ │ ├── index.js │ │ │ ├── menu.jsx │ │ │ └── menu.module.scss │ │ ├── editor-wrapper │ │ ├── editor-wrapper.jsx │ │ ├── editor-wrapper.module.scss │ │ └── index.js │ │ ├── editor │ │ ├── editor.jsx │ │ ├── editor.module.scss │ │ └── index.js │ │ ├── error-modal │ │ ├── error-modal.jsx │ │ ├── error-modal.module.scss │ │ └── index.js │ │ ├── file-browser │ │ ├── add-file-modal │ │ │ ├── add-file-modal.jsx │ │ │ ├── add-file-modal.module.scss │ │ │ └── index.js │ │ ├── add-folder-modal │ │ │ ├── add-folder-modal.jsx │ │ │ ├── add-folder-modal.module.scss │ │ │ └── index.js │ │ ├── delete-file-modal │ │ │ ├── delete-file-modal.jsx │ │ │ ├── delete-file-modal.module.scss │ │ │ └── index.js │ │ ├── delete-folder-modal │ │ │ ├── delete-folder-modal.jsx │ │ │ ├── delete-folder-modal.module.scss │ │ │ └── index.js │ │ ├── file-browser.jsx │ │ ├── file-browser.module.scss │ │ ├── file │ │ │ ├── file.jsx │ │ │ ├── file.module.scss │ │ │ └── index.js │ │ ├── folder │ │ │ ├── folder.jsx │ │ │ ├── folder.module.scss │ │ │ └── index.js │ │ ├── images │ │ │ └── file.inline.svg │ │ ├── index.js │ │ ├── rename-item-modal │ │ │ ├── index.js │ │ │ ├── rename-item-modal.jsx │ │ │ └── rename-item-modal.module.scss │ │ └── tree-recursive │ │ │ ├── index.js │ │ │ ├── tree-recursive.jsx │ │ │ └── tree-recursive.module.scss │ │ ├── icon-button │ │ ├── icon-button.jsx │ │ ├── icon-button.module.scss │ │ ├── icons │ │ │ └── plus.inline.svg │ │ └── index.js │ │ ├── input │ │ ├── index.js │ │ ├── input.jsx │ │ └── input.module.scss │ │ ├── layout │ │ ├── index.js │ │ ├── layout.jsx │ │ └── layout.module.scss │ │ ├── modal-portal │ │ ├── index.js │ │ ├── modal-portal.jsx │ │ └── modal-portal.module.scss │ │ ├── modal │ │ ├── index.js │ │ ├── modal.jsx │ │ └── modal.module.scss │ │ ├── rename-group-modal │ │ ├── index.js │ │ ├── rename-group-modal.jsx │ │ └── rename-group-modal.module.scss │ │ ├── share-modal │ │ ├── index.js │ │ ├── share-modal.jsx │ │ └── share-modal.module.scss │ │ ├── sidebar │ │ ├── authorised-sidebar │ │ │ ├── authorised-sidebar.jsx │ │ │ ├── authorised-sidebar.module.scss │ │ │ ├── index.js │ │ │ └── templates-groups-tree │ │ │ │ ├── index.js │ │ │ │ ├── template-group-item │ │ │ │ ├── images │ │ │ │ │ └── files.inline.svg │ │ │ │ ├── index.js │ │ │ │ ├── template-group-item.jsx │ │ │ │ └── template-group-item.module.scss │ │ │ │ ├── template-item │ │ │ │ ├── index.js │ │ │ │ ├── template-item.jsx │ │ │ │ └── template-item.module.scss │ │ │ │ ├── templates-groups-tree.jsx │ │ │ │ └── templates-groups-tree.module.scss │ │ ├── index.js │ │ ├── sidebar.jsx │ │ └── unauthorised-sidebar │ │ │ ├── images │ │ │ ├── github.inline.svg │ │ │ ├── logo-text.inline.svg │ │ │ └── play.inline.svg │ │ │ ├── index.js │ │ │ ├── unauthorised-sidebar.jsx │ │ │ └── unauthorised-sidebar.module.scss │ │ ├── support-us │ │ ├── index.js │ │ ├── support-us.jsx │ │ └── support-us.module.scss │ │ ├── switch │ │ ├── index.js │ │ ├── switch.jsx │ │ └── switch.module.scss │ │ ├── template-form │ │ ├── files │ │ │ ├── files.jsx │ │ │ ├── files.module.scss │ │ │ └── index.js │ │ ├── index.js │ │ ├── prompts │ │ │ ├── index.js │ │ │ ├── prompts-read-only.jsx │ │ │ ├── prompts.jsx │ │ │ └── prompts.module.scss │ │ ├── template-form.jsx │ │ ├── template-form.module.scss │ │ └── view-only-form.jsx │ │ ├── tooltip │ │ ├── index.js │ │ ├── tooltip.jsx │ │ └── tooltip.module.scss │ │ ├── unshare-modal │ │ ├── index.js │ │ ├── unshare-modal.jsx │ │ └── unshare-modal.module.scss │ │ ├── use-cases │ │ ├── index.js │ │ ├── use-cases.jsx │ │ └── use-cases.module.scss │ │ └── video-player │ │ ├── index.js │ │ ├── video-player.jsx │ │ └── video-player.module.scss │ ├── contexts │ ├── app-context.js │ ├── error-modal-context.jsx │ ├── files-provider.jsx │ ├── open-groups-context.jsx │ └── template-groups-provider.jsx │ ├── db │ └── models │ │ └── user.js │ ├── hooks │ ├── use-alert-if-unsaved-changes.js │ ├── use-outside-click.js │ ├── use-session.js │ └── use-token.js │ ├── icons │ ├── arrow-down-larger.inline.svg │ ├── arrow-down.inline.svg │ ├── arrow-right.inline.svg │ ├── arrow.inline.svg │ ├── close.inline.svg │ ├── dots.inline.svg │ ├── file-types │ │ ├── default_file.inline.svg │ │ ├── file_type_css.inline.svg │ │ ├── file_type_go.inline.svg │ │ ├── file_type_html.inline.svg │ │ ├── file_type_java.inline.svg │ │ ├── file_type_js.inline.svg │ │ ├── file_type_json.inline.svg │ │ ├── file_type_less.inline.svg │ │ ├── file_type_markdown.inline.svg │ │ ├── file_type_python.inline.svg │ │ ├── file_type_reactjs.inline.svg │ │ ├── file_type_ruby.inline.svg │ │ ├── file_type_sass.inline.svg │ │ ├── file_type_typescript.inline.svg │ │ └── file_type_yaml.inline.svg │ ├── folder.inline.svg │ ├── group.inline.svg │ ├── home.inline.svg │ ├── marketplace.inline.svg │ ├── plus.inline.svg │ ├── search.inline.svg │ ├── star.inline.svg │ ├── template.inline.svg │ └── triangle.inline.svg │ ├── pages │ ├── _app.js │ ├── _document.js │ ├── api │ │ └── auth │ │ │ ├── [...nextauth].js │ │ │ └── token.js │ ├── create-template.jsx │ ├── index.jsx │ ├── login.jsx │ ├── marketplace │ │ ├── [collectionSlug].jsx │ │ └── index.jsx │ └── templates │ │ └── [templateId] │ │ ├── edit.jsx │ │ ├── index.jsx │ │ └── preview.jsx │ ├── styles │ ├── fonts.scss │ ├── globals.scss │ ├── mixins.scss │ ├── reset.css │ └── variables.scss │ └── utils │ ├── files-provider-helpers.js │ ├── generate-page-title.js │ ├── generate-token.js │ ├── jwt.js │ ├── language.js │ └── with-auth.js ├── graphql ├── .env.example ├── .gitignore ├── Dockerfile.prod ├── README.md ├── api │ └── client.js ├── index.js ├── package-lock.json ├── package.json ├── template │ ├── index.js │ ├── mutations.js │ ├── queries.js │ └── resolvers │ │ ├── create-template.js │ │ ├── share-template-group.js │ │ ├── share-template.js │ │ ├── unshare-template-from-current-user.js │ │ ├── unshare-template-group-from-current-user.js │ │ ├── unshare-template-group.js │ │ ├── unshare-template.js │ │ └── update-template.js ├── type-defs │ └── index.js └── utils │ ├── helpers.js │ ├── jwt.js │ └── validation.js ├── hasura ├── README.md ├── config.yaml ├── metadata │ ├── actions.graphql │ ├── actions.yaml │ ├── allow_list.yaml │ ├── cron_triggers.yaml │ ├── functions.yaml │ ├── inherited_roles.yaml │ ├── query_collections.yaml │ ├── remote_schemas.yaml │ ├── rest_endpoints.yaml │ ├── tables.yaml │ └── version.yaml └── migrations │ ├── 1608498837990_create-next-auth-db-structure │ └── up.sql │ ├── 1608498904695_alter_table_public_users_drop_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1608498925549_alter_table_public_users_add_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1608498940552_alter_table_public_users_alter_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1608498978601_alter_table_public_sessions_drop_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1608498987762_alter_table_public_sessions_add_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1608498999053_alter_table_public_verification_requests_drop_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1608499010093_alter_table_public_verification_requests_add_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1608499026741_alter_table_public_accounts_drop_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1608499034426_alter_table_public_accounts_add_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1609153789911_create_table_public_templates_groups │ ├── down.sql │ └── up.sql │ ├── 1609154010226_alter_table_public_users_add_column_user_id │ ├── down.sql │ └── up.sql │ ├── 1609154610501_set_fk_public_templates_groups_user_id │ ├── down.sql │ └── up.sql │ ├── 1609158469483_create_table_public_templates │ ├── down.sql │ └── up.sql │ ├── 1609158514185_set_fk_public_templates_owner_id │ ├── down.sql │ └── up.sql │ ├── 1609158677189_set_fk_public_templates_template_group_id │ ├── down.sql │ └── up.sql │ ├── 1609159121201_create_table_public_users_templates_groups │ ├── down.sql │ └── up.sql │ ├── 1609187948640_create_function_create_default_templates_group │ └── up.sql │ ├── 1609188010618_create_trigger_on_insert_user │ └── up.sql │ ├── 1609188422836_alter_table_public_users_templates_groups_alter_column_template_group_id │ ├── down.sql │ └── up.sql │ ├── 1609188510635_create_function_data_from_templates_groups_to_users_templates_groups │ └── up.sql │ ├── 1609188624891_create_trigger_on_insert_templates_group │ └── up.sql │ ├── 1609233908156_set_fk_public_users_templates_groups_templates_group_id │ ├── down.sql │ └── up.sql │ ├── 1609234052981_set_fk_public_templates_template_group_id │ ├── down.sql │ └── up.sql │ ├── 1614775566836_create_table_public_api_keys │ ├── down.sql │ └── up.sql │ ├── 1615056193509_alter_table_public_templates_alter_column_template_group_id │ ├── down.sql │ └── up.sql │ ├── 1615056239344_alter_table_public_templates_alter_column_prompts │ ├── down.sql │ └── up.sql │ ├── 1615059849317_create_table_public_shared_templates │ ├── down.sql │ └── up.sql │ ├── 1615108851148_create_table_public_user_available_templates │ ├── down.sql │ └── up.sql │ ├── 1615108908703_set_fk_public_user_available_templates_template_id │ ├── down.sql │ └── up.sql │ ├── 1615108942283_set_fk_public_user_available_templates_available_for_user_id │ ├── down.sql │ └── up.sql │ ├── 1615109021920_alter_table_public_shared_templates_update_comment │ ├── down.sql │ └── up.sql │ ├── 1615114776546_trigger_create_user_available_template │ └── up.sql │ ├── 1615114910241_set_fk_public_user_available_templates_template_id │ ├── down.sql │ └── up.sql │ ├── 1615114970698_set_fk_public_user_available_templates_available_for_user_id │ ├── down.sql │ └── up.sql │ ├── 1615115175138_alter_table_public_shared_templates_alter_column_share_to_user_id │ ├── down.sql │ └── up.sql │ ├── 1615115224674_trigger_create_user_available_template_when_shared_template_created │ ├── down.sql │ └── up.sql │ ├── 1615116569122_drop_outdated_triggers │ └── up.sql │ ├── 1615116613743_drop_table_public_users_templates_groups │ └── up.sql │ ├── 1615116630052_rename_table_public_templates_groups │ ├── down.sql │ └── up.sql │ ├── 1615116654166_alter_table_public_template_groups_alter_column_user_id │ ├── down.sql │ └── up.sql │ ├── 1615116738770_alter_table_public_shared_templates_alter_column_shared_by_user_ud │ ├── down.sql │ └── up.sql │ ├── 1615116962270_create_table_public_shared_template_groups │ ├── down.sql │ └── up.sql │ ├── 1615117149044_create_table_public_user_available_template_groups │ ├── down.sql │ └── up.sql │ ├── 1615117168001_alter_table_public_user_available_templates_add_column_created_at │ ├── down.sql │ └── up.sql │ ├── 1615117172993_alter_table_public_user_available_templates_add_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1615117198684_alter_table_public_shared_templates_add_column_created_at │ ├── down.sql │ └── up.sql │ ├── 1615117203505_alter_table_public_shared_templates_add_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1615117215499_alter_table_public_shared_template_groups_add_column_created_at │ ├── down.sql │ └── up.sql │ ├── 1615117220654_alter_table_public_shared_template_groups_add_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1615117599372_create_user_available_template_group_when_shared_template_group_created │ └── up.sql │ ├── 1615117752707_create_user_available_template_group_when_template_group_created │ └── up.sql │ ├── 1615136669100_set_fk_public_template_groups_owner_id │ ├── down.sql │ └── up.sql │ ├── 1615138218834_set_fk_public_sessions_user_id │ ├── down.sql │ └── up.sql │ ├── 1615138275788_set_fk_public_accounts_user_id │ ├── down.sql │ └── up.sql │ ├── 1615140447976_set_fk_public_api_keys_user_id │ ├── down.sql │ └── up.sql │ ├── 1617966279753_alter_table_public_user_available_templates_add_column_favourite │ ├── down.sql │ └── up.sql │ ├── 1619104759383_alter_table_public_template_groups_alter_column_name │ ├── down.sql │ └── up.sql │ ├── 1619105097796_alter_table_public_templates_add_column_is_public │ ├── down.sql │ └── up.sql │ ├── 1619357886606_trigger_handle_shared_templates │ ├── down.sql │ └── up.sql │ ├── 1620400461553_set_fk_public_shared_templates_template_id │ ├── down.sql │ └── up.sql │ ├── 1620400497392_set_fk_public_user_available_template_groups_template_group_id │ ├── down.sql │ └── up.sql │ ├── 1620908524916_set_fk_public_templates_owner_id │ ├── down.sql │ └── up.sql │ ├── 1621932219028_create_trigger_handle_insert_and_delete_shared_template_groups │ ├── down.sql │ └── up.sql │ ├── 1621936832456_create_stats_hypertable │ ├── down.sql │ └── up.sql │ ├── 1621954247617_run_sql_migration │ ├── down.sql │ └── up.sql │ ├── 1623157071109_create_table_public_curated_template │ ├── down.sql │ └── up.sql │ ├── 1623157114122_alter_table_public_curated_template_add_column_template_id │ ├── down.sql │ └── up.sql │ ├── 1623157262093_rename_table_public_curated_template │ ├── down.sql │ └── up.sql │ ├── 1623157287619_create_table_public_curated_template_groups │ ├── down.sql │ └── up.sql │ ├── 1623157351985_alter_table_public_curated_templates_add_column_curated_template_group_id │ ├── down.sql │ └── up.sql │ ├── 1623157409530_alter_table_public_curated_template_groups_add_column_name │ ├── down.sql │ └── up.sql │ ├── 1623157422704_alter_table_public_curated_template_groups_add_column_description │ ├── down.sql │ └── up.sql │ ├── 1623157630741_alter_table_public_curated_template_groups_add_column_image_name │ ├── down.sql │ └── up.sql │ ├── 1623158827414_alter_table_public_curated_templates_drop_column_name │ ├── down.sql │ └── up.sql │ ├── 1623158839057_alter_table_public_curated_templates_drop_column_description │ ├── down.sql │ └── up.sql │ ├── 1623158884909_alter_table_public_curated_templates_add_column_created_at │ ├── down.sql │ └── up.sql │ ├── 1623158895373_alter_table_public_curated_templates_add_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1623158942657_set_fk_public_curated_templates_curated_template_group_id │ ├── down.sql │ └── up.sql │ ├── 1623158975996_alter_table_public_curated_templates_alter_column_curated_template_group_id │ ├── down.sql │ └── up.sql │ ├── 1623159029634_set_fk_public_curated_templates_template_id │ ├── down.sql │ └── up.sql │ ├── 1623159140846_alter_table_public_templates_add_column_description │ ├── down.sql │ └── up.sql │ ├── 1623159244459_alter_table_public_curated_template_groups_add_column_slug │ ├── down.sql │ └── up.sql │ ├── 1623159254746_alter_table_public_curated_template_groups_add_column_created_at │ ├── down.sql │ └── up.sql │ ├── 1623159262433_alter_table_public_curated_template_groups_add_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1623159414285_alter_table_public_curated_template_groups_alter_column_id │ ├── down.sql │ └── up.sql │ ├── 1623159422833_alter_table_public_curated_templates_alter_column_id │ ├── down.sql │ └── up.sql │ ├── 1623159471731_alter_table_public_curated_template_groups_alter_column_created_at │ ├── down.sql │ └── up.sql │ ├── 1623159477313_alter_table_public_curated_template_groups_alter_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1623159485027_alter_table_public_curated_templates_alter_column_created_at │ ├── down.sql │ └── up.sql │ ├── 1623159489146_alter_table_public_curated_templates_alter_column_updated_at │ ├── down.sql │ └── up.sql │ ├── 1623160224994_alter_table_public_curated_template_groups_alter_column_slug │ ├── down.sql │ └── up.sql │ ├── 1623162308963_set_fk_public_curated_templates_template_id │ ├── down.sql │ └── up.sql │ ├── 1623162377189_set_fk_public_curated_templates_template_id │ ├── down.sql │ └── up.sql │ └── 1623162380335_set_fk_public_curated_templates_curated_template_group_id │ ├── down.sql │ └── up.sql └── vscode-extension ├── .eslintrc.json ├── .gitignore ├── .vscode ├── extensions.json └── launch.json ├── .vscodeignore ├── CHANGELOG.md ├── README.md ├── jsconfig.json ├── package-lock.json ├── package.json ├── snipsnap-logo.png ├── src ├── _constants │ └── index.js ├── api │ └── index.js ├── commands │ ├── index.js │ └── run-extension.js ├── extension.js └── utils │ └── index.js ├── test ├── runTest.js └── suite │ ├── extension.test.js │ └── index.js └── vsc-extension-quickstart.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: snipsnapdev 2 | -------------------------------------------------------------------------------- /.github/workflows/snipsnap-templates-vscode.yml: -------------------------------------------------------------------------------- 1 | name: snipsnap-templates-vscode 2 | 3 | on: 4 | push: 5 | tags: 6 | - "snipsnap-templates-vscode@*" 7 | 8 | # Allows you to run this workflow manually from the Actions tab 9 | workflow_dispatch: 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | env: 15 | WORKING_DIRECTORY: ./templates/vscode-extension/ 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Install Dependencies 19 | run: npm install 20 | working-directory: ${{env.WORKING_DIRECTORY}} 21 | - name: Package Extension 22 | run: npm run package 23 | working-directory: ${{env.WORKING_DIRECTORY}} 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # misc 7 | .DS_Store 8 | *.pem 9 | 10 | # debug 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # local env files 16 | .env 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | # vercel 23 | .vercel 24 | .vscode/snipsnap.code-snippets 25 | 26 | #linters 27 | .stylelintcache 28 | .eslintcache 29 | 30 | tmp 31 | 32 | prisma/.env 33 | 34 | sentry.properties 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | Snipsnap Logo

4 |

Snipsnap Templates

5 |

Speed up your development with a powerful set of tools

6 | 7 | ### Snipsnap Templates 8 | Manage, share and use code templates with cloud UI and VS Code Extension 9 | 10 | [Read more](https://github.com/snipsnapdev/snipsnap/tree/master/templates) 11 | 12 | ![snipsnap-templates-demo](https://user-images.githubusercontent.com/2697570/119970573-30466080-bfb0-11eb-9455-21c5d7e2561e.gif) 13 | 14 | ### Snipsnap Code Snippets 15 | The ultimate snippets collection and VS Code extension that automatically exposes all available snippets for every library you are using in your project. 16 | 17 | [Read more](https://github.com/snipsnapdev/snipsnap/tree/master/snippets) 18 | 19 | ![snipsnap-snippets-demo](https://user-images.githubusercontent.com/2697570/73568644-23bc0180-4469-11ea-8b64-843c7a9a92d2.gif) 20 | -------------------------------------------------------------------------------- /snippets/collections/javascript/classnames/classnames.json: -------------------------------------------------------------------------------- 1 | { 2 | "classnames-usage": { 3 | "scope": "javascript,javascriptreact,typescript,typescriptreact", 4 | "prefix": ["classnames usage"], 5 | "body": ["${1:classNames}('${2:foo}', '${3:bar}');"] 6 | }, 7 | "classnames-usage-object": { 8 | "scope": "javascript,javascriptreact,typescript,typescriptreact", 9 | "prefix": ["classnames usage object"], 10 | "body": ["${1:classNames}({ '${2:foo-bar}': true });"] 11 | }, 12 | "classnames-import-bind": { 13 | "scope": "javascript,javascriptreact,typescript,typescriptreact", 14 | "prefix": ["classnames import bind"], 15 | "body": ["import ${1:classNames} from 'classnames/bind';"] 16 | }, 17 | "classnames-bind-usage": { 18 | "scope": "javascript,javascriptreact,typescript,typescriptreact", 19 | "prefix": ["classnames bind usage"], 20 | "body": ["const ${1:cx} = ${2:classNames}.bind(styles);"] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /snippets/collections/javascript/dotenv/dotenv.json: -------------------------------------------------------------------------------- 1 | { 2 | "dotenv-require": { 3 | "scope": "javascript,typescript", 4 | "prefix": ["dotenv require"], 5 | "body": ["require('dotenv').config()"], 6 | "description": "As early as possible in your application, require and configure dotenv." 7 | }, 8 | "dotenv-path": { 9 | "scope": "javascript,typescript", 10 | "prefix": ["dotenv path"], 11 | "body": [ 12 | "require('dotenv').config({ path: '${1:/full/custom/path/to/your/env/vars}' })" 13 | ], 14 | "description": "You may specify a custom path if your file containing environment variables is located elsewhere." 15 | }, 16 | "dotenv-encoding": { 17 | "scope": "javascript,typescript", 18 | "prefix": ["dotenv encoding"], 19 | "body": ["require('dotenv').config({ encoding: '${1:latin1}' })"], 20 | "description": "You may specify the encoding of your file containing environment variables." 21 | }, 22 | "dotenv-debug": { 23 | "scope": "javascript,typescript", 24 | "prefix": ["dotenv debug"], 25 | "body": ["require('dotenv').config({ debug: ${1|true,false|} })"], 26 | "description": "You may turn on logging to help debug why certain keys or values are not being set as you expect." 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /snippets/collections/javascript/react-helmet/react-helmet.json: -------------------------------------------------------------------------------- 1 | { 2 | "react-helmet-import": { 3 | "prefix": ["react-helmet import"], 4 | "body": ["import { Helmet } from 'react-helmet';"], 5 | "scope": "javascript,javascriptreact,typescript,typescriptreact" 6 | }, 7 | "react-helmet-title": { 8 | "prefix": ["react-helmet title"], 9 | "body": ["", " ${1:title}", ""], 10 | "scope": "javascript,javascriptreact,typescript,typescriptreact" 11 | }, 12 | "react-helmet-component": { 13 | "prefix": ["react-helmet component"], 14 | "body": ["", "${1:example}", ""], 15 | "scope": "javascript,javascriptreact,typescript,typescriptreact" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /snippets/collections/javascript/redux-thunk/redux-thunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "redux-thunk-import": { 3 | "prefix": ["redux-thunk import"], 4 | "body": ["import thunk from 'redux-thunk'"], 5 | "scope": "javascript,javascriptreact,typescript,typescriptreact", 6 | "description": "Import thunk from redux-thunk" 7 | }, 8 | "redux-thunk-store": { 9 | "prefix": ["redux-thunk createstore"], 10 | "body": [ 11 | "import { createStore, applyMiddleware } from 'redux';", 12 | "import thunk from 'redux-thunk';", 13 | "import ${1:rootReducer} from '${1:./reducers/index}';", 14 | "", 15 | "const store = createStore(", 16 | " ${1:rootReducer},", 17 | " applyMiddleware(thunk)", 18 | ");" 19 | ], 20 | "scope": "javascript,javascriptreact,typescript,typescriptreact", 21 | "description": "Create store with thunk template" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /templates/docker-compose.arm64.yml: -------------------------------------------------------------------------------- 1 | services: 2 | graphql-engine: 3 | image: fedormelexin/graphql-engine-arm64:v2.0.1 4 | -------------------------------------------------------------------------------- /templates/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.6' 2 | services: 3 | postgres: 4 | image: timescale/timescaledb:2.2.1-pg12 5 | restart: always 6 | ports: 7 | - 8433:5432 8 | volumes: 9 | - ./tmp/db:/var/lib/postgresql/data 10 | environment: 11 | POSTGRES_PASSWORD: postgrespassword 12 | graphql-engine: 13 | image: hasura/graphql-engine:v2.0.0-alpha.9 14 | ports: 15 | - '3010:8080' 16 | depends_on: 17 | - 'postgres' 18 | restart: always 19 | environment: 20 | HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres 21 | HASURA_GRAPHQL_ENABLE_CONSOLE: 'false' 22 | HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log 23 | HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey 24 | HASURA_GRAPHQL_UNAUTHORIZED_ROLE: guest 25 | HASURA_GRAPHQL_JWT_SECRET: '{"type":"HS512","key":"eyJrdHkiOiJvY3QiLCJraWQiOiJ1WG5Ub21VaDcwVm15V0U4RmVoR0tpX2JWaTk2UEtSejExWUVTUEV2cWdNdVhuVG9tVWg3MFZteVdFOEZlaEdLaV9iVmk5NlBLUnoxMVlFU1BFdnFnTSIsImFsZyI6IkhTNTEyIiwiayI6IjMwOXFTY3JfSE1FYk"}' 26 | HASURA_GRAPHQL_ENABLE_REMOTE_SCHEMA_PERMISSIONS: 'true' 27 | REMOTE_SCHEMA_URL: http://host.docker.internal:4000/ 28 | -------------------------------------------------------------------------------- /templates/frontend/.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@commitlint/config-conventional"], 3 | "rules": { 4 | "scope-enum": [ 5 | 2, 6 | "always", 7 | [ 8 | "components", 9 | "constants", 10 | "hooks", 11 | "icons", 12 | "images", 13 | "layouts", 14 | "pages", 15 | "styles", 16 | "templates", 17 | "utils" 18 | ] 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /templates/frontend/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | Dockerfile* 4 | docker-compose* 5 | .dockerignore 6 | .git 7 | .gitignore 8 | README.md 9 | LICENSE 10 | .vscode -------------------------------------------------------------------------------- /templates/frontend/.env.example: -------------------------------------------------------------------------------- 1 | DATABASE_URL="postgres://postgres:postgrespassword@localhost:8433/postgres?schema=public" 2 | GITHUB_CLIENT_ID=f72f5e6090032cb78916 3 | GITHUB_CLIENT_SECRET=4337253b93ae24a3337ff245264167a9472c18b8 4 | NEXTAUTH_URL=http://localhost:3000 5 | JWT_SECRET=eyJrdHkiOiJvY3QiLCJraWQiOiJ1WG5Ub21VaDcwVm15V0U4RmVoR0tpX2JWaTk2UEtSejExWUVTUEV2cWdNdVhuVG9tVWg3MFZteVdFOEZlaEdLaV9iVmk5NlBLUnoxMVlFU1BFdnFnTSIsImFsZyI6IkhTNTEyIiwiayI6IjMwOXFTY3JfSE1FYk 6 | NEXT_PUBLIC_SITE_URL=http://localhost:3000 7 | NEXT_PUBLIC_GRAPHQL_URL=http://localhost:3010/v1/graphql 8 | HASURA_ADMIN_SECRET=myadminsecretkey 9 | # Number in seconds 60 * 60 = 1 hour 10 | JWT_API_MAX_AGE=3600 11 | 12 | # Sentry - production only 13 | SENTRY_ENABLED=true 14 | SENTRY_ENVIRONMENT=production 15 | NEXT_PUBLIC_SENTRY_DSN= 16 | SENTRY_URL=https://sentry.io/ 17 | SENTRY_ORG=pixel-point-ip 18 | SENTRY_PROJECT=snipsnap-templates-frontend 19 | SENTRY_AUTH_TOKEN= -------------------------------------------------------------------------------- /templates/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env 29 | .env.local 30 | .env.development.local 31 | .env.test.local 32 | .env.production.local 33 | 34 | # vercel 35 | .vercel 36 | .vscode/snipsnap.code-snippets 37 | 38 | #linters 39 | .stylelintcache 40 | .eslintcache 41 | 42 | tmp 43 | 44 | prisma/.env 45 | 46 | sentry.properties -------------------------------------------------------------------------------- /templates/frontend/.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /templates/frontend/.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | cd templates/frontend 5 | npx --no-install commitlint --edit "$1" 6 | -------------------------------------------------------------------------------- /templates/frontend/.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | cd templates/frontend 5 | npx --no-install lint-staged --concurrent false 6 | -------------------------------------------------------------------------------- /templates/frontend/.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.{js,jsx,html,css,scss,md}": "prettier --write", 3 | "*.{js,jsx}": "eslint --cache --fix", 4 | "*.{css,sass,scss,md,html}": "stylelint --cache --fix --ignore-path .gitignore", 5 | } -------------------------------------------------------------------------------- /templates/frontend/.prettierignore: -------------------------------------------------------------------------------- 1 | package.json 2 | package-lock.json -------------------------------------------------------------------------------- /templates/frontend/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "quoteProps": "as-needed", 8 | "jsxSingleQuote": false, 9 | "trailingComma": "es5", 10 | "bracketSpacing": true, 11 | "jsxBracketSameLine": false, 12 | "arrowParens": "always", 13 | "endOfLine": "lf" 14 | } 15 | -------------------------------------------------------------------------------- /templates/frontend/.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "stylelint-config-standard", 4 | "stylelint-config-recommended-scss", 5 | "stylelint-config-css-modules", 6 | "stylelint-config-recess-order" 7 | ], 8 | "rules": { 9 | "no-descending-specificity": null, 10 | "at-rule-no-unknown": null, 11 | "scss/at-rule-no-unknown": [ 12 | true, 13 | { 14 | "ignoreAtRules": [ 15 | "value" 16 | ] 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /templates/frontend/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | # Check out https://hub.docker.com/_/node to select a new base image 2 | FROM node:14.16-alpine3.13 3 | 4 | # Set NODE_ENV to prevent installation of dev dependencies in production 5 | ENV NODE_ENV=production 6 | 7 | # Set to a non-root built-in user `node` 8 | USER node 9 | 10 | # Create app directory (with user `node`) 11 | RUN mkdir -p /home/node/app 12 | 13 | WORKDIR /home/node/app 14 | 15 | # Install app dependencies 16 | # A wildcard is used to ensure both package.json AND package-lock.json are copied 17 | # where available (npm@5+) 18 | COPY --chown=node package*.json ./ 19 | 20 | RUN npm ci --ignore-scripts 21 | 22 | # Bundle app source code 23 | COPY --chown=node . . 24 | 25 | CMD [ "npm", "start" ] -------------------------------------------------------------------------------- /templates/frontend/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "src", 4 | "jsx": "react" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /templates/frontend/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/favicon.png -------------------------------------------------------------------------------- /templates/frontend/public/fonts/inter-v3-latin-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/fonts/inter-v3-latin-300.woff -------------------------------------------------------------------------------- /templates/frontend/public/fonts/inter-v3-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/fonts/inter-v3-latin-300.woff2 -------------------------------------------------------------------------------- /templates/frontend/public/fonts/inter-v3-latin-500.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/fonts/inter-v3-latin-500.woff -------------------------------------------------------------------------------- /templates/frontend/public/fonts/inter-v3-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/fonts/inter-v3-latin-500.woff2 -------------------------------------------------------------------------------- /templates/frontend/public/fonts/inter-v3-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/fonts/inter-v3-latin-regular.woff -------------------------------------------------------------------------------- /templates/frontend/public/fonts/inter-v3-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/fonts/inter-v3-latin-regular.woff2 -------------------------------------------------------------------------------- /templates/frontend/public/images/empty-box-illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/images/empty-box-illustration.png -------------------------------------------------------------------------------- /templates/frontend/public/images/github-illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/images/github-illustration.png -------------------------------------------------------------------------------- /templates/frontend/public/images/marketplace-illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/images/marketplace-illustration.png -------------------------------------------------------------------------------- /templates/frontend/public/images/peace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/images/peace.png -------------------------------------------------------------------------------- /templates/frontend/public/images/rock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/images/rock.png -------------------------------------------------------------------------------- /templates/frontend/public/images/templates-illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/images/templates-illustration.png -------------------------------------------------------------------------------- /templates/frontend/public/logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/logo-white.png -------------------------------------------------------------------------------- /templates/frontend/public/social-media.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/social-media.jpg -------------------------------------------------------------------------------- /templates/frontend/public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /templates/frontend/public/videos/demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snipsnapdev/snipsnap/cf104e1663572b1122081d201a355ec81ff7f8dc/templates/frontend/public/videos/demo.mp4 -------------------------------------------------------------------------------- /templates/frontend/sentry.client.config.js: -------------------------------------------------------------------------------- 1 | // This file configures the intialization of Sentry on the browser. 2 | // The config you add here will be used whenever a page is visited. 3 | // https://docs.sentry.io/platforms/javascript/guides/nextjs/ 4 | 5 | import * as Sentry from '@sentry/nextjs'; 6 | 7 | Sentry.init({ 8 | dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, 9 | release: process.env.npm_package_version, 10 | // Note: if you want to override the automatic release value, do not set a 11 | // `release` value here - use the environment variable `SENTRY_RELEASE`, so 12 | // that it will also get attached to your source maps 13 | }); 14 | -------------------------------------------------------------------------------- /templates/frontend/sentry.server.config.js: -------------------------------------------------------------------------------- 1 | // This file configures the initialization of Sentry on the server. 2 | // The config you add here will be used whenever the server handles a request. 3 | // https://docs.sentry.io/platforms/javascript/guides/nextjs/ 4 | 5 | import * as Sentry from '@sentry/nextjs'; 6 | 7 | const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; 8 | 9 | Sentry.init({ 10 | dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, 11 | release: process.env.npm_package_version, 12 | // Note: if you want to override the automatic release value, do not set a 13 | // `release` value here - use the environment variable `SENTRY_RELEASE`, so 14 | // that it will also get attached to your source maps 15 | }); 16 | -------------------------------------------------------------------------------- /templates/frontend/src/api/queries.js: -------------------------------------------------------------------------------- 1 | import { gql } from 'api/graphql'; 2 | 3 | export const getUsersTemplateGroupSharedTo = gql` 4 | query MyQuery($groupId: uuid!) { 5 | shared_template_groups(where: { template_group_id: { _eq: $groupId } }) { 6 | shared_to_user { 7 | id 8 | name 9 | image 10 | email 11 | } 12 | } 13 | } 14 | `; 15 | 16 | export const getUsersTemplateSharedTo = gql` 17 | query MyQuery($templateId: uuid!) { 18 | shared_templates(where: { template_id: { _eq: $templateId } }) { 19 | shared_to_user_id 20 | shared_to_user { 21 | id 22 | name 23 | image 24 | email 25 | } 26 | } 27 | } 28 | `; 29 | 30 | export const getTemplatePublicStatusQuery = gql` 31 | query MyQuery($templateId: uuid!) { 32 | templates(where: { id: { _eq: $templateId } }) { 33 | id 34 | is_public 35 | } 36 | } 37 | `; 38 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/collection/collection.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | padding: 30px; 3 | } 4 | 5 | .header { 6 | display: flex; 7 | align-items: center; 8 | margin-bottom: 20px; 9 | } 10 | 11 | .image { 12 | height: 34px; 13 | margin-right: 10px; 14 | } 15 | 16 | .title { 17 | font-size: 30px; 18 | font-weight: $font-weight-xs; 19 | line-height: $line-height-even; 20 | } 21 | 22 | .description { 23 | max-width: 870px; 24 | margin-bottom: 30px; 25 | font-size: 16px; 26 | font-weight: $font-weight-xs; 27 | line-height: 1.4; 28 | color: $color-light-grey; 29 | } 30 | 31 | .item { 32 | display: flex; 33 | align-items: center; 34 | justify-content: space-between; 35 | min-height: 50px; 36 | padding: 10px; 37 | box-shadow: 0 1px 0 $color-dark-grey, inset 0 1px 0 $color-dark-grey; 38 | transition: background-color $transition-base, color $transition-base; 39 | 40 | &:hover { 41 | color: $color-link; 42 | cursor: pointer; 43 | background-color: $color-dark-grey; 44 | } 45 | } 46 | 47 | .item-name { 48 | font-size: 16px; 49 | } 50 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/collection/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './collection'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/create-template/create-template.jsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from 'next/router'; 2 | 3 | import TemplateForm from 'components/shared/template-form'; 4 | 5 | const defaultTemplateValues = { 6 | name: '', 7 | prompts: [], 8 | files: [], 9 | }; 10 | 11 | const CreateTemplate = () => { 12 | const router = useRouter(); 13 | 14 | const { groupId } = router.query; 15 | 16 | return ( 17 | 18 | ); 19 | }; 20 | 21 | export default CreateTemplate; 22 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/create-template/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './create-template.jsx'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/edit-template/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './edit-template.jsx'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/home/home.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | 3 | import SupportUs from 'components/shared/support-us'; 4 | import UseCases from 'components/shared/use-cases'; 5 | import VideoPlayer from 'components/shared/video-player'; 6 | 7 | import styles from './home.module.scss'; 8 | import Steps from './steps'; 9 | 10 | const cx = classNames.bind(styles); 11 | 12 | const Home = () => ( 13 |
14 |
15 | 16 |
17 |
18 | 19 | 20 | 21 |
22 |
23 | ); 24 | 25 | export default Home; 26 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/home/home.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: grid; 3 | grid-template-columns: repeat(2, 1fr); 4 | padding-top: 30px; 5 | padding-right: 30px; 6 | padding-bottom: 30px; 7 | padding-left: 30px; 8 | } 9 | 10 | .left { 11 | padding-top: 25px; 12 | padding-right: 60px; 13 | } 14 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/home/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './home.jsx'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/home/steps/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './steps'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/login/images/play.inline.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/login/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './login'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/community-templates/community-templates.module.scss: -------------------------------------------------------------------------------- 1 | .title { 2 | display: flex; 3 | align-items: center; 4 | margin-bottom: 20px; 5 | font-size: 26px; 6 | font-weight: $font-weight-xs; 7 | line-height: $line-height-even; 8 | 9 | span { 10 | margin-left: 5px; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/community-templates/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './community-templates'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/community-templates/items/empty-items/empty-items.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | import Image from 'next/image'; 3 | import Link from 'next/link'; 4 | 5 | import styles from './empty-items.module.scss'; 6 | 7 | const cx = classNames.bind(styles); 8 | 9 | const EmptyItems = () => ( 10 |
11 |
12 | Empty 19 |
20 |
21 | No items found.{' '} 22 | 23 | Add new template 24 | 25 |
26 |
27 | ); 28 | 29 | export default EmptyItems; 30 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/community-templates/items/empty-items/empty-items.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: flex; 3 | flex-direction: column; 4 | flex-grow: 1; 5 | align-items: center; 6 | justify-content: center; 7 | } 8 | 9 | .image { 10 | width: 170px; 11 | height: 170px; 12 | margin-bottom: 30px; 13 | background-color: $color-dark-grey; 14 | border-radius: 50%; 15 | } 16 | 17 | .text { 18 | font-size: $font-size-lg; 19 | font-weight: $font-weight-xs; 20 | line-height: $line-height-even; 21 | color: $color-white; 22 | } 23 | 24 | .link { 25 | color: $color-link; 26 | text-decoration: none; 27 | 28 | &:hover { 29 | color: $color-link-hover; 30 | } 31 | } 32 | 33 | .image-wrapper { 34 | margin-bottom: 40px; 35 | 36 | & > div { 37 | display: block; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/community-templates/items/empty-items/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './empty-items'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/community-templates/items/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './items'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/community-templates/search/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './search'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/community-templates/search/search.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import CloseIcon from 'icons/close.inline.svg'; 5 | import SearchIcon from 'icons/search.inline.svg'; 6 | 7 | import styles from './search.module.scss'; 8 | 9 | const cx = classNames.bind(styles); 10 | 11 | const Search = ({ value, onChange }) => { 12 | const handleInputChange = (event) => onChange(event.currentTarget.value); 13 | const handleResetButtonClick = () => onChange(''); 14 | 15 | return ( 16 | 31 | ); 32 | }; 33 | 34 | Search.propTypes = { 35 | value: PropTypes.string.isRequired, 36 | onChange: PropTypes.func.isRequired, 37 | }; 38 | 39 | export default Search; 40 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/curated-collections/curated-collections.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | margin-bottom: 60px; 3 | } 4 | 5 | .title { 6 | display: flex; 7 | align-items: center; 8 | margin-bottom: 20px; 9 | font-size: 26px; 10 | font-weight: $font-weight-xs; 11 | line-height: $line-height-even; 12 | 13 | span { 14 | margin-left: 5px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/curated-collections/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './curated-collections'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/curated-collections/items/images/tailwindui.inline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/curated-collections/items/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './items'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/curated-collections/items/items.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: grid; 3 | grid-template-columns: repeat(3, 1fr); 4 | row-gap: 20px; 5 | column-gap: 20px; 6 | height: 100%; 7 | padding-right: 30px; 8 | padding-left: 30px; 9 | margin-right: -30px; 10 | margin-left: -30px; 11 | } 12 | 13 | .item { 14 | display: flex; 15 | flex-direction: column; 16 | justify-content: space-between; 17 | min-height: 120px; 18 | padding-top: 20px; 19 | padding-right: 20px; 20 | padding-bottom: 20px; 21 | padding-left: 20px; 22 | cursor: pointer; 23 | background-color: $color-dark-grey; 24 | border: 1px solid $color-middle-grey; 25 | border-radius: 2px; 26 | } 27 | 28 | .item-header { 29 | display: flex; 30 | justify-content: space-between; 31 | margin-bottom: 10px; 32 | } 33 | 34 | .item-name { 35 | max-width: 220px; 36 | font-size: 20px; 37 | font-weight: $font-weight-sm; 38 | line-height: 1.4; 39 | } 40 | 41 | .item-image { 42 | height: 30px; 43 | } 44 | 45 | .item-number { 46 | align-self: flex-start; 47 | } 48 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './marketplace'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/marketplace.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | import Image from 'next/image'; 3 | 4 | import CommunityTemplates from './community-templates'; 5 | import CuratedCollections from './curated-collections'; 6 | import styles from './marketplace.module.scss'; 7 | 8 | const cx = classNames.bind(styles); 9 | 10 | const Marketplace = () => ( 11 |
12 |
13 |

Marketplace

14 |

15 | Find templates created by other users. Clone them and modify for your needs. Share your 16 | templates with the community. 17 |

18 |
19 | 20 | 21 |
22 | Marketplace 29 |
30 |
31 | ); 32 | 33 | export default Marketplace; 34 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/marketplace/marketplace.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | min-height: 100vh; 6 | padding-top: 55px; 7 | padding-right: 30px; 8 | padding-bottom: 55px; 9 | padding-left: 30px; 10 | } 11 | 12 | .header { 13 | margin-bottom: 45px; 14 | } 15 | 16 | .title { 17 | margin-bottom: 15px; 18 | font-size: 30px; 19 | font-weight: $font-weight-xs; 20 | line-height: $line-height-even; 21 | } 22 | 23 | .description { 24 | max-width: 550px; 25 | font-size: 16px; 26 | font-weight: $font-weight-xs; 27 | line-height: 1.4; 28 | color: $color-light-grey; 29 | } 30 | 31 | .image-wrapper { 32 | position: absolute; 33 | top: 0; 34 | right: 0; 35 | } 36 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/images/download.inline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './preview-template'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/preview-template.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | padding: 30px; 3 | } 4 | 5 | .title { 6 | margin-bottom: 20px; 7 | font-size: 20px; 8 | font-weight: $font-weight-xs; 9 | line-height: $line-height-even; 10 | } 11 | 12 | .title-wrapper { 13 | display: flex; 14 | align-items: center; 15 | justify-content: space-between; 16 | 17 | & .title { 18 | margin-bottom: 0; 19 | } 20 | } 21 | 22 | .description-wrapper { 23 | display: flex; 24 | align-items: flex-start; 25 | } 26 | 27 | .description { 28 | margin-right: 40px; 29 | font-size: 16px; 30 | font-weight: $font-weight-xs; 31 | line-height: 1.4; 32 | color: $color-light-grey; 33 | } 34 | 35 | .clone-button { 36 | flex-shrink: 0; 37 | } 38 | 39 | .download-icon { 40 | fill: none !important; 41 | } 42 | 43 | .animation { 44 | position: relative; 45 | width: 100%; 46 | margin-top: 40px; 47 | } 48 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/vscode-animation/folder-menu/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './folder-menu'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/vscode-animation/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './vscode-animation'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/vscode-animation/prompt-input/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './prompt-input'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/vscode-animation/prompt-input/prompt-input.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | import Typewriter from 'typewriter-effect'; 3 | 4 | import styles from './prompt-input.module.scss'; 5 | 6 | const cx = classNames.bind(styles); 7 | 8 | const PromptInput = ({ value, message, className }) => ( 9 |
10 |
11 | 12 | { 14 | typewriter.pauseFor(500).typeString(value).start(); 15 | }} 16 | /> 17 | 18 |
19 |
20 |
{message}
21 |
22 |
23 | ); 24 | 25 | export default PromptInput; 26 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/vscode-animation/template-select/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './template-select'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/vscode-animation/template-select/template-select.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | 3 | import styles from './template-select.module.scss'; 4 | 5 | const cx = classNames.bind(styles); 6 | 7 | const TEMPLATES = ['Storybook for React Component', 'Dockerfile', 'NodeJS + Express']; 8 | 9 | const TemplateSelect = ({ templateName, className }) => ( 10 |
11 |
12 | Please choose a template you want to use 13 |
14 |
15 |
{templateName}
16 | {TEMPLATES.map((template) => ( 17 |
18 | {template} 19 |
20 | ))} 21 |
22 |
23 | ); 24 | 25 | export default TemplateSelect; 26 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/vscode-animation/vscode-animation.module.scss: -------------------------------------------------------------------------------- 1 | .animation { 2 | position: relative; 3 | width: 100%; 4 | margin-top: 40px; 5 | } 6 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/vscode-animation/vscode-layout/images/top-left-icons.inline.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 11 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/vscode-animation/vscode-layout/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './vscode-layout'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/vscode-animation/vscode-layout/vscode-sidebar/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './vscode-sidebar'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/preview-template/vscode-animation/vscode-layout/vscode-sidebar/vscode-sidebar.module.scss: -------------------------------------------------------------------------------- 1 | .sidebar { 2 | display: flex; 3 | flex-direction: column; 4 | width: 320px; 5 | background-color: #252526; 6 | } 7 | 8 | .top { 9 | position: relative; 10 | padding: 8px 20px; 11 | color: #ccc; 12 | } 13 | 14 | .icon-dots { 15 | position: absolute; 16 | top: 10px; 17 | right: 16px; 18 | width: 16px; 19 | height: 16px; 20 | fill: #ccc; 21 | transform: rotate(90deg); 22 | } 23 | 24 | .section { 25 | position: relative; 26 | padding: 5px 23px; 27 | color: #ccc; 28 | 29 | & .icon-down { 30 | position: absolute; 31 | top: 10px; 32 | left: 8px; 33 | width: 10px; 34 | height: 6px; 35 | } 36 | } 37 | 38 | .section-title { 39 | text-transform: uppercase; 40 | } 41 | 42 | .open-editors { 43 | border-bottom: 1px solid #3c3c3c; 44 | } 45 | 46 | .outline { 47 | margin-top: auto; 48 | border-top: 1px solid #3c3c3c; 49 | 50 | & .icon-down { 51 | transform: rotate(-90deg); 52 | } 53 | } 54 | 55 | .files { 56 | flex-grow: 1; 57 | padding-top: 5px; 58 | padding-right: 0; 59 | padding-left: 0; 60 | margin-left: -10px; 61 | } 62 | -------------------------------------------------------------------------------- /templates/frontend/src/components/pages/view-template/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './view-template.jsx'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/async-button/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './async-button'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/avatar/avatar.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | import Image from 'next/image'; 3 | import PropTypes from 'prop-types'; 4 | 5 | import styles from './avatar.module.scss'; 6 | 7 | const cx = classNames.bind(styles); 8 | 9 | const Avatar = ({ className: additionalClassName, userName, avatar }) => { 10 | const symbol = userName?.slice(0, 1); 11 | 12 | return ( 13 |
14 | {avatar ? ( 15 | 16 | ) : ( 17 |
{symbol}
18 | )} 19 |
20 | ); 21 | }; 22 | 23 | Avatar.propTypes = { 24 | className: PropTypes.string, 25 | userName: PropTypes.string, 26 | avatar: PropTypes.string, 27 | }; 28 | 29 | Avatar.defaultProps = { 30 | className: null, 31 | userName: null, 32 | avatar: null, 33 | }; 34 | 35 | export default Avatar; 36 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/avatar/avatar.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | position: relative; 3 | width: 30px; 4 | height: 30px; 5 | overflow: hidden; 6 | background-color: $color-dark-grey; 7 | border-radius: 50%; 8 | } 9 | 10 | .symbol { 11 | position: absolute; 12 | top: 50%; 13 | left: 50%; 14 | font-weight: $font-weight-md; 15 | transform: translate(-50%, -50%); 16 | } 17 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/avatar/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './avatar'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/button/images/loader.inline.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/button/images/success.inline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/button/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './button'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/create-template-group-modal/create-template-group-modal.module.scss: -------------------------------------------------------------------------------- 1 | .actions { 2 | display: flex; 3 | justify-content: flex-start; 4 | margin-top: 30px; 5 | 6 | & > *:not(:last-child) { 7 | margin-right: 20px; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/create-template-group-modal/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './create-template-group-modal'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/delete-group-modal/delete-group-modal.module.scss: -------------------------------------------------------------------------------- 1 | .actions { 2 | display: flex; 3 | justify-content: center; 4 | 5 | & > *:not(:last-child) { 6 | margin-right: 20px; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/delete-group-modal/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './delete-group-modal'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/delete-template-modal/delete-template-modal.module.scss: -------------------------------------------------------------------------------- 1 | .actions { 2 | display: flex; 3 | justify-content: center; 4 | 5 | & > *:not(:last-child) { 6 | margin-right: 20px; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/delete-template-modal/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './delete-template-modal'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/dropdown/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './dropdown'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/dropdown/menu/index.js: -------------------------------------------------------------------------------- 1 | import Menu from './menu'; 2 | 3 | export default Menu; 4 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/editor-wrapper/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './editor-wrapper.jsx'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/editor/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './editor.jsx'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/error-modal/error-modal.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | import { useContext } from 'react'; 3 | 4 | import Button from 'components/shared/button'; 5 | import Modal from 'components/shared/modal'; 6 | import ModalPortal from 'components/shared/modal-portal'; 7 | import { ErrorModalContext } from 'contexts/error-modal-context'; 8 | 9 | import styles from './error-modal.module.scss'; 10 | 11 | const cx = classNames.bind(styles); 12 | 13 | const ErrorModal = () => { 14 | const { errorText, closeErrorModal, isErrorModalOpen } = useContext(ErrorModalContext); 15 | 16 | if (!isErrorModalOpen) { 17 | return <>; 18 | } 19 | 20 | return ( 21 | 22 | 23 |
24 | 27 |
28 |
29 |
30 | ); 31 | }; 32 | 33 | export default ErrorModal; 34 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/error-modal/error-modal.module.scss: -------------------------------------------------------------------------------- 1 | .actions { 2 | display: flex; 3 | justify-content: center; 4 | 5 | & > *:not(:last-child) { 6 | margin-right: 20px; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/error-modal/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './error-modal'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/add-file-modal/add-file-modal.module.scss: -------------------------------------------------------------------------------- 1 | .actions { 2 | display: flex; 3 | justify-content: flex-start; 4 | margin-top: 30px; 5 | 6 | & > *:not(:last-child) { 7 | margin-right: 20px; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/add-file-modal/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './add-file-modal'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/add-folder-modal/add-folder-modal.module.scss: -------------------------------------------------------------------------------- 1 | .actions { 2 | display: flex; 3 | justify-content: flex-start; 4 | margin-top: 30px; 5 | 6 | & > *:not(:last-child) { 7 | margin-right: 20px; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/add-folder-modal/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './add-folder-modal'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/delete-file-modal/delete-file-modal.module.scss: -------------------------------------------------------------------------------- 1 | .actions { 2 | display: flex; 3 | justify-content: center; 4 | 5 | & > *:not(:last-child) { 6 | margin-right: 20px; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/delete-file-modal/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './delete-file-modal'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/delete-folder-modal/delete-folder-modal.module.scss: -------------------------------------------------------------------------------- 1 | .actions { 2 | display: flex; 3 | justify-content: center; 4 | 5 | & > *:not(:last-child) { 6 | margin-right: 20px; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/delete-folder-modal/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './delete-folder-modal'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/file-browser.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | position: relative; 3 | padding-top: 10px; 4 | padding-right: 10px; 5 | padding-bottom: 10px; 6 | padding-left: 10px; 7 | font-family: $font-family; 8 | font-size: $font-size-xs; 9 | font-weight: $font-weight-md; 10 | line-height: $line-height-xs; 11 | color: $color-white; 12 | 13 | &-dragover { 14 | background-color: rgba(51, 187, 255, 0.05); 15 | border: 1px dashed $color-link; 16 | } 17 | } 18 | 19 | .empty { 20 | position: absolute; 21 | top: 50%; 22 | left: 50%; 23 | display: flex; 24 | flex-direction: column; 25 | align-items: center; 26 | width: max-content; 27 | font-size: $font-size-md; 28 | font-weight: $font-weight-sm; 29 | line-height: $line-height-even; 30 | color: $color-grey; 31 | transform: translate(-50%, -50%); 32 | 33 | & svg { 34 | margin-bottom: 25px; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/file/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './file.jsx'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/folder/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './folder.jsx'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './file-browser.jsx'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/rename-item-modal/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './rename-item-modal'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/rename-item-modal/rename-item-modal.module.scss: -------------------------------------------------------------------------------- 1 | .actions { 2 | display: flex; 3 | justify-content: flex-start; 4 | margin-top: 30px; 5 | 6 | & > *:not(:last-child) { 7 | margin-right: 20px; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/tree-recursive/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './tree-recursive.jsx'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/file-browser/tree-recursive/tree-recursive.module.scss: -------------------------------------------------------------------------------- 1 | .tree { 2 | display: flex; 3 | flex-direction: column; 4 | user-select: none; 5 | } 6 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/icon-button/icon-button.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import styles from './icon-button.module.scss'; 5 | import PlusSvg from './icons/plus.inline.svg'; 6 | 7 | const cx = classNames.bind(styles); 8 | 9 | const ICONS = { 10 | plus: PlusSvg, 11 | }; 12 | 13 | const IconButton = ({ className: additionalClassName, icon, ...otherProps }) => { 14 | const Icon = ICONS[icon.name]; 15 | 16 | return ( 17 | 20 | ); 21 | }; 22 | 23 | IconButton.propTypes = { 24 | className: PropTypes.string, 25 | icon: PropTypes.shape({ 26 | name: PropTypes.oneOf(['plus']).isRequired, 27 | size: PropTypes.number, 28 | }).isRequired, 29 | }; 30 | 31 | IconButton.defaultProps = { 32 | className: null, 33 | }; 34 | 35 | export default IconButton; 36 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/icon-button/icon-button.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: inline-flex; 3 | align-items: center; 4 | justify-content: center; 5 | width: 20px; 6 | height: 20px; 7 | padding-top: 0; 8 | padding-right: 0; 9 | padding-bottom: 0; 10 | padding-left: 0; 11 | background-color: $color-accent-primary; 12 | border: none; 13 | border-radius: 2px; 14 | outline: none; 15 | transition: background-color $transition-base; 16 | 17 | &:hover { 18 | background-color: $color-accent-primary-hover; 19 | } 20 | } 21 | 22 | .icon { 23 | fill: $color-white; 24 | } 25 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/icon-button/icons/plus.inline.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/icon-button/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './icon-button'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/input/index.js: -------------------------------------------------------------------------------- 1 | import Input from './input'; 2 | 3 | export default Input; 4 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/input/input.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | import PropTypes from 'prop-types'; 3 | import { forwardRef } from 'react'; 4 | 5 | import styles from './input.module.scss'; 6 | 7 | const cx = classNames.bind(styles); 8 | 9 | const Input = forwardRef((props, ref) => { 10 | const { className: additionalClassName, register, label, type, error, ...otherProps } = props; 11 | return ( 12 |
13 | {label &&
{label}
} 14 |
15 | 21 | {error &&
{error}
} 22 |
23 |
24 | ); 25 | }); 26 | 27 | Input.propTypes = { 28 | className: PropTypes.string, 29 | label: PropTypes.string, 30 | type: PropTypes.string, 31 | error: PropTypes.string, 32 | }; 33 | 34 | Input.defaultProps = { 35 | type: 'text', 36 | error: null, 37 | label: null, 38 | className: '', 39 | }; 40 | 41 | export default Input; 42 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/input/input.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: block; 3 | } 4 | 5 | .label { 6 | display: block; 7 | margin-bottom: 8px; 8 | font-size: $font-size-xs; 9 | line-height: $line-height-even; 10 | color: $color-grey; 11 | } 12 | 13 | .input-wrapper { 14 | position: relative; 15 | } 16 | 17 | .input { 18 | width: 100%; 19 | height: 40px; 20 | padding-right: 15px; 21 | padding-left: 15px; 22 | font-size: $font-size-sm; 23 | font-weight: $font-weight-md; 24 | font-weight: $font-weight-sm; 25 | line-height: $line-height-sm; 26 | color: $color-white; 27 | background: $color-primary-black; 28 | border: 1px solid $color-middle-grey; 29 | border-radius: 2px; 30 | transition: border-color $transition-base; 31 | 32 | &:hover { 33 | border-color: $color-grey; 34 | } 35 | 36 | &:focus { 37 | border-color: $color-link; 38 | box-shadow: 0 0 5px rgba(51, 187, 255, 0.75); 39 | } 40 | 41 | &.invalid { 42 | border-color: $color-red; 43 | } 44 | } 45 | 46 | .error { 47 | position: absolute; 48 | bottom: -5px; 49 | left: 0; 50 | width: 100%; 51 | font-size: 11px; 52 | color: $color-red; 53 | transform: translateY(100%); 54 | } 55 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/layout/index.js: -------------------------------------------------------------------------------- 1 | import Layout from './layout'; 2 | 3 | export default Layout; 4 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/layout/layout.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: flex; 3 | } 4 | 5 | .main { 6 | flex-grow: 1; 7 | min-height: 100vh; 8 | // 280px is sidebar's width 9 | padding-left: 280px; 10 | 11 | &.unauthorised { 12 | // 360px is unauthorised sidebar's width 13 | padding-left: 360px; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/modal-portal/index.js: -------------------------------------------------------------------------------- 1 | import ModalPortal from './modal-portal'; 2 | 3 | export default ModalPortal; 4 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/modal-portal/modal-portal.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from 'react'; 2 | import { createPortal } from 'react-dom'; 3 | 4 | const ModalPortal = ({ children }) => { 5 | const el = useRef(null); 6 | const mount = document.getElementById('modal'); 7 | if (!el.current) el.current = document.createElement('div'); 8 | useEffect(() => { 9 | mount.appendChild(el.current); 10 | return () => mount.removeChild(el.current); 11 | // eslint-disable-next-line react-hooks/exhaustive-deps 12 | }, []); 13 | 14 | return createPortal(children, el.current); 15 | }; 16 | 17 | export default ModalPortal; 18 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/modal-portal/modal-portal.module.scss: -------------------------------------------------------------------------------- 1 | /* your css code */ 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/modal/index.js: -------------------------------------------------------------------------------- 1 | import Modal from './modal'; 2 | 3 | export default Modal; 4 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/rename-group-modal/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './rename-group-modal'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/rename-group-modal/rename-group-modal.module.scss: -------------------------------------------------------------------------------- 1 | .actions { 2 | display: flex; 3 | justify-content: flex-start; 4 | margin-top: 30px; 5 | 6 | & > *:not(:last-child) { 7 | margin-right: 20px; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/share-modal/index.js: -------------------------------------------------------------------------------- 1 | import ShareModal from './share-modal'; 2 | 3 | export default ShareModal; 4 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/sidebar/authorised-sidebar/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './authorised-sidebar'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/sidebar/authorised-sidebar/templates-groups-tree/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './templates-groups-tree'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/sidebar/authorised-sidebar/templates-groups-tree/template-group-item/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './template-group-item'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/sidebar/authorised-sidebar/templates-groups-tree/template-item/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './template-item'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/sidebar/authorised-sidebar/templates-groups-tree/templates-groups-tree.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | height: calc(100vh - 255px); 3 | padding-right: 20px; 4 | padding-left: 20px; 5 | margin-right: -20px; 6 | margin-bottom: 30px; 7 | margin-left: -20px; 8 | overflow-y: scroll; 9 | } 10 | 11 | .section { 12 | margin-bottom: 20px; 13 | 14 | &:last-child { 15 | margin-bottom: 0; 16 | } 17 | } 18 | 19 | .subtitle { 20 | margin-bottom: 5px; 21 | color: $color-grey; 22 | } 23 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/sidebar/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './sidebar'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/sidebar/sidebar.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import useSession from 'hooks/use-session'; 4 | 5 | import AuthorisedSidebar from './authorised-sidebar'; 6 | import UnauthorisedSidebar from './unauthorised-sidebar'; 7 | 8 | const Sidebar = () => { 9 | const [session = {}] = useSession(); 10 | 11 | const { user } = session; 12 | 13 | if (user) return ; 14 | return ; 15 | }; 16 | 17 | export default Sidebar; 18 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/sidebar/unauthorised-sidebar/images/play.inline.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/sidebar/unauthorised-sidebar/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './unauthorised-sidebar'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/support-us/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './support-us'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/support-us/support-us.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | import dynamic from 'next/dynamic'; 3 | import Image from 'next/image'; 4 | 5 | import styles from './support-us.module.scss'; 6 | 7 | const GitHubButton = dynamic(import('react-github-btn'), { ssr: false }); 8 | 9 | const cx = classNames.bind(styles); 10 | 11 | const SupportUs = () => ( 12 |
13 |

14 | Snipsnap is an Open Source and Free tool, we will appreciate if you give us a star 15 |

16 |
17 | 24 | Star 25 | 26 |
27 |
28 | Support us on Github 35 |
36 |
37 | ); 38 | 39 | export default SupportUs; 40 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/support-us/support-us.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | position: relative; 3 | min-height: 220px; 4 | padding-top: 30px; 5 | padding-right: 30px; 6 | padding-bottom: 30px; 7 | padding-left: 30px; 8 | margin-bottom: 30px; 9 | background-color: $color-secondary-black; 10 | border: 1px solid $color-middle-grey; 11 | border-radius: 2px; 12 | } 13 | 14 | .text { 15 | margin-bottom: 20px; 16 | font-size: $font-size-lg; 17 | line-height: 1.4; 18 | } 19 | 20 | .image-wrapper { 21 | position: absolute; 22 | right: 0; 23 | bottom: 0; 24 | } 25 | 26 | .github-button { 27 | position: relative; 28 | z-index: 1; 29 | } 30 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/switch/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './switch'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/switch/switch.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import styles from './switch.module.scss'; 5 | 6 | const cx = classNames.bind(styles); 7 | 8 | const Switch = ({ className, isChecked, onChange, label }) => ( 9 |
10 |
18 | ); 19 | 20 | Switch.propTypes = { 21 | className: PropTypes.string, 22 | isChecked: PropTypes.bool, 23 | onChange: PropTypes.func, 24 | label: PropTypes.string, 25 | }; 26 | 27 | Switch.defaultProps = { 28 | className: '', 29 | isChecked: false, 30 | onChange: undefined, 31 | label: '', 32 | }; 33 | 34 | export default Switch; 35 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/switch/switch.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: flex; 3 | align-items: center; 4 | width: 100%; 5 | font-size: $font-size-md; 6 | line-height: $line-height-even; 7 | color: $color-light-grey; 8 | } 9 | 10 | .label { 11 | margin-left: 10px; 12 | } 13 | 14 | .switch-button { 15 | position: relative; 16 | width: 47px; 17 | height: 26px; 18 | cursor: pointer; 19 | background-color: $color-primary-black; 20 | border: none; 21 | border-radius: 30px; 22 | outline: none; 23 | transition: background-color $transition-base; 24 | 25 | @include no-highlight-on-tap; 26 | 27 | &::after { 28 | position: absolute; 29 | top: 5px; 30 | left: 5px; 31 | width: 16px; 32 | height: 16px; 33 | cursor: pointer; 34 | content: ''; 35 | background-color: $color-grey; 36 | border-radius: 100%; 37 | transition: all $transition-base; 38 | } 39 | 40 | &.checked { 41 | background-color: $color-accent-primary; 42 | 43 | &::after { 44 | left: 53%; 45 | background-color: $color-white; 46 | } 47 | } 48 | 49 | &:hover { 50 | .border-gradient { 51 | opacity: 0; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/template-form/files/files.module.scss: -------------------------------------------------------------------------------- 1 | .head { 2 | display: flex; 3 | align-items: center; 4 | width: 100%; 5 | margin-bottom: 15px; 6 | } 7 | 8 | .title { 9 | font-size: $font-size-lg; 10 | font-weight: $font-weight-xs; 11 | line-height: $line-height-even; 12 | } 13 | 14 | .add-button { 15 | margin-left: 10px; 16 | } 17 | 18 | .add-options-inner { 19 | width: 100px; 20 | } 21 | 22 | .group-options { 23 | margin-left: auto; 24 | } 25 | 26 | .file-browser { 27 | height: calc(100% - 35px); 28 | min-height: 300px; 29 | overflow-x: hidden; 30 | overflow-y: scroll; 31 | background-color: $color-primary-black; 32 | border: 1px solid $color-middle-grey; 33 | border-radius: 2px; 34 | } 35 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/template-form/files/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './files'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/template-form/index.js: -------------------------------------------------------------------------------- 1 | import TemplateForm from './template-form'; 2 | 3 | export default TemplateForm; 4 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/template-form/prompts/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './prompts'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/tooltip/index.js: -------------------------------------------------------------------------------- 1 | import Tooltip from './tooltip'; 2 | 3 | export default Tooltip; 4 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/tooltip/tooltip.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | import React from 'react'; 3 | import ReactTooltip from 'react-tooltip'; 4 | 5 | import styles from './tooltip.module.scss'; 6 | 7 | const cx = classNames.bind(styles); 8 | 9 | const Tooltip = ({ className: additionalClassName, children, dataFor }) => ( 10 | <> 11 |
12 | ? 13 |
14 | 15 | ); 16 | 17 | export default Tooltip; 18 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/tooltip/tooltip.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | position: relative; 3 | z-index: 1; 4 | display: inline-block; 5 | width: 18px; 6 | height: 18px; 7 | margin-left: 8px; 8 | font-size: 12px; 9 | line-height: 18px; 10 | color: $color-light-grey; 11 | text-align: center; 12 | cursor: pointer; 13 | background-color: $color-dark-grey; 14 | border-radius: 50%; 15 | 16 | &:hover { 17 | color: $color-white; 18 | background-color: $color-middle-grey; 19 | 20 | .content { 21 | display: block; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/unshare-modal/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './unshare-modal'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/unshare-modal/unshare-modal.module.scss: -------------------------------------------------------------------------------- 1 | .actions { 2 | display: flex; 3 | justify-content: center; 4 | 5 | & > *:not(:last-child) { 6 | margin-right: 20px; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/use-cases/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './use-cases'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/use-cases/use-cases.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | max-width: 515px; 3 | margin-top: 30px; 4 | margin-bottom: 30px; 5 | } 6 | 7 | .title { 8 | margin-bottom: 15px; 9 | font-size: 18px; 10 | font-weight: $font-weight-sm; 11 | line-height: $line-height-even; 12 | } 13 | 14 | .links { 15 | display: grid; 16 | grid-template-rows: repeat(4, auto); 17 | grid-template-columns: 1fr 1fr max-content; 18 | grid-auto-flow: column; 19 | row-gap: 10px; 20 | 21 | @include sm-down { 22 | grid-template-columns: 1fr 1fr; 23 | grid-auto-flow: row; 24 | } 25 | 26 | & span { 27 | line-height: 1.4; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/video-player/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './video-player'; 2 | -------------------------------------------------------------------------------- /templates/frontend/src/components/shared/video-player/video-player.jsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames/bind'; 2 | import PropTypes from 'prop-types'; 3 | import React from 'react'; 4 | 5 | import styles from './video-player.module.scss'; 6 | 7 | const cx = classNames.bind(styles); 8 | 9 | const VideoPlayer = ({ className: additionalClassName }) => ( 10 |
11 |
12 |