├── .editorconfig ├── .env.example ├── .eslintrc.js ├── .gitignore ├── .gitpod.yml ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENCE.md ├── README.md ├── TODO.md ├── assets ├── css │ └── main.css └── js │ └── script.js ├── components ├── blocks │ ├── dashboard │ │ └── Title.vue │ ├── detail │ │ ├── BooleanValue.vue │ │ ├── ImageValue.vue │ │ ├── RelationValue.vue │ │ ├── RichTextValue.vue │ │ ├── StringValue.vue │ │ └── UnixTimestampValue.vue │ ├── form │ │ ├── BooleanInput.vue │ │ ├── ImageInput.vue │ │ ├── RichTextInput.vue │ │ ├── SelectInput.vue │ │ ├── SelectRelationInput.vue │ │ ├── TextInput.vue │ │ ├── TextareaInput.vue │ │ └── UnixTimestampInput.vue │ ├── list │ │ ├── BooleanValue.vue │ │ ├── ImageValue.vue │ │ ├── RelationValue.vue │ │ ├── StringValue.vue │ │ └── UnixTimestampValue.vue │ └── presentation │ │ └── Divider.vue └── core │ ├── Form.vue │ └── MenuTree.vue ├── jsconfig.json ├── layouts ├── app.vue └── default.vue ├── middleware ├── guestOnly.ts ├── loadConfig.ts └── userOnly.ts ├── netlify.toml ├── nuxt.config.js ├── package-lock.json ├── package.json ├── pages ├── app │ ├── index.vue │ └── panels │ │ └── _panelId │ │ ├── _documentId │ │ ├── edit.vue │ │ └── view.vue │ │ ├── create.vue │ │ └── index.vue ├── index.vue └── login.vue ├── services ├── appwrite.ts └── utils.ts ├── static ├── cover.png ├── dev_config.json ├── favicon.ico └── logo.png ├── store ├── README.md ├── config.ts └── headerActions.ts ├── tailwind.config.js ├── ts-shim.d.ts ├── tsconfig.json ├── utils └── api.ts └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | IS_DEVELOPMENT=true -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true 6 | }, 7 | extends: [ 8 | '@nuxtjs/eslint-config-typescript', 9 | 'plugin:nuxt/recommended', 10 | 'prettier' 11 | ], 12 | plugins: [ 13 | ], 14 | // add your custom rules here 15 | rules: {} 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | /logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # vuepress build output 75 | .vuepress/dist 76 | 77 | # Serverless directories 78 | .serverless 79 | 80 | # IDE / Editor 81 | .idea 82 | 83 | # Service worker 84 | sw.* 85 | 86 | # macOS 87 | .DS_Store 88 | 89 | # Vim swap files 90 | *.swp 91 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | # This configuration file was automatically generated by Gitpod. 2 | # Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file) 3 | # and commit this file to your remote git repository to share the goodness with others. 4 | 5 | tasks: 6 | - init: yarn install 7 | command: yarn dev 8 | 9 | 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to make participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity, expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | - Using welcoming and inclusive language 18 | - Being respectful of differing viewpoints and experiences 19 | - Gracefully accepting constructive criticism 20 | - Focusing on what is best for the community 21 | - Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | - The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | - Trolling, insulting/derogatory comments, and personal or political attacks 28 | - Public or private harassment 29 | - Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | - Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team lead at matejbaco2000@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # 🤝 Contributing 2 | 3 | We would ❤️ for you to contribute to AppwriteCMS and help make it better! We want contributing to AppwriteCMS to be fun, enjoyable, and educational for anyone and everyone. All contributions are welcome, including issues, new docs as well as updates and tweaks, blog posts, workshops, and more. 4 | 5 | ## 🤔 How to Start? 6 | 7 | If you are worried or don’t know where to start, check out our next section explaining what kind of help we could use and where can you get involved. You can also submit an issue, and a maintainer can guide you! 8 | 9 | ## 📜 Code of Conduct 10 | 11 | Help us keep AppwriteCMS open and inclusive. Please read and follow our [Code of Conduct](https://github.com/Meldiron/appwrite-cms/blob/master/CODE_OF_CONDUCT.md). 12 | 13 | ## 🚀 Submit a Pull Request 14 | 15 | Branch naming convention is as following: `TYPE-ISSUE_ID-DESCRIPTION`, for example: 16 | 17 | ``` 18 | doc-548-update-contribution-guide 19 | ``` 20 | 21 | Where `TYPE` can be: 22 | 23 | - **feat** - is a new feature 24 | - **doc** - documentation only changes 25 | - **cicd** - changes related to CI/CD system 26 | - **fix** - a bug fix 27 | - **refactor** - code change that neither fixes a bug nor adds a feature 28 | 29 | Issue ID can be ommited if there isn't any issue about problem you are solving. Description should be descriptive, but short enough so person using branch after you doesn't need to write a sentence 😅 30 | 31 | **All PRs must include a commit message with the changes description!** 32 | 33 | For the initial start, fork the project and use git clone command to download the repository to your computer. A standard procedure for working on an issue would be to: 34 | 35 | 1. `git pull`, before creating a new branch, pull the changes from upstream. Your master needs to be up to date. 36 | 37 | ``` 38 | $ git pull 39 | ``` 40 | 41 | 2. Create new branch from `master` like: `doc-548-update-contribution-guide`
42 | 43 | ``` 44 | $ git checkout -b [name_of_your_new_branch] 45 | ``` 46 | 47 | 3. Work - commit - repeat ( be sure to be in your branch ) 48 | 49 | 4. Push changes to GitHub 50 | 51 | ``` 52 | $ git push origin [name_of_your_new_branch] 53 | ``` 54 | 55 | 5. Submit your changes for review 56 | If you go to your repository on GitHub, you'll see a `Compare & pull request` button. Click on that button. 57 | 6. Start a Pull Request 58 | Now submit the pull request and click on `Create pull request`. 59 | 7. Get a code review approval/reject 60 | 8. After approval, merge your PR 61 | 9. GitHub will automatically delete the branch after the merge is done. (they can still be restored). 62 | 63 | ## 🤖 Development setup 64 | 65 | To set up a working **development environment**, just fork the project git repository and install the dependencies using the proper package manager. 66 | 67 | ```bash 68 | $ yarn -D 69 | $ yarn dev 70 | ``` 71 | -------------------------------------------------------------------------------- /LICENCE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 AppwriteCMS 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Cover image](/static/cover.png) 2 | 3 | _Documentation is hosted on [GitBook](https://meldiron-appwrite.gitbook.io/appwrite-cms/). Please refer to this website when looking for any guides._ 4 | 5 | # AppwriteCMS 6 | 7 | Hey there 👋 8 | 9 | Happy to see you here... Since you are looking for Appwrite admin panel, you already know what Appwrite is, right... Right?!?! 10 | 11 | If you never heard about Appwrite, please check out their [Website](https://appwrite.io/) to learn more about this amazing backend as a service. Believe it or not, you can't use AppwriteCMS without Appwrite 😬 12 | 13 | With that said... 14 | 15 | Prepare admin panels for your projects rapidly using AppwriteCMS, a headless CMS for your Appwrite project. 16 | 17 | AppwriteCMS is headless CMS for your Appwrite database. Appwrite allows you to manage your database and files, but the UI is too developer-ish and allows zero customization. In the end, it is a tool for developer not copywriter, so noone ever expected to use Appwrite as CMS. That's where AppwriteCMS comes into play! Connect AppwriteCMS to your Appwrite project and configure it as much as you need. AppwriteCMS also allows you to write your own components to achieve any interface your project needs. You can learn more in our [official documentation](https://meldiron-appwrite.gitbook.io/appwrite-cms/). 18 | 19 | Oh, I almost forgot... 20 | 21 | I never liked when people miss-spell my name from Matej to Madžejč. Products feel the same! 🤖 Let's not offend them, okay? 22 | 23 | The correct spelling is `Appwrite`, not `AppWrite`. Just like that, this is product is called `AppwriteCMS`, not `Apppwrite CMS`, and absolutely not `ApVrajt CMS`. 24 | 25 | Thanks for your attention open source community! See you later in GitHub issues section 👋 26 | 27 | ## Documentation 28 | 29 | You can find bunch of resources in our official [GitBook](https://meldiron-appwrite.gitbook.io/appwrite-cms/) documentation. 30 | 31 | ## Contributing 32 | 33 | Fun fact, we are using Nuxt! 🥳 If you understand Vue, you are more than ready to start building components. If you don't, eh, you will figure it out 😅 Don't be scared, components are tiny HTML, CSS and JS snippets that only uses Vue to bind data between HTML an JavaScript. To see quick example, you can take a look at our [FormTextareaInput](https://github.com/Meldiron/appwrite-cms/blob/master/components/blocks/form/TextareaInput.vue). 34 | 35 | All code external contributions must go through a pull request and be approved by a core developer team before being merged. This flow ensures a proper review of all the code and increases the quality of the product. 36 | 37 | We truly ❤️ pull requests! Refer to information below and our [Contributing Guide](https://github.com/Meldiron/appwrite-cms/blob/master/CONTRIBUTING.md) in order to understand how to setup AppwriteCMS, build the project and see how folder structore works. 38 | 39 | ## Build Setup 40 | 41 | ```bash 42 | # install dependencies 43 | $ yarn install 44 | 45 | # serve with hot reload at localhost:3000 46 | $ yarn dev 47 | 48 | # build for production and launch server 49 | $ yarn build 50 | $ yarn start 51 | 52 | # generate static project 53 | $ yarn generate 54 | ``` 55 | 56 | For detailed explanation on how things work, check out the [documentation](https://nuxtjs.org). 57 | 58 | ### Special Directories 59 | 60 | You can create the following extra directories, some of which have special behaviors. Only `pages` is required; you can delete them if you don't want to use their functionality. 61 | 62 | #### `assets` 63 | 64 | The assets directory contains your uncompiled assets such as Stylus or Sass files, images, or fonts. 65 | 66 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/assets). 67 | 68 | #### `components` 69 | 70 | The components directory contains your Vue.js components. Components make up the different parts of your page and can be reused and imported into your pages, layouts and even other components. 71 | 72 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/components). 73 | 74 | #### `layouts` 75 | 76 | Layouts are a great help when you want to change the look and feel of your Nuxt app, whether you want to include a sidebar or have distinct layouts for mobile and desktop. 77 | 78 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/layouts). 79 | 80 | #### `pages` 81 | 82 | This directory contains your application views and routes. Nuxt will read all the `*.vue` files inside this directory and setup Vue Router automatically. 83 | 84 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/get-started/routing). 85 | 86 | #### `plugins` 87 | 88 | The plugins directory contains JavaScript plugins that you want to run before instantiating the root Vue.js Application. This is the place to add Vue plugins and to inject functions or constants. Every time you need to use `Vue.use()`, you should create a file in `plugins/` and add its path to plugins in `nuxt.config.js`. 89 | 90 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/plugins). 91 | 92 | #### `static` 93 | 94 | This directory contains your static files. Each file inside this directory is mapped to `/`. 95 | 96 | Example: `/static/robots.txt` is mapped as `/robots.txt`. 97 | 98 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/static). 99 | 100 | #### `store` 101 | 102 | This directory contains your Vuex store files. Creating a file in this directory automatically activates Vuex. 103 | 104 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/store). 105 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | Features I have in mind and would like to implement before releasing AppwriteCMS 1.0: 4 | 5 | - Sort by attribute functionality 6 | - Multiselect delete in list 7 | - Array in list, somehow 8 | - Relationship components 9 | - Dashboard components (graphs, ...) 10 | - Dark theme 11 | - Responsibity 12 | - Write GitBook docs 13 | - Auth using email&password (custom cloud function) 14 | - Offset pagination option 15 | - Research cursor pagination (probably never before direction) 16 | - TODOS in code 17 | - Better relation system allowing relation on ANY component 18 | -------------------------------------------------------------------------------- /assets/css/main.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,300;1,400;1,500;1,600;1,700&display=swap'); 2 | 3 | @tailwind base; 4 | @tailwind components; 5 | @tailwind utilities; 6 | 7 | * { 8 | font-family: 'Poppins', sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /assets/js/script.js: -------------------------------------------------------------------------------- 1 | const bodyElement = document.querySelector('body') 2 | bodyElement.classList.add('bg-slate-100') 3 | -------------------------------------------------------------------------------- /components/blocks/dashboard/Title.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 28 | -------------------------------------------------------------------------------- /components/blocks/detail/BooleanValue.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | -------------------------------------------------------------------------------- /components/blocks/detail/ImageValue.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | -------------------------------------------------------------------------------- /components/blocks/detail/RelationValue.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /components/blocks/detail/RichTextValue.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /components/blocks/detail/StringValue.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /components/blocks/detail/UnixTimestampValue.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /components/blocks/form/BooleanInput.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | -------------------------------------------------------------------------------- /components/blocks/form/ImageInput.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | -------------------------------------------------------------------------------- /components/blocks/form/RichTextInput.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | -------------------------------------------------------------------------------- /components/blocks/form/SelectInput.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | -------------------------------------------------------------------------------- /components/blocks/form/SelectRelationInput.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | -------------------------------------------------------------------------------- /components/blocks/form/TextInput.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | -------------------------------------------------------------------------------- /components/blocks/form/TextareaInput.vue: -------------------------------------------------------------------------------- 1 |