├── .gitignore ├── .nvmrc ├── LICENSE.md ├── README.md ├── strapi-nextjs-comments ├── README.md ├── next-app │ ├── .eslintrc.json │ ├── .gitignore │ ├── api │ │ └── comment.ts │ ├── components │ │ ├── Comments │ │ │ ├── Comment.tsx │ │ │ ├── NewCommentForm.tsx │ │ │ └── index.tsx │ │ ├── Footer │ │ │ └── index.tsx │ │ ├── MainLayout │ │ │ └── index.tsx │ │ └── Navbar │ │ │ └── index.tsx │ ├── hooks │ │ └── useComments.ts │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── pages │ │ ├── [slug].tsx │ │ ├── _app.tsx │ │ └── index.tsx │ ├── public │ │ ├── favicon.ico │ │ └── vercel.svg │ ├── tsconfig.json │ ├── types │ │ └── comments.ts │ └── yarn.lock └── strapi-app │ ├── .editorconfig │ ├── .env.example │ ├── .eslintignore │ ├── .eslintrc │ ├── config │ ├── admin.js │ ├── api.js │ ├── database.js │ ├── middlewares.js │ ├── plugins.js │ └── server.js │ ├── database │ └── migrations │ │ └── .gitkeep │ ├── favicon.ico │ ├── package.json │ ├── public │ ├── robots.txt │ └── uploads │ │ └── .gitkeep │ ├── src │ ├── admin │ │ ├── app.example.js │ │ └── webpack.config.example.js │ ├── api │ │ ├── .gitkeep │ │ └── post │ │ │ ├── content-types │ │ │ └── post │ │ │ │ └── schema.json │ │ │ ├── controllers │ │ │ └── post.js │ │ │ ├── routes │ │ │ └── post.js │ │ │ └── services │ │ │ └── post.js │ ├── bootstrap │ │ ├── data.json │ │ └── index.js │ ├── extensions │ │ └── .gitkeep │ └── index.js │ └── yarn.lock ├── strapi-nextjs-navigation ├── README.md ├── next-app │ ├── .babelrc │ ├── .eslintrc.json │ ├── .gitignore │ ├── api │ │ └── index.ts │ ├── components │ │ ├── Footer │ │ │ └── index.tsx │ │ ├── MainLayout │ │ │ └── index.tsx │ │ └── Navbar │ │ │ ├── index.tsx │ │ │ ├── item.tsx │ │ │ └── list.tsx │ ├── next-env.d.ts │ ├── next.config.js │ ├── package-lock.json │ ├── package.json │ ├── pages │ │ ├── [...path].tsx │ │ ├── _app.tsx │ │ └── index.tsx │ ├── public │ │ ├── favicon.ico │ │ └── vercel.svg │ ├── styles │ │ └── global.css │ ├── tsconfig.json │ ├── types │ │ └── navigation.ts │ └── yarn.lock └── strapi-app │ ├── .editorconfig │ ├── .env.example │ ├── .eslintignore │ ├── .eslintrc │ ├── .gitignore │ ├── config │ ├── admin.js │ ├── api.js │ ├── database.js │ ├── middlewares.js │ ├── plugins.js │ └── server.js │ ├── database │ └── migrations │ │ └── .gitkeep │ ├── favicon.ico │ ├── package.json │ ├── public │ ├── robots.txt │ └── uploads │ │ └── .gitkeep │ ├── src │ ├── admin │ │ ├── app.example.js │ │ └── webpack.config.example.js │ ├── api │ │ ├── .gitkeep │ │ └── page │ │ │ ├── content-types │ │ │ └── page │ │ │ │ └── schema.json │ │ │ ├── controllers │ │ │ └── page.js │ │ │ ├── routes │ │ │ └── page.js │ │ │ └── services │ │ │ └── page.js │ ├── bootstrap │ │ ├── data.json │ │ └── index.js │ ├── extensions │ │ └── .gitkeep │ └── index.js │ └── yarn.lock ├── strapi-plugin-comments ├── .editorconfig ├── .env.example ├── .eslintignore ├── .eslintrc ├── .nvmrc ├── README.md ├── api │ ├── .gitkeep │ └── blog-post │ │ ├── config │ │ └── routes.json │ │ ├── controllers │ │ └── blog-post.js │ │ ├── models │ │ ├── blog-post.js │ │ └── blog-post.settings.json │ │ └── services │ │ └── blog-post.js ├── config │ ├── custom.js │ ├── database.js │ ├── functions │ │ ├── bootstrap.js │ │ ├── cron.js │ │ └── responses │ │ │ └── 404.js │ └── server.js ├── extensions │ └── users-permissions │ │ └── config │ │ └── jwt.js ├── favicon.ico ├── package.json ├── public │ ├── robots.txt │ └── uploads │ │ └── .gitkeep └── yarn.lock ├── strapi-plugin-navigation ├── .editorconfig ├── .env.example ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .nvmrc ├── README.md ├── api │ ├── .gitkeep │ └── blog-post │ │ ├── config │ │ └── routes.json │ │ ├── controllers │ │ └── blog-post.js │ │ ├── models │ │ ├── blog-post.js │ │ └── blog-post.settings.json │ │ └── services │ │ └── blog-post.js ├── config │ ├── custom.js │ ├── database.js │ ├── functions │ │ ├── bootstrap.js │ │ ├── cron.js │ │ └── responses │ │ │ └── 404.js │ └── server.js ├── extensions │ └── users-permissions │ │ └── config │ │ └── jwt.js ├── favicon.ico ├── package.json ├── public │ ├── robots.txt │ └── uploads │ │ └── .gitkeep └── yarn.lock ├── strapi-v4-plugin-comments ├── .editorconfig ├── .env.example ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .nvmrc ├── .vscode │ └── settings.json ├── README.md ├── config │ ├── admin.js │ ├── api.js │ ├── database.js │ ├── middlewares.js │ ├── plugins.js │ └── server.js ├── favicon.ico ├── package.json ├── public │ ├── robots.txt │ └── uploads │ │ └── .gitkeep ├── src │ ├── admin │ │ ├── app.js │ │ └── webpack.config.js │ ├── api │ │ ├── .gitkeep │ │ ├── blog-post │ │ │ ├── content-types │ │ │ │ └── blog-post │ │ │ │ │ └── schema.json │ │ │ ├── controllers │ │ │ │ └── blog-post.js │ │ │ ├── routes │ │ │ │ └── blog-post.js │ │ │ └── services │ │ │ │ └── blog-post.js │ │ └── page │ │ │ ├── content-types │ │ │ └── page │ │ │ │ └── schema.json │ │ │ ├── controllers │ │ │ └── page.js │ │ │ ├── routes │ │ │ └── page.js │ │ │ └── services │ │ │ └── page.js │ ├── components │ │ └── elements │ │ │ ├── accordion-item.json │ │ │ └── accordion.json │ ├── extensions │ │ └── .gitkeep │ └── index.js └── yarn.lock └── strapi-v4-plugin-navigation ├── .editorconfig ├── .env.example ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .nvmrc ├── .vscode └── settings.json ├── README.md ├── config ├── admin.js ├── api.js ├── database.js ├── middlewares.js ├── plugins.js └── server.js ├── favicon.ico ├── package.json ├── public ├── robots.txt └── uploads │ └── .gitkeep ├── src ├── admin │ ├── app.js │ └── webpack.config.js ├── api │ ├── .gitkeep │ ├── blog-post │ │ ├── content-types │ │ │ └── blog-post │ │ │ │ └── schema.json │ │ ├── controllers │ │ │ └── blog-post.js │ │ ├── routes │ │ │ └── blog-post.js │ │ └── services │ │ │ └── blog-post.js │ └── page │ │ ├── content-types │ │ └── page │ │ │ └── schema.json │ │ ├── controllers │ │ └── page.js │ │ ├── routes │ │ └── page.js │ │ └── services │ │ └── page.js ├── components │ └── elements │ │ ├── accordion-item.json │ │ └── accordion.json ├── extensions │ └── .gitkeep └── index.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | ############################ 2 | # OS X 3 | ############################ 4 | 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | Icon 9 | .Spotlight-V100 10 | .Trashes 11 | ._* 12 | 13 | 14 | ############################ 15 | # Linux 16 | ############################ 17 | 18 | *~ 19 | 20 | 21 | ############################ 22 | # Windows 23 | ############################ 24 | 25 | Thumbs.db 26 | ehthumbs.db 27 | Desktop.ini 28 | $RECYCLE.BIN/ 29 | *.cab 30 | *.msi 31 | *.msm 32 | *.msp 33 | 34 | 35 | ############################ 36 | # Packages 37 | ############################ 38 | 39 | *.7z 40 | *.csv 41 | *.dat 42 | *.dmg 43 | *.gz 44 | *.iso 45 | *.jar 46 | *.rar 47 | *.tar 48 | *.zip 49 | *.com 50 | *.class 51 | *.dll 52 | *.exe 53 | *.o 54 | *.seed 55 | *.so 56 | *.swo 57 | *.swp 58 | *.swn 59 | *.swm 60 | *.out 61 | *.pid 62 | 63 | 64 | ############################ 65 | # Logs and databases 66 | ############################ 67 | 68 | .tmp 69 | *.log 70 | *.sql 71 | *.sqlite 72 | *.sqlite3 73 | 74 | 75 | ############################ 76 | # Misc. 77 | ############################ 78 | 79 | *# 80 | ssl 81 | .idea 82 | nbproject 83 | public/uploads/* 84 | !public/uploads/.gitkeep 85 | 86 | ############################ 87 | # Node.js 88 | ############################ 89 | 90 | lib-cov 91 | lcov.info 92 | pids 93 | logs 94 | results 95 | node_modules 96 | .node_history 97 | 98 | ############################ 99 | # Tests 100 | ############################ 101 | 102 | testApp 103 | coverage 104 | 105 | ############################ 106 | # Strapi 107 | ############################ 108 | 109 | .env 110 | license.txt 111 | exports 112 | *.cache 113 | build 114 | .strapi-updater.json 115 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v14.17.3 2 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 VirtusLab Sp. z o.o. & Strapi Solutions. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Strapi examples 2 | 3 | ## Plugins 4 | 5 | ### Comments 6 | - [v2.x - v4 support](/strapi-v4-plugin-comments) 7 | - [v1.x](/strapi-plugin-comments) 8 | 9 | ### Navigation 10 | - [v2.x - v4 support](/strapi-v4-plugin-navigation) 11 | - [v1.x](/strapi-plugin-navigation) 12 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/README.md: -------------------------------------------------------------------------------- 1 | # Strapi Plugin Comments example with NextJS 2 | 3 | This example is set up to show how to create a project with our comments plugin installed as well as integrate it with a sample frontend. 4 | 5 | ## 🔧 Getting Started 6 | 7 | To run this project, you need to prepare two shell windows. One window will be used to set up and run strapi server and the second one will be used to run development server for nextjs frontend. 8 | 9 | ### Strapi Server 10 | 11 | Install all packages 12 | 13 | ```sh 14 | cd ./strapi-app 15 | yarn install 16 | ``` 17 | 18 | Run the server 19 | 20 | > Before running the strapi server be sure to create your own `.env` file. Example of this file can be found in strapi app folder. 21 | 22 | ```sh 23 | yarn build 24 | yarn develop 25 | 26 | # or 27 | 28 | yarn develop --watch-admin 29 | ``` 30 | 31 | After that open strapi admin panel and create admin user. The strapi project should be ready to use at this point. 32 | 33 | ### NextJS development server 34 | 35 | Install all packages 36 | ```sh 37 | cd ./next-app 38 | yarn install 39 | ``` 40 | 41 | Run the server 42 | ```sh 43 | yarn dev 44 | ``` 45 | 46 | After that the nextJs frontend should be ready to use. You can direct to `localhost:3000` to see it. -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/.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 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/api/comment.ts: -------------------------------------------------------------------------------- 1 | import { Author, Report } from "../types/comments"; 2 | 3 | export async function PostComment(postId: number, author: Author, content: string) { 4 | const body = JSON.stringify({ author, content }); 5 | const res = await fetch(`http://localhost:1337/api/comments/api::post.post:${postId}`, 6 | { 7 | headers: { 8 | 'Accept': 'application/json', 9 | 'Content-Type': 'application/json' 10 | }, 11 | method: "POST", 12 | body, 13 | } 14 | ); 15 | } 16 | 17 | export async function ReportComment(postId: number, commentId: number, report: Report) { 18 | const body = JSON.stringify(report); 19 | const res = await fetch(`http://localhost:1337/api/comments/api::post.post:${postId}/comment/${commentId}/report-abuse`, 20 | { 21 | headers: { 22 | 'Accept': 'application/json', 23 | 'Content-Type': 'application/json' 24 | }, 25 | method: "POST", 26 | body 27 | } 28 | ); 29 | } 30 | 31 | export async function GetComments(postId: number) { 32 | const res = await fetch(`http://localhost:1337/api/comments/api::post.post:${postId}`); 33 | const data = await res.json(); 34 | return data; 35 | } -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/components/Comments/Comment.tsx: -------------------------------------------------------------------------------- 1 | import { Dropdown } from "react-bootstrap" 2 | import { Comment, Report } from "../../types/comments" 3 | 4 | interface IProps { 5 | comment: Comment; 6 | postId: number; 7 | reportComment: (postId: number, commentId: number, report: Report) => Promise; 8 | } 9 | 10 | const reports: Array = [ 11 | { reason: "BAD_WORDS", content: "Comment reported for containing bad words", label: "Report for bad words" }, 12 | { reason: "DISCRIMINATION", content: "Comment reported for being discriminative", label: "Report for discrimination" }, 13 | { reason: "OTHER", content: "Comment reported for unspecified reason", label: "Report for other" }, 14 | ]; 15 | 16 | const Comment: React.FC = ({ comment, postId, reportComment }) => { 17 | const blocked = comment.blocked; 18 | return ( 19 | 45 | ) 46 | }; 47 | 48 | export default Comment; 49 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/components/Comments/NewCommentForm.tsx: -------------------------------------------------------------------------------- 1 | import { useFormik } from "formik"; 2 | import { Author } from "../../types/comments"; 3 | 4 | interface IProps { 5 | postId: number; 6 | postComment: (postId: number, author: Author, content: string, threadOf?: number) => Promise; 7 | } 8 | 9 | const NewCommentForm: React.FC = ({ postId, postComment }) => { 10 | const formik = useFormik({ 11 | initialValues: { 12 | name: "", 13 | email: "", 14 | content: "", 15 | }, 16 | onSubmit: async () => { 17 | const author = { 18 | id: formik.values.email.replace("@", "_"), 19 | name: formik.values.name, 20 | email: formik.values.email, 21 | } 22 | await postComment(postId, author, formik.values.content); 23 | formik.setValues(formik.initialValues); 24 | } 25 | }); 26 | 27 | const defaultProps = (field: "name" | "email" | "content") => ({ 28 | className: "form-control", 29 | value: formik.values[field], 30 | onChange: formik.handleChange, 31 | required: true, 32 | disabled: formik.isSubmitting, 33 | id: field, 34 | name: field, 35 | }); 36 | 37 | return ( 38 |
39 |

40 | Add new comment 41 |

42 |
43 |
44 | 45 | 46 |
47 | Valid last name is required. 48 |
49 |
50 |
51 | 52 | 53 |
54 | Valid last name is required. 55 |
56 |
57 |
58 |
59 | 60 | 61 |
62 |
63 |
64 | 65 |
66 |
67 |
68 | ); 69 | } 70 | 71 | export default NewCommentForm; -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/components/Comments/index.tsx: -------------------------------------------------------------------------------- 1 | import usePostComments from "../../hooks/useComments"; 2 | import Comment from "./Comment"; 3 | import NewCommentForm from "./NewCommentForm"; 4 | 5 | interface IProps { 6 | postId: number; 7 | } 8 | 9 | const CommentsList: React.FC = ({ postId }) => { 10 | const { data, isLoading, reportComment, postComment } = usePostComments(postId); 11 | 12 | if (isLoading || !data) { 13 | return
Loading comments...
; 14 | } 15 | 16 | return ( 17 | <> 18 |
19 |

Comments

20 |
21 | { 22 | data.map(comment => 23 | ) 29 | } 30 |
31 | 32 | 33 | ); 34 | } 35 | 36 | export default CommentsList; 37 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/components/Footer/index.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | 3 | const footerItems = [{ 4 | id: 1, 5 | title: 'Strapi Documentation', 6 | path: 'https://docs.strapi.io/', 7 | }, { 8 | id: 2, 9 | title: 'Strapi Plugin Comments', 10 | path: 'https://github.com/VirtusLab-Open-Source/strapi-plugin-comments/', 11 | }, { 12 | id: 3, 13 | title: 'Strapi Plugin Navigation', 14 | path: 'https://github.com/VirtusLab-Open-Source/strapi-plugin-navigation/', 15 | }]; 16 | 17 | const MainFooter: React.FC = () => { 18 | return ( 19 |
20 |
21 |

Created by VirtusLab

22 |
    23 | {footerItems.map((navItem) => ( 24 | 25 |
  • 26 | {navItem.title} 27 |
  • 28 | 29 | ))} 30 |
31 |
32 |
33 | ); 34 | } 35 | 36 | export default MainFooter; -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/components/MainLayout/index.tsx: -------------------------------------------------------------------------------- 1 | import { Container } from "react-bootstrap"; 2 | import Footer from "../Footer"; 3 | import Navbar from "../Navbar"; 4 | 5 | interface IProps { 6 | children: JSX.Element 7 | } 8 | 9 | const MainLayout: React.FC = ({ children }) => { 10 | return ( 11 |
12 | 13 | 14 | {children} 15 | 16 |
17 |
18 | ); 19 | } 20 | 21 | export default MainLayout; -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/components/Navbar/index.tsx: -------------------------------------------------------------------------------- 1 | import { Container, Navbar } from 'react-bootstrap'; 2 | import Link from "next/link"; 3 | 4 | const MainNavbar: React.FC<{}> = () => { 5 | return ( 6 | 7 | 8 | 9 | 10 | Strapi Plugin Comments Example 11 | 12 | 13 | 14 | 15 | ); 16 | } 17 | 18 | export default MainNavbar; -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/hooks/useComments.ts: -------------------------------------------------------------------------------- 1 | import { useQuery, useQueryClient } from "react-query"; 2 | import { GetComments, PostComment, ReportComment } from "../api/comment"; 3 | import { Comment } from "../types/comments"; 4 | 5 | const usePostComments = (postId: number) => { 6 | const queryClient = useQueryClient(); 7 | const { isLoading, data, error } = useQuery('getComments', () => GetComments(postId)); 8 | 9 | const handleError = (error: unknown) => console.error(error); 10 | const handleSuccess = async () => await queryClient.invalidateQueries('getComments'); 11 | 12 | const reportComment = async (...args: Parameters) => { 13 | try { 14 | await ReportComment(...args); 15 | await handleSuccess(); 16 | } catch (e) { 17 | handleError(e); 18 | } 19 | } 20 | 21 | const postComment = async (...args: Parameters) => { 22 | try { 23 | await PostComment(...args); 24 | await handleSuccess(); 25 | } catch (e) { 26 | handleError(e); 27 | } 28 | } 29 | 30 | return { data, isLoading, error, reportComment, postComment }; 31 | }; 32 | 33 | export default usePostComments; -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | } 5 | 6 | module.exports = nextConfig 7 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "strapi-plugin-comments-example-frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "bootstrap": "^5.1.3", 13 | "formik": "^2.2.9", 14 | "next": "12.1.6", 15 | "react": "18.1.0", 16 | "react-bootstrap": "^2.4.0", 17 | "react-dom": "18.1.0", 18 | "react-query": "^3.39.1", 19 | "styled-components": "^5.3.5" 20 | }, 21 | "devDependencies": { 22 | "@types/node": "17.0.42", 23 | "@types/react": "18.0.12", 24 | "@types/react-dom": "18.0.5", 25 | "@types/styled-components": "^5.1.25", 26 | "eslint": "8.17.0", 27 | "eslint-config-next": "12.1.6", 28 | "typescript": "4.7.3" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/pages/[slug].tsx: -------------------------------------------------------------------------------- 1 | import { GetStaticPaths, GetStaticProps } from "next/types"; 2 | import CommentsList from "../components/Comments"; 3 | import { Post } from "../types/comments"; 4 | 5 | interface IProps { 6 | post: Post; 7 | } 8 | 9 | const PostDetails: React.FC = ({ post }) => { 10 | const { id, attributes } = post; 11 | return ( 12 | <> 13 |
14 |

{attributes.Title}

15 |

{attributes.Description}

16 |
17 | {attributes.Content.split('\n').map((item, index) =>

{item}

)} 18 |
19 | 20 | 21 | ); 22 | } 23 | 24 | export const getStaticPaths: GetStaticPaths = async () => { 25 | const res = await fetch('http://localhost:1337/api/posts'); 26 | const { data: posts }: { data: Post[] } = await res.json(); 27 | const paths = posts.map(post => ({ params: { slug: post.attributes.Slug } })); 28 | 29 | return { 30 | paths, 31 | fallback: true, 32 | } 33 | } 34 | 35 | export const getStaticProps: GetStaticProps = async ({ params }: any) => { 36 | const { slug } = params; 37 | const resPost = await fetch(`http://localhost:1337/api/posts?filters[slug][$eq]=${slug}`); 38 | const { data } = await resPost.json(); 39 | const post: Post = data[0]; 40 | return { 41 | props: { 42 | post 43 | } 44 | } 45 | } 46 | 47 | export default PostDetails; -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import 'bootstrap/dist/css/bootstrap.min.css'; 2 | import type { AppProps } from 'next/app'; 3 | import MainLayout from '../components/MainLayout'; 4 | import { QueryClient, QueryClientProvider } from 'react-query'; 5 | 6 | const queryClient = new QueryClient(); 7 | 8 | function MyApp({ Component, pageProps }: AppProps) { 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | } 17 | 18 | export default MyApp; 19 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import type { GetStaticProps, NextPage } from 'next' 2 | import { Card } from 'react-bootstrap'; 3 | import { Post } from '../types/comments' 4 | 5 | interface IProps { 6 | posts: Post[]; 7 | } 8 | 9 | const Home: NextPage = ({ posts }) => { 10 | return ( 11 |
12 | {posts.map(({ id, attributes }) => ( 13 | 14 | 15 | {attributes.Title} 16 | {attributes.Slug} 17 | 18 | {attributes.Description} 19 | 20 | Details 21 | Api Link 22 | 23 | 24 | ))} 25 |
26 | ) 27 | } 28 | 29 | export const getStaticProps: GetStaticProps = async () => { 30 | const res = await fetch(`http://localhost:1337/api/posts`); 31 | const { data: posts }: { data: Post[] } = await res.json(); 32 | 33 | return { 34 | props: { 35 | posts, 36 | } 37 | } 38 | } 39 | 40 | export default Home 41 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-nextjs-comments/next-app/public/favicon.ico -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true 17 | }, 18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 19 | "exclude": ["node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/next-app/types/comments.ts: -------------------------------------------------------------------------------- 1 | export type Post = { 2 | id: number; 3 | attributes: { 4 | Title: string; 5 | Slug: string; 6 | Description: string; 7 | Content: string; 8 | } 9 | } 10 | 11 | export type Author = { 12 | id: number | string; 13 | name: string; 14 | email: string; 15 | } 16 | 17 | export type ReportReason = "BAD_WORDS" | "OTHER" | "DISCRIMINATION"; 18 | export type Report = { 19 | reason: ReportReason; 20 | content: string; 21 | } 22 | 23 | export type Comment = { 24 | id: number; 25 | content: string; 26 | createdAt: string; 27 | author: Author; 28 | blocked: boolean; 29 | } -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{package.json,*.yml}] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/.env.example: -------------------------------------------------------------------------------- 1 | HOST=0.0.0.0 2 | PORT=1337 3 | APP_KEYS= 4 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/.eslintignore: -------------------------------------------------------------------------------- 1 | .cache 2 | build 3 | **/node_modules/** 4 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "eslint:recommended", 4 | "env": { 5 | "commonjs": true, 6 | "es6": true, 7 | "node": true, 8 | "browser": false 9 | }, 10 | "parserOptions": { 11 | "ecmaFeatures": { 12 | "experimentalObjectRestSpread": true, 13 | "jsx": false 14 | }, 15 | "sourceType": "module" 16 | }, 17 | "globals": { 18 | "strapi": true 19 | }, 20 | "rules": { 21 | "indent": ["error", 2, { "SwitchCase": 1 }], 22 | "linebreak-style": ["error", "unix"], 23 | "no-console": 0, 24 | "quotes": ["error", "single"], 25 | "semi": ["error", "always"] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/config/admin.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | auth: { 3 | secret: env('ADMIN_JWT_SECRET'), 4 | }, 5 | apiToken: { 6 | salt: env('API_TOKEN_SALT'), 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/config/api.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rest: { 3 | defaultLimit: 25, 4 | maxLimit: 100, 5 | withCount: true, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/config/database.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = ({ env }) => ({ 4 | connection: { 5 | client: 'sqlite', 6 | connection: { 7 | filename: path.join(__dirname, '..', env('DATABASE_FILENAME', '.tmp/data.db')), 8 | }, 9 | useNullAsDefault: true, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/config/middlewares.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | 'strapi::errors', 3 | 'strapi::security', 4 | 'strapi::cors', 5 | 'strapi::poweredBy', 6 | 'strapi::logger', 7 | 'strapi::query', 8 | 'strapi::body', 9 | 'strapi::session', 10 | 'strapi::favicon', 11 | 'strapi::public', 12 | ]; 13 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/config/plugins.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | comments: { 3 | enable: true, 4 | config: { 5 | moderatorRoles: [], 6 | badWords: true, 7 | enabledCollections: [ 'api::post.post' ], 8 | approvalFlow: [], 9 | entryLabel: { 10 | 'api::post.post': [ 'Title' ] 11 | }, 12 | reportReasons: { 13 | BAD_LANGUAGE: 'BAD_LANGUAGE', 14 | DISCRIMINATION: 'DISCRIMINATION', 15 | OTHER: 'OTHER' 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/config/server.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | host: env('HOST', '0.0.0.0'), 3 | port: env.int('PORT', 1337), 4 | app: { 5 | keys: env.array('APP_KEYS'), 6 | }, 7 | }); 8 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/database/migrations/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-nextjs-comments/strapi-app/database/migrations/.gitkeep -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-nextjs-comments/strapi-app/favicon.ico -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "strapi-plugin-comments-example", 3 | "private": true, 4 | "version": "0.1.0", 5 | "description": "Example of strapi-plugin-comments usage", 6 | "scripts": { 7 | "develop": "strapi develop", 8 | "start": "strapi start", 9 | "build": "strapi build", 10 | "strapi": "strapi" 11 | }, 12 | "devDependencies": {}, 13 | "dependencies": { 14 | "@strapi/plugin-i18n": "4.1.12", 15 | "@strapi/plugin-users-permissions": "4.1.12", 16 | "@strapi/strapi": "4.1.12", 17 | "better-sqlite3": "7.4.6", 18 | "strapi-plugin-comments": "^2.1.7" 19 | }, 20 | "author": { 21 | "name": "VirtusLab", 22 | "email": "strapi@virtuslab.com", 23 | "url": "https://virtuslab.com" 24 | }, 25 | "maintainers": [ 26 | { 27 | "name": "VirtusLab // Maciej Witkowski", 28 | "email": "mwitkowski@virtuslab.com", 29 | "url": "https://virtuslab.com" 30 | } 31 | ], 32 | "strapi": { 33 | "uuid": "94e27b44-cb95-4487-bf0c-973fdcc69f4d" 34 | }, 35 | "engines": { 36 | "node": ">=12.x.x <=16.x.x", 37 | "npm": ">=6.0.0" 38 | }, 39 | "license": "MIT" 40 | } 41 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/public/robots.txt: -------------------------------------------------------------------------------- 1 | # To prevent search engines from seeing the site altogether, uncomment the next two lines: 2 | # User-Agent: * 3 | # Disallow: / 4 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/public/uploads/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-nextjs-comments/strapi-app/public/uploads/.gitkeep -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/src/admin/app.example.js: -------------------------------------------------------------------------------- 1 | export default { 2 | config: { 3 | locales: [ 4 | // 'ar', 5 | // 'fr', 6 | // 'cs', 7 | // 'de', 8 | // 'dk', 9 | // 'es', 10 | // 'he', 11 | // 'id', 12 | // 'it', 13 | // 'ja', 14 | // 'ko', 15 | // 'ms', 16 | // 'nl', 17 | // 'no', 18 | // 'pl', 19 | // 'pt-BR', 20 | // 'pt', 21 | // 'ru', 22 | // 'sk', 23 | // 'sv', 24 | // 'th', 25 | // 'tr', 26 | // 'uk', 27 | // 'vi', 28 | // 'zh-Hans', 29 | // 'zh', 30 | ], 31 | }, 32 | bootstrap(app) { 33 | console.log(app); 34 | }, 35 | }; 36 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/src/admin/webpack.config.example.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* eslint-disable no-unused-vars */ 4 | module.exports = (config, webpack) => { 5 | // Note: we provide webpack above so you should not `require` it 6 | // Perform customizations to webpack config 7 | // Important: return the modified config 8 | return config; 9 | }; 10 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/src/api/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-nextjs-comments/strapi-app/src/api/.gitkeep -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/src/api/post/content-types/post/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "collectionType", 3 | "collectionName": "posts", 4 | "info": { 5 | "singularName": "post", 6 | "pluralName": "posts", 7 | "displayName": "Post", 8 | "description": "" 9 | }, 10 | "options": { 11 | "draftAndPublish": true 12 | }, 13 | "pluginOptions": {}, 14 | "attributes": { 15 | "Title": { 16 | "type": "string" 17 | }, 18 | "Slug": { 19 | "type": "string", 20 | "unique": true 21 | }, 22 | "Description": { 23 | "type": "text" 24 | }, 25 | "Content": { 26 | "type": "richtext" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/src/api/post/controllers/post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * post controller 5 | */ 6 | 7 | const { createCoreController } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreController('api::post.post'); 10 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/src/api/post/routes/post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * post router. 5 | */ 6 | 7 | const { createCoreRouter } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreRouter('api::post.post'); 10 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/src/api/post/services/post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * post service. 5 | */ 6 | 7 | const { createCoreService } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreService('api::post.post'); 10 | -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/src/bootstrap/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "posts": [ 3 | { 4 | "Title": "First Post", 5 | "Slug": "first-post", 6 | "Description": "Example post content type with basic fields...", 7 | "Content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sed blandit sem. Proin quis leo elementum, volutpat arcu in, suscipit dolor. Quisque in nibh justo. Nulla facilisi. Mauris vitae nisi luctus, blandit libero in, pellentesque sapien. Integer nec tempor mi. In aliquet imperdiet ornare. In dolor ex, facilisis fermentum ex ac, consequat laoreet ligula. Nullam mattis augue ac tellus dapibus ornare. Donec vestibulum, urna vitae efficitur finibus, quam metus vestibulum libero, eu accumsan nisi leo eget est. Fusce vitae metus vitae tortor mattis laoreet. Sed ut urna ante. Etiam tellus neque, laoreet eu orci nec, tincidunt blandit turpis. Duis ut nisl non turpis aliquet lacinia. Vestibulum metus mi, pellentesque vitae fringilla et, egestas eget elit. Fusce nec mattis quam, at semper justo.\\n\\nMaecenas hendrerit tempor mauris vel consectetur. Proin lectus tellus, luctus sed commodo vitae, volutpat id urna. Fusce ultrices felis nisl, at lobortis elit dignissim nec. Aliquam pretium venenatis urna, et blandit urna porta ut. Curabitur quis neque vel mi lacinia varius. Curabitur sed pulvinar quam. Quisque pharetra sem nec metus vestibulum accumsan. Maecenas laoreet dictum augue, a mollis purus faucibus et. In hac habitasse platea dictumst. In non accumsan mi. Cras eget luctus ante. Duis vehicula nibh et nunc vehicula, quis viverra ipsum fringilla. Curabitur interdum odio nulla, id dictum ipsum laoreet eu.\\n\\nSed felis odio, elementum eget elit a, tempus interdum turpis. Aenean nisl velit, volutpat et interdum ac, blandit tempus neque. Aenean ultricies erat at ex efficitur, in consequat odio lobortis. Fusce posuere quam eget enim lacinia, at ultricies orci mattis. Nullam lorem ante, maximus bibendum odio eu, tincidunt sagittis justo. Nulla facilisi. Sed orci eros, sollicitudin at imperdiet ut, interdum ac diam. Maecenas fringilla mollis dapibus. Nullam nec velit ac libero pharetra suscipit ac quis nisl. Proin vulputate libero mattis, pretium ex sit amet, tristique odio. Phasellus ultrices lorem in sodales ullamcorper. Phasellus gravida euismod dolor, vitae fringilla neque tempor bibendum. Fusce tempor scelerisque purus vel vehicula. Suspendisse vitae ligula neque. Mauris auctor sagittis dolor ac tincidunt.", 8 | "createdAt": "1656170873413", 9 | "updatedAt": "1656170873413" 10 | }, 11 | { 12 | "Title": "Second Post", 13 | "Slug": "second-post", 14 | "Description": "Example post content type with basic fields...", 15 | "Content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer luctus, elit non finibus vehicula, purus odio mattis nulla, vitae rhoncus augue tellus vel est. Aliquam cursus purus in arcu malesuada, nec vestibulum arcu accumsan. Nullam enim tellus, pulvinar eu nunc sit amet, imperdiet tempor nisl. Mauris pellentesque purus ut lacus rhoncus condimentum. Nulla facilisi. In hac habitasse platea dictumst. Phasellus commodo libero augue, id eleifend urna maximus sit amet. Phasellus eget tincidunt odio, a cursus ligula. In sit amet hendrerit arcu. Suspendisse eget diam cursus, fermentum nisi quis, iaculis lorem. Fusce volutpat est nulla, quis porttitor sapien dictum nec. Phasellus quis velit vel risus sodales pretium. Morbi at interdum felis. Aenean mi enim, aliquet a vulputate eget, feugiat eget nisl.\\n\\nAliquam placerat quam a felis tristique, quis facilisis risus tristique. Nullam in porta lorem. Aliquam facilisis ultricies molestie. Donec nunc tortor, pulvinar sed nibh quis, placerat fringilla nisl. Vestibulum vehicula orci vitae nisl dictum efficitur. Integer eget ipsum mollis, vestibulum felis sed, varius justo. Sed rhoncus mi non lorem condimentum luctus.\\n\\nDonec iaculis quam quis finibus iaculis. Suspendisse cursus volutpat quam a elementum. Vivamus ut justo a nisl faucibus viverra. Etiam lacus arcu, fringilla vitae fermentum vel, tempus eget nisi. Morbi in commodo quam. Suspendisse in diam sit amet libero suscipit molestie. Maecenas venenatis dignissim dui vel blandit. In sit amet nulla scelerisque, viverra nulla sed, convallis felis. Aenean tristique libero in pellentesque iaculis. Pellentesque ut gravida nisl. Aliquam sit amet ligula elit. Curabitur sit amet quam eu massa eleifend tincidunt. Nulla suscipit ligula nec vulputate cursus. Praesent neque metus, consequat ac suscipit at, sagittis sit amet orci.", 16 | "createdAt": "1656069830871", 17 | "updatedAt": "1656170889300" 18 | }, 19 | { 20 | "Title": "Third Post", 21 | "Slug": "third-post", 22 | "Description": "Example post content type with basic fields...", 23 | "Content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec magna sit amet sem tincidunt pellentesque et nec sem. Fusce vitae ultricies ex. Donec commodo turpis dui, at iaculis nibh pulvinar in. Nullam sed sapien eget diam tincidunt fermentum. Mauris ut vehicula enim, in laoreet orci. Maecenas lobortis tortor justo, ut aliquet ligula condimentum eu. Donec et aliquet elit. Nunc leo erat, ullamcorper quis rutrum vel, mattis in ante. Curabitur vestibulum sollicitudin nulla et maximus. Morbi et nisi mattis, pretium odio vitae, viverra neque. Donec dapibus pulvinar est et varius. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur velit ante, dapibus non finibus sit amet, porta ut turpis. Phasellus dapibus, nibh a tempor efficitur, risus tortor euismod ante, vel fermentum metus tortor in leo. Vestibulum ultricies erat ut molestie consectetur. Vivamus accumsan tempor sagittis.\n\nNullam vitae commodo enim, non malesuada neque. Quisque laoreet condimentum sem, non hendrerit purus tincidunt sed. Cras convallis tortor laoreet est condimentum commodo. Phasellus tempor venenatis nisl a maximus. Cras sagittis consequat odio non egestas. Cras et diam quis ligula feugiat finibus quis non urna. Donec ornare massa leo, quis condimentum quam aliquam in. Nulla auctor urna et arcu dictum aliquam. Sed vitae ligula enim. Curabitur vitae faucibus ex, et lacinia purus. Curabitur feugiat commodo magna, in luctus nunc eleifend id. Donec sit amet orci ut tellus ornare congue. Ut lacinia nisi id leo sollicitudin, a pretium elit commodo. Mauris placerat enim vel ipsum lacinia placerat. Aliquam vitae ante aliquam, malesuada magna vel, consectetur dolor. Vestibulum egestas eget enim sit amet pulvinar.\n\nProin iaculis bibendum dapibus. Vivamus ac dolor diam. Ut vulputate lacus eget sem viverra, et semper massa aliquet. Nulla congue lectus quis tellus pharetra, eget sodales tellus sagittis. Etiam libero nunc, pulvinar id lorem non, hendrerit imperdiet leo. Etiam nec turpis urna. Pellentesque in diam et augue semper dictum.", 24 | "createdAt": "1656069898707", 25 | "updatedAt": "1656170909136" 26 | } 27 | ], 28 | "comments": [ 29 | { 30 | "content": "Example Comment 1", 31 | "blocked": false, 32 | "blockedThread": false, 33 | "blockReason": null, 34 | "authorId": "maciekwitkowski322_gmail.com", 35 | "authorName": "Maciej Witkowski", 36 | "authorEmail": "maciekwitkowski322@gmail.com", 37 | "authorAvatar": null, 38 | "removed": null, 39 | "approvalStatus": null, 40 | "related": "api::post.post:1", 41 | "createdAt": "2022-06-25T19:09:38.963Z", 42 | "updatedAt": "2022-06-25T19:09:38.963Z" 43 | }, 44 | { 45 | "content": "Example Comment 2", 46 | "blocked": false, 47 | "blockedThread": false, 48 | "blockReason": null, 49 | "authorId": "maciekwitkowski322_gmail.com", 50 | "authorName": "Maciej Witkowski", 51 | "authorEmail": "maciekwitkowski322@gmail.com", 52 | "authorAvatar": null, 53 | "removed": null, 54 | "approvalStatus": null, 55 | "related": "api::post.post:1", 56 | "createdAt": "2022-06-26T13:57:39.343Z", 57 | "updatedAt": "2022-06-26T13:57:39.343Z" 58 | }, 59 | { 60 | "content": "Example Comment 3", 61 | "blocked": false, 62 | "blockedThread": false, 63 | "blockReason": null, 64 | "authorId": "maciekwitkowski322_gmail.com", 65 | "authorName": "Maciej Witkowski", 66 | "authorEmail": "maciekwitkowski322@gmail.com", 67 | "authorAvatar": null, 68 | "removed": null, 69 | "approvalStatus": null, 70 | "related": "api::post.post:1", 71 | "createdAt": "2022-06-26T14:01:56.205Z", 72 | "updatedAt": "2022-06-26T14:01:56.205Z" 73 | } 74 | ] 75 | } -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/src/bootstrap/index.js: -------------------------------------------------------------------------------- 1 | const { posts, comments } = require('./data.json'); 2 | async function isFirstRun() { 3 | const pluginStore = strapi.store({ 4 | environment: strapi.config.environment, 5 | type: "type", 6 | name: "setup", 7 | }); 8 | const initHasRun = await pluginStore.get({ key: "initHasRun" }); 9 | await pluginStore.set({ key: "initHasRun", value: true }); 10 | return !initHasRun; 11 | } 12 | 13 | async function setPublicPermissions(newPermissions) { 14 | const publicRole = await strapi 15 | .query("plugin::users-permissions.role") 16 | .findOne({ 17 | where: { 18 | type: "public", 19 | }, 20 | }); 21 | 22 | const allPermissionsToCreate = []; 23 | Object.keys(newPermissions).map((controller) => { 24 | const actions = newPermissions[controller]; 25 | const permissionsToCreate = actions.map((action) => { 26 | return strapi.query("plugin::users-permissions.permission").create({ 27 | data: { 28 | action: `${controller}.${action}`, 29 | role: publicRole.id, 30 | }, 31 | }); 32 | }); 33 | allPermissionsToCreate.push(...permissionsToCreate); 34 | }); 35 | await Promise.all(allPermissionsToCreate); 36 | } 37 | 38 | async function createEntry({ uid, entry }) { 39 | try { 40 | await strapi.entityService.create(uid, { 41 | data: entry, 42 | }); 43 | } catch (error) { 44 | console.error({ uid, entry, error }); 45 | } 46 | } 47 | 48 | async function importPosts() { 49 | for (const post of posts) { 50 | await createEntry({ 51 | uid: "api::post.post", 52 | entry: { 53 | ...post, 54 | publishedAt: Date.now(), // Make sure it's not draft 55 | }, 56 | }); 57 | } 58 | console.log(`Imported ${posts.length} posts from 'data.json'`) 59 | } 60 | 61 | async function importComments() { 62 | for (const comment of comments) { 63 | await createEntry({ 64 | uid: "plugin::comments.comment", 65 | entry: comment, 66 | }); 67 | } 68 | console.log(`Imported ${comments.length} comments from 'data.json'`) 69 | } 70 | 71 | async function importSeedData() { 72 | await setPublicPermissions({ 73 | "api::post.post": ["find", "findOne"], 74 | "plugin::comments.client": ["findAllFlat", "findAllInHierarchy", "post", "put", "removeComment", "reportAbuse"], 75 | }); 76 | 77 | await importPosts(); 78 | await importComments(); 79 | } 80 | 81 | module.exports = async () => { 82 | const shouldImportSeedData = await isFirstRun(); 83 | 84 | if (shouldImportSeedData) { 85 | try { 86 | await importSeedData(); 87 | console.log("Data imported"); 88 | } catch (error) { 89 | console.log("Could not import seed data"); 90 | console.error(error); 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/src/extensions/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-nextjs-comments/strapi-app/src/extensions/.gitkeep -------------------------------------------------------------------------------- /strapi-nextjs-comments/strapi-app/src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const bootstrap = require('./bootstrap') 3 | module.exports = { 4 | register() {}, 5 | bootstrap, 6 | }; 7 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/README.md: -------------------------------------------------------------------------------- 1 | # Strapi Plugin Navigation example with NextJS 2 | 3 | This example is set up to show how to create a project with our navigation plugin installed as well as integrate it with a sample frontend. 4 | 5 | ## 🔧 Getting Started 6 | 7 | To run this project, you need to prepare two shell windows. One window will be used to set up and run strapi server and the second one will be used to run development server for nextjs frontend. 8 | 9 | ### Strapi Server 10 | 11 | Install all packages 12 | 13 | ```sh 14 | cd ./strapi-app 15 | yarn install 16 | ``` 17 | 18 | Run the server 19 | 20 | > Before running the strapi server be sure to create your own `.env` file. Example of this file can be found in strapi app folder. 21 | ```sh 22 | yarn build 23 | yarn develop 24 | # or 25 | yarn develop --watch-admin 26 | ``` 27 | 28 | After that open strapi admin panel and create admin user. The strapi project should be ready to use at this point. 29 | 30 | ### NextJS development server 31 | 32 | Install all packages 33 | ```sh 34 | cd ./next-app 35 | yarn install 36 | ``` 37 | 38 | Run the server 39 | ```sh 40 | yarn dev 41 | ``` 42 | 43 | After that the nextJs frontend should be ready to use. You can direct to `localhost:3000` to see it. -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "next/babel" 4 | ], 5 | "plugins": [ 6 | [ 7 | "styled-components", 8 | { 9 | "ssr": true, 10 | "displayName": true, 11 | "preprocess": false 12 | } 13 | ] 14 | ] 15 | } -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/.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 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/api/index.ts: -------------------------------------------------------------------------------- 1 | import { NavigationItemFlat, NavigationItemTree } from "../types/navigation"; 2 | 3 | export const fetchMainNavigation = async (idOrSlug: string | number) => { 4 | const res = await fetch(`http://localhost:1337/api/navigation/render/${idOrSlug}?type=TREE`) 5 | const data: NavigationItemTree[] = await res.json(); 6 | return data; 7 | } 8 | 9 | export const fetchFooterNavigation = async () => { 10 | const res = await fetch("http://localhost:1337/api/navigation/render/2?type=FLAT"); 11 | const data: NavigationItemFlat[] = await res.json(); 12 | return data; 13 | } -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/components/Footer/index.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { NavigationItemFlat } from "../../types/navigation"; 3 | import Link from "next/link"; 4 | import { fetchFooterNavigation } from "../../api"; 5 | 6 | const MainFooter = () => { 7 | const [footerItems, setFooterItems] = useState([]); 8 | useEffect(() => { 9 | fetchFooterNavigation() 10 | .then(setFooterItems) 11 | .catch(e => console.error(e)); 12 | }, []); 13 | 14 | return ( 15 |
16 |
17 |

Created by VirtusLab

18 |
    19 | {footerItems.map((navItem) => { 20 | const isExternal = navItem.type === "EXTERNAL"; 21 | return ( 22 | 23 |
  • 24 | {navItem.title} 25 |
  • 26 | 27 | ); 28 | })} 29 |
30 |
31 |
32 | ); 33 | } 34 | 35 | export default MainFooter; -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/components/MainLayout/index.tsx: -------------------------------------------------------------------------------- 1 | import { Container } from "react-bootstrap"; 2 | import Footer from "../Footer"; 3 | import Navbar from "../Navbar"; 4 | 5 | const MainLayout: React.FC = ({ children }) => { 6 | return ( 7 |
8 | 9 | 10 | {children} 11 | 12 |
13 |
14 | ); 15 | } 16 | 17 | export default MainLayout; -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/components/Navbar/index.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { NavigationItemTree } from "../../types/navigation"; 3 | import { Container, Nav, Navbar } from 'react-bootstrap'; 4 | import Link from "next/link"; 5 | import List from "./list"; 6 | import { fetchMainNavigation } from "../../api"; 7 | 8 | interface IProps { 9 | idOrSlug?: number | string; 10 | } 11 | 12 | const MainNavbar: React.FC = ({ idOrSlug = 1 }) => { 13 | const [navigationItems, setNavigationItems] = useState([]); 14 | useEffect(() => { 15 | fetchMainNavigation(idOrSlug) 16 | .then(setNavigationItems) 17 | .catch(e => console.error(e)); 18 | }, [idOrSlug]); 19 | 20 | return ( 21 | 22 | 23 | 24 | 25 | Strapi Plugin Navigation Example 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | 36 | ); 37 | } 38 | 39 | export default MainNavbar; -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/components/Navbar/item.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import { Nav } from "react-bootstrap"; 3 | import { NavigationItemTree } from "../../types/navigation"; 4 | import List from "./list"; 5 | 6 | interface IProps { 7 | item: NavigationItemTree; 8 | level: number; 9 | } 10 | 11 | const Item: React.FC = ({ item, level }) => { 12 | return ( 13 | 14 | 15 | {item.title} 16 | 17 | {item.items && item.items.length ? : null} 18 | 19 | ); 20 | } 21 | 22 | export default Item; 23 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/components/Navbar/list.tsx: -------------------------------------------------------------------------------- 1 | import { NavigationItemTree } from "../../types/navigation"; 2 | import Item from "./item"; 3 | 4 | interface IProps { 5 | items: NavigationItemTree[]; 6 | level: number; 7 | } 8 | 9 | const List: React.FC = ({ items, level }) => { 10 | const preparedItems = items.map(item => ); 11 | return level > 0 12 | ?
{preparedItems}
13 | : <>{preparedItems}; 14 | } 15 | 16 | export default List; 17 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | } 5 | 6 | module.exports = nextConfig 7 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "strapi-plugin-comments-example-frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "bootstrap": "^5.1.3", 13 | "next": "12.1.6", 14 | "react": "18.1.0", 15 | "react-bootstrap": "^2.4.0", 16 | "react-dom": "18.1.0", 17 | "react-markdown": "^8.0.3", 18 | "styled-components": "^5.3.5" 19 | }, 20 | "devDependencies": { 21 | "@types/node": "17.0.40", 22 | "@types/react": "18.0.12", 23 | "@types/react-dom": "18.0.5", 24 | "@types/styled-components": "^5.1.25", 25 | "babel-plugin-styled-components": "^2.0.7", 26 | "eslint": "8.17.0", 27 | "eslint-config-next": "12.1.6", 28 | "typescript": "4.7.3" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/pages/[...path].tsx: -------------------------------------------------------------------------------- 1 | import Head from "next/head"; 2 | import { GetStaticPaths, GetStaticProps } from "next/types"; 3 | import styled from "styled-components"; 4 | import { NavigationItemTree } from "../types/navigation"; 5 | import ReactMarkdown from 'react-markdown'; 6 | 7 | type Page = { 8 | id: 1, 9 | title: string, 10 | content: string, 11 | name: string, 12 | } 13 | 14 | const Wrapper = styled.div` 15 | img[alt=logo] { 16 | max-width: 200px; 17 | } 18 | `; 19 | 20 | const PathPage = ({ page }: { page: Page }) => { 21 | const content = page.content || ""; 22 | const title = page.title || ""; 23 | return ( 24 | 25 | 26 | {title} 27 | 28 | {content} 29 | 30 | ); 31 | } 32 | 33 | export const getStaticPaths: GetStaticPaths = async () => { 34 | const res = await fetch('http://localhost:1337/api/navigation/render/1?type=TREE'); 35 | const data: NavigationItemTree[] = await res.json(); 36 | const internalItems = data.filter(item => item.type === "INTERNAL") as NavigationItemTree[]; 37 | const getPaths = (item: NavigationItemTree): string[] => item.type === "INTERNAL" ? item.items?.length ? [...item.items.map(getPaths).flat(), item.path] : [item.path] : []; 38 | const paths = internalItems.reduce((acc, current) => { 39 | return [...acc, ...getPaths(current)]; 40 | }, []); 41 | return { 42 | paths, 43 | fallback: true, 44 | } 45 | } 46 | 47 | export const getStaticProps: GetStaticProps = async ({ params }: any) => { 48 | const path = params.path.join('/'); 49 | const res = await fetch(`http://localhost:1337/api/navigation/render/1?path=/${path}&type=TREE`); 50 | const data: NavigationItemTree[] = await res.json(); 51 | const page = data[0].related; 52 | 53 | return { 54 | props: { 55 | page, 56 | } 57 | } 58 | } 59 | 60 | export default PathPage; 61 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import 'bootstrap/dist/css/bootstrap.min.css'; 2 | import '../styles/global.css'; 3 | import type { AppProps } from 'next/app' 4 | import MainLayout from '../components/MainLayout' 5 | 6 | function MyApp({ Component, pageProps }: AppProps) { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | 13 | } 14 | 15 | export default MyApp 16 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import type { NextPage } from 'next' 2 | import { useRouter } from 'next/router'; 3 | import { useEffect } from 'react'; 4 | 5 | const Home: NextPage = () => { 6 | const router = useRouter(); 7 | useEffect(() => { 8 | router.push('/home'); 9 | }, [router]); 10 | return ( 11 |
12 | Loading... 13 |
14 | ) 15 | } 16 | 17 | export default Home 18 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-nextjs-navigation/next-app/public/favicon.ico -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/styles/global.css: -------------------------------------------------------------------------------- 1 | .navbar-nav > .nav-link:hover > .dropdown-menu{ 2 | display: block; 3 | } 4 | 5 | .dropdown-menu > .nav-link:hover > .dropdown-menu{ 6 | display: block; 7 | position: absolute; 8 | top: 0; 9 | left: calc(0px + 100%); 10 | z-index: 1; 11 | } 12 | 13 | .nav-link { 14 | position: relative; 15 | } -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true 17 | }, 18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 19 | "exclude": ["node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/next-app/types/navigation.ts: -------------------------------------------------------------------------------- 1 | export type NavigationItemInternalFlat = { 2 | order: number; 3 | id: number; 4 | title: string; 5 | type: "INTERNAL"; 6 | path: string; 7 | uiRouterKey: string; 8 | menuAttached: boolean; 9 | related: unknown; 10 | } 11 | 12 | export type NavigationItemExternalFlat = { 13 | order: number; 14 | id: number; 15 | title: string; 16 | type: "EXTERNAL"; 17 | externalPath: string; 18 | uiRouterKey: string; 19 | menuAttached: boolean; 20 | } 21 | 22 | export type NavigationItemFlat = NavigationItemExternalFlat | NavigationItemInternalFlat; 23 | 24 | export type NavigationItemTree = { 25 | order: number; 26 | id: number; 27 | title: string; 28 | type: "INTERNAL" | "EXTERNAL"; 29 | path: string; 30 | uiRouterKey: string; 31 | menuAttached: boolean; 32 | related: unknown; 33 | items: NavigationItemTree[] | null; 34 | } 35 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{package.json,*.yml}] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/.env.example: -------------------------------------------------------------------------------- 1 | HOST=0.0.0.0 2 | PORT=1337 3 | APP_KEYS= 4 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/.eslintignore: -------------------------------------------------------------------------------- 1 | .cache 2 | build 3 | **/node_modules/** 4 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "eslint:recommended", 4 | "env": { 5 | "commonjs": true, 6 | "es6": true, 7 | "node": true, 8 | "browser": false 9 | }, 10 | "parserOptions": { 11 | "ecmaFeatures": { 12 | "experimentalObjectRestSpread": true, 13 | "jsx": false 14 | }, 15 | "sourceType": "module" 16 | }, 17 | "globals": { 18 | "strapi": true 19 | }, 20 | "rules": { 21 | "indent": ["error", 2, { "SwitchCase": 1 }], 22 | "linebreak-style": ["error", "unix"], 23 | "no-console": 0, 24 | "quotes": ["error", "single"], 25 | "semi": ["error", "always"] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/.gitignore: -------------------------------------------------------------------------------- 1 | ############################ 2 | # OS X 3 | ############################ 4 | 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | Icon 9 | .Spotlight-V100 10 | .Trashes 11 | ._* 12 | 13 | 14 | ############################ 15 | # Linux 16 | ############################ 17 | 18 | *~ 19 | 20 | 21 | ############################ 22 | # Windows 23 | ############################ 24 | 25 | Thumbs.db 26 | ehthumbs.db 27 | Desktop.ini 28 | $RECYCLE.BIN/ 29 | *.cab 30 | *.msi 31 | *.msm 32 | *.msp 33 | 34 | 35 | ############################ 36 | # Packages 37 | ############################ 38 | 39 | *.7z 40 | *.csv 41 | *.dat 42 | *.dmg 43 | *.gz 44 | *.iso 45 | *.jar 46 | *.rar 47 | *.tar 48 | *.zip 49 | *.com 50 | *.class 51 | *.dll 52 | *.exe 53 | *.o 54 | *.seed 55 | *.so 56 | *.swo 57 | *.swp 58 | *.swn 59 | *.swm 60 | *.out 61 | *.pid 62 | 63 | 64 | ############################ 65 | # Logs and databases 66 | ############################ 67 | 68 | .tmp 69 | *.log 70 | *.sql 71 | *.sqlite 72 | *.sqlite3 73 | 74 | 75 | ############################ 76 | # Misc. 77 | ############################ 78 | 79 | *# 80 | ssl 81 | .idea 82 | nbproject 83 | public/uploads/* 84 | !public/uploads/.gitkeep 85 | 86 | ############################ 87 | # Node.js 88 | ############################ 89 | 90 | lib-cov 91 | lcov.info 92 | pids 93 | logs 94 | results 95 | node_modules 96 | .node_history 97 | 98 | ############################ 99 | # Tests 100 | ############################ 101 | 102 | testApp 103 | coverage 104 | 105 | ############################ 106 | # Strapi 107 | ############################ 108 | 109 | .env 110 | license.txt 111 | exports 112 | *.cache 113 | build 114 | .strapi-updater.json 115 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/config/admin.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | auth: { 3 | secret: env('ADMIN_JWT_SECRET'), 4 | }, 5 | apiToken: { 6 | salt: env('API_TOKEN_SALT'), 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/config/api.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rest: { 3 | defaultLimit: 25, 4 | maxLimit: 100, 5 | withCount: true, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/config/database.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = ({ env }) => ({ 4 | connection: { 5 | client: 'sqlite', 6 | connection: { 7 | filename: path.join(__dirname, '..', env('DATABASE_FILENAME', '.tmp/data.db')), 8 | }, 9 | useNullAsDefault: true, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/config/middlewares.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | 'strapi::errors', 3 | 'strapi::security', 4 | 'strapi::cors', 5 | 'strapi::poweredBy', 6 | 'strapi::logger', 7 | 'strapi::query', 8 | 'strapi::body', 9 | 'strapi::session', 10 | 'strapi::favicon', 11 | 'strapi::public', 12 | ]; 13 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/config/plugins.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | navigation: { 3 | enable: true, 4 | config: 5 | { 6 | additionalFields: [], 7 | contentTypes: ['api::page.page'], 8 | contentTypesNameFields: { 9 | 'api::page.page': ['name'] 10 | }, 11 | contentTypesPopulate: {}, 12 | allowedLevels: 2, 13 | gql: { navigationItemRelated: ['Page'] }, 14 | i18nEnabled: false, 15 | pruneObsoleteI18nNavigations: false, 16 | }, 17 | } 18 | } -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/config/server.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | host: env('HOST', '0.0.0.0'), 3 | port: env.int('PORT', 1337), 4 | app: { 5 | keys: env.array('APP_KEYS'), 6 | }, 7 | }); 8 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/database/migrations/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-nextjs-navigation/strapi-app/database/migrations/.gitkeep -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-nextjs-navigation/strapi-app/favicon.ico -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "strapi-plugin-comments-example", 3 | "private": true, 4 | "version": "0.1.0", 5 | "description": "Example of strapi-plugin-comments usage", 6 | "scripts": { 7 | "develop": "strapi develop", 8 | "start": "strapi start", 9 | "build": "strapi build", 10 | "strapi": "strapi" 11 | }, 12 | "devDependencies": {}, 13 | "dependencies": { 14 | "@strapi/plugin-i18n": "4.1.12", 15 | "@strapi/plugin-users-permissions": "4.1.12", 16 | "@strapi/strapi": "4.1.12", 17 | "better-sqlite3": "7.4.6", 18 | "strapi-plugin-navigation": "2.1.0" 19 | }, 20 | "author": { 21 | "name": "VirtusLab", 22 | "email": "strapi@virtuslab.com", 23 | "url": "https://virtuslab.com" 24 | }, 25 | "maintainers": [ 26 | { 27 | "name": "VirtusLab // Maciej Witkowski", 28 | "email": "mwitkowski@virtuslab.com", 29 | "url": "https://virtuslab.com" 30 | } 31 | ], 32 | "strapi": { 33 | "uuid": "94e27b44-cb95-4487-bf0c-973fdcc69f4d" 34 | }, 35 | "engines": { 36 | "node": ">=12.x.x <=16.x.x", 37 | "npm": ">=6.0.0" 38 | }, 39 | "license": "MIT" 40 | } -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/public/robots.txt: -------------------------------------------------------------------------------- 1 | # To prevent search engines from seeing the site altogether, uncomment the next two lines: 2 | # User-Agent: * 3 | # Disallow: / 4 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/public/uploads/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-nextjs-navigation/strapi-app/public/uploads/.gitkeep -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/src/admin/app.example.js: -------------------------------------------------------------------------------- 1 | export default { 2 | config: { 3 | locales: [ 4 | // 'ar', 5 | // 'fr', 6 | // 'cs', 7 | // 'de', 8 | // 'dk', 9 | // 'es', 10 | // 'he', 11 | // 'id', 12 | // 'it', 13 | // 'ja', 14 | // 'ko', 15 | // 'ms', 16 | // 'nl', 17 | // 'no', 18 | // 'pl', 19 | // 'pt-BR', 20 | // 'pt', 21 | // 'ru', 22 | // 'sk', 23 | // 'sv', 24 | // 'th', 25 | // 'tr', 26 | // 'uk', 27 | // 'vi', 28 | // 'zh-Hans', 29 | // 'zh', 30 | ], 31 | }, 32 | bootstrap(app) { 33 | console.log(app); 34 | }, 35 | }; 36 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/src/admin/webpack.config.example.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* eslint-disable no-unused-vars */ 4 | module.exports = (config, webpack) => { 5 | // Note: we provide webpack above so you should not `require` it 6 | // Perform customizations to webpack config 7 | // Important: return the modified config 8 | return config; 9 | }; 10 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/src/api/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-nextjs-navigation/strapi-app/src/api/.gitkeep -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/src/api/page/content-types/page/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "collectionType", 3 | "collectionName": "pages", 4 | "info": { 5 | "singularName": "page", 6 | "pluralName": "pages", 7 | "displayName": "Page", 8 | "description": "" 9 | }, 10 | "options": { 11 | "draftAndPublish": true 12 | }, 13 | "pluginOptions": { 14 | "i18n": { 15 | "localized": true 16 | } 17 | }, 18 | "attributes": { 19 | "name": { 20 | "type": "string", 21 | "required": true, 22 | "unique": true, 23 | "pluginOptions": { 24 | "i18n": { 25 | "localized": true 26 | } 27 | } 28 | }, 29 | "title": { 30 | "type": "string", 31 | "required": true, 32 | "pluginOptions": { 33 | "i18n": { 34 | "localized": true 35 | } 36 | } 37 | }, 38 | "content": { 39 | "type": "richtext", 40 | "pluginOptions": { 41 | "i18n": { 42 | "localized": true 43 | } 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/src/api/page/controllers/page.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * page controller 5 | */ 6 | 7 | const { createCoreController } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreController('api::page.page'); 10 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/src/api/page/routes/page.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * page router. 5 | */ 6 | 7 | const { createCoreRouter } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreRouter('api::page.page'); 10 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/src/api/page/services/page.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * page service. 5 | */ 6 | 7 | const { createCoreService } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreService('api::page.page'); 10 | -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/src/bootstrap/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | { 4 | "id": 1, 5 | "title": "Home Page", 6 | "content": "# Welcome to `strapi-plugin-navigation` example\n![logo](https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-plugin-navigation/master/public/assets/logo.png)\n\nIn this example you can find \"out\": \n\n- How to set up strapi project with navigation and internalisation plugins installed\n- How to configure navigation plugin to work with your content types\n- How to set up next.js project and consume strapi api\n- How to build dynamic navigation with strapi-plugin-navigation plugin", 7 | "createdAt": "2022-06-06T10:10:35.935Z", 8 | "updatedAt": "2022-06-14T11:57:32.421Z", 9 | "publishedAt": "2022-06-06T10:12:21.706Z", 10 | "name": "Home", 11 | "locale": "en" 12 | }, 13 | { 14 | "id": 2, 15 | "title": "About Navigation Plugin", 16 | "content": "# Strapi v4 - Navigation plugin\nCreate consumable navigation with a simple and straightforward visual builder.\n\nStrapi Navigation Plugin provides a website navigation / menu builder feature for [Strapi Headless CMS](https://github.com/strapi/strapi) admin panel. Navigation has the possibility to control the audience and can be consumed by the website with different output structure renderers:\n\n- Flat\n- Tree (nested)\n- RFR (ready for handling by Redux First Router)\n\n## ✨ Features\n\n- **Navigation Public API:** Simple and ready for use API endpoint for consuming the navigation structure you've created\n- **Visual builder:** Elegant and easy to use visual builder\n- **Any Content Type relation:** Navigation can by linked to any of your Content Types by default. Simply, you're controlling it and also limiting available content types by configuration props\n- **Different types of navigation items:** Create navigation with items linked to internal types, to external links or wrapper elements to keep structure clean \n- **Multiple navigations:** Create as many Navigation containers as you want, setup them and use in the consumer application\n- **Light / Dark mode compatible:** By design we're supporting Strapi ☀️ Light / 🌙 Dark modes \n- **Customizable:** Possibility to customize the options \"like\": available Content Types, Maximum level for \"attach to menu\", Additional fields (audience)\n- **Audit log:** integration with Strapi Molecules Audit Log plugin that provides changes track record", 17 | "createdAt": "2022-06-06T10:16:13.910Z", 18 | "updatedAt": "2022-06-06T10:28:45.073Z", 19 | "publishedAt": "2022-06-06T10:19:10.053Z", 20 | "name": "About", 21 | "locale": "en" 22 | }, 23 | { 24 | "id": 3, 25 | "title": "Find out more... ", 26 | "content": "# Find out more about our team\n- [Virtuslab](https://virtuslab.com/)\n- [Navigation Plugin](https://github.com/VirtusLab-Open-Source/strapi-plugin-navigation)\n- [Comments Plugin](https://github.com/VirtusLab-Open-Source/strapi-plugin-comments)\n- [Typescript utility for Strapi](https://github.com/VirtusLab-Open-Source/strapi-typed)", 27 | "createdAt": "2022-06-06T10:19:05.792Z", 28 | "updatedAt": "2022-06-06T10:30:11.728Z", 29 | "publishedAt": "2022-06-06T10:19:06.341Z", 30 | "name": "More", 31 | "locale": "en" 32 | }, 33 | { 34 | "id": 7, 35 | "title": "Contact Page", 36 | "content": "# Hejka to jest przykładowa strona ", 37 | "createdAt": "2022-06-08T07:58:16.352Z", 38 | "updatedAt": "2022-06-08T07:58:16.352Z", 39 | "publishedAt": null, 40 | "name": "Contact", 41 | "locale": "en" 42 | } 43 | ], 44 | "navigations": [ 45 | { 46 | "name": "Footer Navigation", 47 | "slug": "navigation-footer", 48 | "visible": true, 49 | "createdAt": "2022-06-06T12:11:44.090Z", 50 | "updatedAt": "2022-06-28T11:27:01.673Z" 51 | } 52 | ], 53 | "navigationItems": [ 54 | { 55 | "title": "Home Page", 56 | "type": "INTERNAL", 57 | "path": "home", 58 | "externalPath": null, 59 | "uiRouterKey": "home-page", 60 | "menuAttached": true, 61 | "order": 1, 62 | "collapsed": false, 63 | "createdAt": "2022-06-06T12:10:31.402Z", 64 | "updatedAt": "2022-06-15T13:37:48.038Z", 65 | "master": "1", 66 | "related": "1" 67 | }, 68 | { 69 | "title": "About Page", 70 | "type": "INTERNAL", 71 | "path": "about", 72 | "externalPath": null, 73 | "uiRouterKey": "about-page", 74 | "menuAttached": true, 75 | "order": 2, 76 | "collapsed": false, 77 | "createdAt": "2022-06-06T12:10:31.402Z", 78 | "updatedAt": "2022-06-15T13:37:48.038Z", 79 | "master": "1", 80 | "related": "2" 81 | }, 82 | { 83 | "title": "More Page", 84 | "type": "INTERNAL", 85 | "path": "more", 86 | "externalPath": null, 87 | "uiRouterKey": "more-page", 88 | "menuAttached": true, 89 | "order": 3, 90 | "collapsed": false, 91 | "createdAt": "2022-06-06T12:10:31.404Z", 92 | "updatedAt": "2022-06-15T13:37:48.039Z", 93 | "master": "1", 94 | "related": "3" 95 | }, 96 | { 97 | "title": "Strapi Docs", 98 | "type": "EXTERNAL", 99 | "path": null, 100 | "externalPath": "https://docs.strapi.io/", 101 | "uiRouterKey": "strapi-docs", 102 | "menuAttached": false, 103 | "order": 1, 104 | "collapsed": false, 105 | "createdAt": "2022-06-06T12:18:11.131Z", 106 | "updatedAt": "2022-06-06T12:18:11.131Z", 107 | "master": "2" 108 | }, 109 | { 110 | "title": "Navigation Plugin Docs", 111 | "type": "EXTERNAL", 112 | "path": null, 113 | "externalPath": "https://github.com/VirtusLab-Open-Source/strapi-plugin-navigation/", 114 | "uiRouterKey": "navigation-plugin-docs", 115 | "menuAttached": false, 116 | "order": 2, 117 | "collapsed": false, 118 | "createdAt": "2022-06-06T12:18:11.131Z", 119 | "updatedAt": "2022-06-06T12:18:11.131Z", 120 | "master": "2" 121 | }, 122 | { 123 | "title": "Internationalization Plugin Docs", 124 | "type": "EXTERNAL", 125 | "path": null, 126 | "externalPath": "https://docs.strapi.io/developer-docs/latest/plugins/i18n.html", 127 | "uiRouterKey": "internationalization-plugin-docs", 128 | "menuAttached": false, 129 | "order": 3, 130 | "collapsed": false, 131 | "createdAt": "2022-06-06T12:18:11.131Z", 132 | "updatedAt": "2022-06-06T12:18:11.131Z", 133 | "master": "2" 134 | } 135 | ], 136 | "navigationItemsRelations": [ 137 | { 138 | "related_id": "1", 139 | "related_type": "api::page.page", 140 | "field": "navigation", 141 | "order": 1, 142 | "master": "1", 143 | "createdAt": "2022-06-06T12:10:31.395Z", 144 | "updatedAt": "2022-06-06T12:10:31.395Z" 145 | }, 146 | { 147 | "related_id": "2", 148 | "related_type": "api::page.page", 149 | "field": "navigation", 150 | "order": 1, 151 | "master": "1", 152 | "createdAt": "2022-06-06T12:10:31.396Z", 153 | "updatedAt": "2022-06-06T12:10:31.396Z" 154 | }, 155 | { 156 | "related_id": "3", 157 | "related_type": "api::page.page", 158 | "field": "navigation", 159 | "order": 1, 160 | "master": "1", 161 | "createdAt": "2022-06-06T12:10:31.396Z", 162 | "updatedAt": "2022-06-06T12:10:31.396Z" 163 | } 164 | ] 165 | } -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/src/bootstrap/index.js: -------------------------------------------------------------------------------- 1 | const { pages, navigations, navigationItems, navigationItemsRelations } = require('./data.json'); 2 | async function isFirstRun() { 3 | const pluginStore = strapi.store({ 4 | environment: strapi.config.environment, 5 | type: "type", 6 | name: "setup", 7 | }); 8 | const initHasRun = await pluginStore.get({ key: "initHasRun" }); 9 | await pluginStore.set({ key: "initHasRun", value: true }); 10 | return !initHasRun; 11 | } 12 | 13 | async function setPublicPermissions(newPermissions) { 14 | const publicRole = await strapi 15 | .query("plugin::users-permissions.role") 16 | .findOne({ 17 | where: { 18 | type: "public", 19 | }, 20 | }); 21 | 22 | const allPermissionsToCreate = []; 23 | Object.keys(newPermissions).map((controller) => { 24 | const actions = newPermissions[controller]; 25 | const permissionsToCreate = actions.map((action) => { 26 | return strapi.query("plugin::users-permissions.permission").create({ 27 | data: { 28 | action: `${controller}.${action}`, 29 | role: publicRole.id, 30 | }, 31 | }); 32 | }); 33 | allPermissionsToCreate.push(...permissionsToCreate); 34 | }); 35 | await Promise.all(allPermissionsToCreate); 36 | } 37 | 38 | async function createEntry({ uid, entry }) { 39 | try { 40 | await strapi.entityService.create(uid, { 41 | data: entry, 42 | }); 43 | } catch (error) { 44 | console.error({ uid, entry, error }); 45 | } 46 | } 47 | 48 | async function importPages() { 49 | for (const page of pages) { 50 | await createEntry({ 51 | uid: "api::page.page", 52 | entry: { 53 | ...page, 54 | publishedAt: Date.now(), // Make sure it's not draft 55 | }, 56 | }); 57 | } 58 | console.log(`Imported ${pages.length} pages from 'data.json'`); 59 | } 60 | 61 | async function importNavigations() { 62 | for (const navigation of navigations) { 63 | await createEntry({ 64 | uid: "plugin::navigation.navigation", 65 | entry: navigation, 66 | }); 67 | } 68 | console.log(`Imported ${navigations.length} navigations from 'data.json'`); 69 | } 70 | 71 | async function importNavigationsItems() { 72 | for (const navigationItem of navigationItems) { 73 | await createEntry({ 74 | uid: "plugin::navigation.navigation-item", 75 | entry: navigationItem, 76 | }); 77 | } 78 | console.log(`Imported ${navigationItems.length} navigationItems from 'data.json'`); 79 | } 80 | 81 | async function importNavigationsItemsRelated() { 82 | for (const navigationItemsRelated of navigationItemsRelations) { 83 | await createEntry({ 84 | uid: "plugin::navigation.navigations-items-related", 85 | entry: navigationItemsRelated, 86 | }); 87 | } 88 | console.log(`Imported ${navigationItemsRelations.length} navigationItemsRelations from 'data.json'`); 89 | } 90 | 91 | async function importSeedData() { 92 | await setPublicPermissions({ 93 | "api::post.post": ["find", "findOne"], 94 | "plugin::navigation.client": ["render"], 95 | }); 96 | 97 | await importPages(); 98 | await importNavigations(); 99 | await importNavigationsItemsRelated(); 100 | await importNavigationsItems(); 101 | } 102 | 103 | module.exports = async () => { 104 | const shouldImportSeedData = await isFirstRun(); 105 | 106 | if (shouldImportSeedData) { 107 | try { 108 | await importSeedData(); 109 | console.log("Data imported"); 110 | } catch (error) { 111 | console.log("Could not import seed data"); 112 | console.error(error); 113 | } 114 | } 115 | } -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/src/extensions/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-nextjs-navigation/strapi-app/src/extensions/.gitkeep -------------------------------------------------------------------------------- /strapi-nextjs-navigation/strapi-app/src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const bootstrap = require('./bootstrap'); 3 | 4 | module.exports = { 5 | /** 6 | * An asynchronous register function that runs before 7 | * your application is initialized. 8 | * 9 | * This gives you an opportunity to extend code. 10 | */ 11 | register(/*{ strapi }*/) {}, 12 | 13 | /** 14 | * An asynchronous bootstrap function that runs before 15 | * your application gets started. 16 | * 17 | * This gives you an opportunity to set up your data model, 18 | * run jobs, or perform some special logic. 19 | */ 20 | bootstrap, 21 | }; 22 | -------------------------------------------------------------------------------- /strapi-plugin-comments/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{package.json,*.yml}] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /strapi-plugin-comments/.env.example: -------------------------------------------------------------------------------- 1 | HOST=0.0.0.0 2 | PORT=1337 3 | -------------------------------------------------------------------------------- /strapi-plugin-comments/.eslintignore: -------------------------------------------------------------------------------- 1 | .cache 2 | build 3 | **/node_modules/** 4 | -------------------------------------------------------------------------------- /strapi-plugin-comments/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "eslint:recommended", 4 | "env": { 5 | "commonjs": true, 6 | "es6": true, 7 | "node": true, 8 | "browser": false 9 | }, 10 | "parserOptions": { 11 | "ecmaFeatures": { 12 | "experimentalObjectRestSpread": true, 13 | "jsx": false 14 | }, 15 | "sourceType": "module" 16 | }, 17 | "globals": { 18 | "strapi": true 19 | }, 20 | "rules": { 21 | "indent": ["error", 2, { "SwitchCase": 1 }], 22 | "linebreak-style": ["error", "unix"], 23 | "no-console": 0, 24 | "quotes": ["error", "single"], 25 | "semi": ["error", "always"] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /strapi-plugin-comments/.nvmrc: -------------------------------------------------------------------------------- 1 | v14.9.0 -------------------------------------------------------------------------------- /strapi-plugin-comments/README.md: -------------------------------------------------------------------------------- 1 | # Strapi examples - Plugin: Comments 2 | 3 | https://github.com/VirtusLab/strapi-plugin-comments 4 | -------------------------------------------------------------------------------- /strapi-plugin-comments/api/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-plugin-comments/api/.gitkeep -------------------------------------------------------------------------------- /strapi-plugin-comments/api/blog-post/config/routes.json: -------------------------------------------------------------------------------- 1 | { 2 | "routes": [ 3 | { 4 | "method": "GET", 5 | "path": "/blog-posts", 6 | "handler": "blog-post.find", 7 | "config": { 8 | "policies": [] 9 | } 10 | }, 11 | { 12 | "method": "GET", 13 | "path": "/blog-posts/count", 14 | "handler": "blog-post.count", 15 | "config": { 16 | "policies": [] 17 | } 18 | }, 19 | { 20 | "method": "GET", 21 | "path": "/blog-posts/:id", 22 | "handler": "blog-post.findOne", 23 | "config": { 24 | "policies": [] 25 | } 26 | }, 27 | { 28 | "method": "POST", 29 | "path": "/blog-posts", 30 | "handler": "blog-post.create", 31 | "config": { 32 | "policies": [] 33 | } 34 | }, 35 | { 36 | "method": "PUT", 37 | "path": "/blog-posts/:id", 38 | "handler": "blog-post.update", 39 | "config": { 40 | "policies": [] 41 | } 42 | }, 43 | { 44 | "method": "DELETE", 45 | "path": "/blog-posts/:id", 46 | "handler": "blog-post.delete", 47 | "config": { 48 | "policies": [] 49 | } 50 | } 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /strapi-plugin-comments/api/blog-post/controllers/blog-post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/controllers.html#core-controllers) 5 | * to customize this controller 6 | */ 7 | 8 | module.exports = {}; 9 | -------------------------------------------------------------------------------- /strapi-plugin-comments/api/blog-post/models/blog-post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/models.html#lifecycle-hooks) 5 | * to customize this model 6 | */ 7 | 8 | module.exports = {}; 9 | -------------------------------------------------------------------------------- /strapi-plugin-comments/api/blog-post/models/blog-post.settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "collectionType", 3 | "collectionName": "blog_posts", 4 | "info": { 5 | "name": "Blog post" 6 | }, 7 | "options": { 8 | "increments": true, 9 | "timestamps": true, 10 | "draftAndPublish": true 11 | }, 12 | "attributes": { 13 | "Title": { 14 | "type": "string" 15 | }, 16 | "Content": { 17 | "type": "richtext" 18 | }, 19 | "comments": { 20 | "plugin": "comments", 21 | "collection": "comment", 22 | "via": "related" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /strapi-plugin-comments/api/blog-post/services/blog-post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/services.html#core-services) 5 | * to customize this service 6 | */ 7 | 8 | module.exports = {}; 9 | -------------------------------------------------------------------------------- /strapi-plugin-comments/config/custom.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | comments: { }, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /strapi-plugin-comments/config/database.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | defaultConnection: 'default', 3 | connections: { 4 | default: { 5 | connector: 'bookshelf', 6 | settings: { 7 | client: 'sqlite', 8 | filename: env('DATABASE_FILENAME', '.tmp/data.db'), 9 | }, 10 | options: { 11 | useNullAsDefault: true, 12 | }, 13 | }, 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /strapi-plugin-comments/config/functions/bootstrap.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * An asynchronous bootstrap function that runs before 5 | * your application gets started. 6 | * 7 | * This gives you an opportunity to set up your data model, 8 | * run jobs, or perform some special logic. 9 | * 10 | * See more details here: https://strapi.io/documentation/developer-docs/latest/concepts/configurations.html#bootstrap 11 | */ 12 | 13 | module.exports = () => {}; 14 | -------------------------------------------------------------------------------- /strapi-plugin-comments/config/functions/cron.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Cron config that gives you an opportunity 5 | * to run scheduled jobs. 6 | * 7 | * The cron format consists of: 8 | * [SECOND (optional)] [MINUTE] [HOUR] [DAY OF MONTH] [MONTH OF YEAR] [DAY OF WEEK] 9 | * 10 | * See more details here: https://strapi.io/documentation/developer-docs/latest/concepts/configurations.html#cron-tasks 11 | */ 12 | 13 | module.exports = { 14 | /** 15 | * Simple example. 16 | * Every monday at 1am. 17 | */ 18 | // '0 1 * * 1': () => { 19 | // 20 | // } 21 | }; 22 | -------------------------------------------------------------------------------- /strapi-plugin-comments/config/functions/responses/404.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = async (/* ctx */) => { 4 | // return ctx.notFound('My custom message 404'); 5 | }; 6 | -------------------------------------------------------------------------------- /strapi-plugin-comments/config/server.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | host: env('HOST', '0.0.0.0'), 3 | port: env.int('PORT', 1337), 4 | admin: { 5 | auth: { 6 | secret: env('ADMIN_JWT_SECRET', '26cbc137d5df719b20fde7897ab31aae'), 7 | }, 8 | }, 9 | }); 10 | -------------------------------------------------------------------------------- /strapi-plugin-comments/extensions/users-permissions/config/jwt.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | jwtSecret: process.env.JWT_SECRET || '0e6ef767-d170-43f4-aa74-57fbba57e2f1' 3 | }; -------------------------------------------------------------------------------- /strapi-plugin-comments/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-plugin-comments/favicon.ico -------------------------------------------------------------------------------- /strapi-plugin-comments/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "strapi-examples-comments", 3 | "private": true, 4 | "version": "0.1.0", 5 | "description": "Strapi examples - Plugin: Comments", 6 | "scripts": { 7 | "develop": "strapi develop --watch-admin", 8 | "start": "strapi start", 9 | "build": "strapi build", 10 | "strapi": "strapi" 11 | }, 12 | "devDependencies": {}, 13 | "dependencies": { 14 | "strapi": "3.6.1", 15 | "strapi-admin": "3.6.1", 16 | "strapi-utils": "3.6.1", 17 | "strapi-plugin-content-type-builder": "3.6.1", 18 | "strapi-plugin-content-manager": "3.6.1", 19 | "strapi-plugin-users-permissions": "3.6.1", 20 | "strapi-plugin-email": "3.6.1", 21 | "strapi-plugin-upload": "3.6.1", 22 | "strapi-plugin-comments": "^1.0.1", 23 | "strapi-connector-bookshelf": "3.6.1", 24 | "knex": "<0.20.0", 25 | "sqlite3": "latest" 26 | }, 27 | "author": { 28 | "name": "VirtusLab // Mateusz Ziarko", 29 | "email": "mziarko@virtuslab.com", 30 | "url": "https://virtuslab.com" 31 | }, 32 | "maintainers": [ 33 | { 34 | "name": "VirtusLab // Mateusz Ziarko", 35 | "email": "mziarko@virtuslab.com", 36 | "url": "https://virtuslab.com" 37 | } 38 | ], 39 | "strapi": { 40 | "uuid": "92d33c58-658c-46dc-ba4d-ac19bb9f97cc" 41 | }, 42 | "engines": { 43 | "node": ">=10.16.0 <=14.x.x", 44 | "npm": ">=6.0.0" 45 | }, 46 | "license": "MIT" 47 | } 48 | -------------------------------------------------------------------------------- /strapi-plugin-comments/public/robots.txt: -------------------------------------------------------------------------------- 1 | # To prevent search engines from seeing the site altogether, uncomment the next two lines: 2 | # User-Agent: * 3 | # Disallow: / 4 | -------------------------------------------------------------------------------- /strapi-plugin-comments/public/uploads/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-plugin-comments/public/uploads/.gitkeep -------------------------------------------------------------------------------- /strapi-plugin-navigation/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{package.json,*.yml}] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/.env.example: -------------------------------------------------------------------------------- 1 | HOST=0.0.0.0 2 | PORT=1337 3 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/.eslintignore: -------------------------------------------------------------------------------- 1 | .cache 2 | build 3 | **/node_modules/** 4 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "eslint:recommended", 4 | "env": { 5 | "commonjs": true, 6 | "es6": true, 7 | "node": true, 8 | "browser": false 9 | }, 10 | "parserOptions": { 11 | "ecmaFeatures": { 12 | "experimentalObjectRestSpread": true, 13 | "jsx": false 14 | }, 15 | "sourceType": "module" 16 | }, 17 | "globals": { 18 | "strapi": true 19 | }, 20 | "rules": { 21 | "indent": ["error", 2, { "SwitchCase": 1 }], 22 | "linebreak-style": ["error", "unix"], 23 | "no-console": 0, 24 | "quotes": ["error", "single"], 25 | "semi": ["error", "always"] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/.gitignore: -------------------------------------------------------------------------------- 1 | ############################ 2 | # OS X 3 | ############################ 4 | 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | Icon 9 | .Spotlight-V100 10 | .Trashes 11 | ._* 12 | 13 | 14 | ############################ 15 | # Linux 16 | ############################ 17 | 18 | *~ 19 | 20 | 21 | ############################ 22 | # Windows 23 | ############################ 24 | 25 | Thumbs.db 26 | ehthumbs.db 27 | Desktop.ini 28 | $RECYCLE.BIN/ 29 | *.cab 30 | *.msi 31 | *.msm 32 | *.msp 33 | 34 | 35 | ############################ 36 | # Packages 37 | ############################ 38 | 39 | *.7z 40 | *.csv 41 | *.dat 42 | *.dmg 43 | *.gz 44 | *.iso 45 | *.jar 46 | *.rar 47 | *.tar 48 | *.zip 49 | *.com 50 | *.class 51 | *.dll 52 | *.exe 53 | *.o 54 | *.seed 55 | *.so 56 | *.swo 57 | *.swp 58 | *.swn 59 | *.swm 60 | *.out 61 | *.pid 62 | 63 | 64 | ############################ 65 | # Logs and databases 66 | ############################ 67 | 68 | .tmp 69 | *.log 70 | *.sql 71 | *.sqlite 72 | *.sqlite3 73 | 74 | 75 | ############################ 76 | # Misc. 77 | ############################ 78 | 79 | *# 80 | ssl 81 | .idea 82 | nbproject 83 | public/uploads/* 84 | !public/uploads/.gitkeep 85 | 86 | ############################ 87 | # Node.js 88 | ############################ 89 | 90 | lib-cov 91 | lcov.info 92 | pids 93 | logs 94 | results 95 | node_modules 96 | .node_history 97 | 98 | ############################ 99 | # Tests 100 | ############################ 101 | 102 | testApp 103 | coverage 104 | 105 | ############################ 106 | # Strapi 107 | ############################ 108 | 109 | .env 110 | license.txt 111 | exports 112 | *.cache 113 | build 114 | .strapi-updater.json 115 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/.nvmrc: -------------------------------------------------------------------------------- 1 | v14.9.0 -------------------------------------------------------------------------------- /strapi-plugin-navigation/README.md: -------------------------------------------------------------------------------- 1 | # Strapi examples - Plugin: Navigation 2 | 3 | https://github.com/VirtusLab/strapi-plugin-navigation 4 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/api/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-plugin-navigation/api/.gitkeep -------------------------------------------------------------------------------- /strapi-plugin-navigation/api/blog-post/config/routes.json: -------------------------------------------------------------------------------- 1 | { 2 | "routes": [ 3 | { 4 | "method": "GET", 5 | "path": "/blog-posts", 6 | "handler": "blog-post.find", 7 | "config": { 8 | "policies": [] 9 | } 10 | }, 11 | { 12 | "method": "GET", 13 | "path": "/blog-posts/count", 14 | "handler": "blog-post.count", 15 | "config": { 16 | "policies": [] 17 | } 18 | }, 19 | { 20 | "method": "GET", 21 | "path": "/blog-posts/:id", 22 | "handler": "blog-post.findOne", 23 | "config": { 24 | "policies": [] 25 | } 26 | }, 27 | { 28 | "method": "POST", 29 | "path": "/blog-posts", 30 | "handler": "blog-post.create", 31 | "config": { 32 | "policies": [] 33 | } 34 | }, 35 | { 36 | "method": "PUT", 37 | "path": "/blog-posts/:id", 38 | "handler": "blog-post.update", 39 | "config": { 40 | "policies": [] 41 | } 42 | }, 43 | { 44 | "method": "DELETE", 45 | "path": "/blog-posts/:id", 46 | "handler": "blog-post.delete", 47 | "config": { 48 | "policies": [] 49 | } 50 | } 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/api/blog-post/controllers/blog-post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/controllers.html#core-controllers) 5 | * to customize this controller 6 | */ 7 | 8 | module.exports = {}; 9 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/api/blog-post/models/blog-post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/models.html#lifecycle-hooks) 5 | * to customize this model 6 | */ 7 | 8 | module.exports = {}; 9 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/api/blog-post/models/blog-post.settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "collectionType", 3 | "collectionName": "blog_posts", 4 | "info": { 5 | "name": "Blog post" 6 | }, 7 | "options": { 8 | "increments": true, 9 | "timestamps": true, 10 | "draftAndPublish": true 11 | }, 12 | "attributes": { 13 | "Title": { 14 | "type": "string" 15 | }, 16 | "Content": { 17 | "type": "richtext" 18 | }, 19 | "navigation": { 20 | "model": "navigationitem", 21 | "plugin": "navigation", 22 | "via": "related", 23 | "configurable": false, 24 | "hidden": true 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/api/blog-post/services/blog-post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/services.html#core-services) 5 | * to customize this service 6 | */ 7 | 8 | module.exports = {}; 9 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/config/custom.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | navigation: { 4 | additionalFields: ['audience'], 5 | excludedContentTypes: ["plugins::", "strapi"], 6 | allowedLevels: 2, 7 | contentTypesNameFields: { 8 | 'blog_posts': ['Title'], 9 | }, 10 | }, 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/config/database.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | defaultConnection: 'default', 3 | connections: { 4 | default: { 5 | connector: 'bookshelf', 6 | settings: { 7 | client: 'sqlite', 8 | filename: env('DATABASE_FILENAME', '.tmp/data.db'), 9 | }, 10 | options: { 11 | useNullAsDefault: true, 12 | }, 13 | }, 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/config/functions/bootstrap.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * An asynchronous bootstrap function that runs before 5 | * your application gets started. 6 | * 7 | * This gives you an opportunity to set up your data model, 8 | * run jobs, or perform some special logic. 9 | * 10 | * See more details here: https://strapi.io/documentation/developer-docs/latest/concepts/configurations.html#bootstrap 11 | */ 12 | 13 | module.exports = () => {}; 14 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/config/functions/cron.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Cron config that gives you an opportunity 5 | * to run scheduled jobs. 6 | * 7 | * The cron format consists of: 8 | * [SECOND (optional)] [MINUTE] [HOUR] [DAY OF MONTH] [MONTH OF YEAR] [DAY OF WEEK] 9 | * 10 | * See more details here: https://strapi.io/documentation/developer-docs/latest/concepts/configurations.html#cron-tasks 11 | */ 12 | 13 | module.exports = { 14 | /** 15 | * Simple example. 16 | * Every monday at 1am. 17 | */ 18 | // '0 1 * * 1': () => { 19 | // 20 | // } 21 | }; 22 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/config/functions/responses/404.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = async (/* ctx */) => { 4 | // return ctx.notFound('My custom message 404'); 5 | }; 6 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/config/server.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | host: env('HOST', '0.0.0.0'), 3 | port: env.int('PORT', 1337), 4 | admin: { 5 | auth: { 6 | secret: env('ADMIN_JWT_SECRET', '26cbc137d5df719b20fde7897ab31aae'), 7 | }, 8 | }, 9 | }); 10 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/extensions/users-permissions/config/jwt.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | jwtSecret: process.env.JWT_SECRET || 'f4d87ca3-3612-49c6-ae45-a6056cda904a' 3 | }; -------------------------------------------------------------------------------- /strapi-plugin-navigation/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-plugin-navigation/favicon.ico -------------------------------------------------------------------------------- /strapi-plugin-navigation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "strapi-examples-navigation", 3 | "private": true, 4 | "version": "0.1.1", 5 | "description": "Strapi examples - Plugin: Navigation", 6 | "scripts": { 7 | "develop": "strapi develop --watch-admin", 8 | "start": "strapi start", 9 | "build": "strapi build", 10 | "strapi": "strapi" 11 | }, 12 | "devDependencies": {}, 13 | "dependencies": { 14 | "strapi": "3.6.1", 15 | "strapi-admin": "3.6.1", 16 | "strapi-utils": "3.6.1", 17 | "strapi-plugin-content-type-builder": "3.6.1", 18 | "strapi-plugin-content-manager": "3.6.1", 19 | "strapi-plugin-users-permissions": "3.6.1", 20 | "strapi-plugin-email": "3.6.1", 21 | "strapi-plugin-upload": "3.6.1", 22 | "strapi-plugin-navigation": "^1.0.1", 23 | "strapi-connector-bookshelf": "3.6.1", 24 | "knex": "<0.20.0", 25 | "sqlite3": "latest" 26 | }, 27 | "author": { 28 | "name": "VirtusLab // Mateusz Ziarko", 29 | "email": "mziarko@virtuslab.com", 30 | "url": "https://virtuslab.com" 31 | }, 32 | "maintainers": [ 33 | { 34 | "name": "VirtusLab // Mateusz Ziarko", 35 | "email": "mziarko@virtuslab.com", 36 | "url": "https://virtuslab.com" 37 | } 38 | ], 39 | "strapi": { 40 | "uuid": "92d33c58-658c-46dc-ba4d-ac19bb9f97cc" 41 | }, 42 | "engines": { 43 | "node": ">=10.16.0 <=14.x.x", 44 | "npm": ">=6.0.0" 45 | }, 46 | "license": "MIT" 47 | } 48 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/public/robots.txt: -------------------------------------------------------------------------------- 1 | # To prevent search engines from seeing the site altogether, uncomment the next two lines: 2 | # User-Agent: * 3 | # Disallow: / 4 | -------------------------------------------------------------------------------- /strapi-plugin-navigation/public/uploads/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-plugin-navigation/public/uploads/.gitkeep -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{package.json,*.yml}] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/.env.example: -------------------------------------------------------------------------------- 1 | HOST=0.0.0.0 2 | PORT=1337 3 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/.eslintignore: -------------------------------------------------------------------------------- 1 | .cache 2 | build 3 | **/node_modules/** 4 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "eslint:recommended", 4 | "env": { 5 | "commonjs": true, 6 | "es6": true, 7 | "node": true, 8 | "browser": false 9 | }, 10 | "parserOptions": { 11 | "ecmaFeatures": { 12 | "experimentalObjectRestSpread": true, 13 | "jsx": false 14 | }, 15 | "sourceType": "module" 16 | }, 17 | "globals": { 18 | "strapi": true 19 | }, 20 | "rules": { 21 | "indent": ["error", 2, { "SwitchCase": 1 }], 22 | "linebreak-style": ["error", "unix"], 23 | "no-console": 0, 24 | "quotes": ["error", "single"], 25 | "semi": ["error", "always"] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/.gitignore: -------------------------------------------------------------------------------- 1 | ############################ 2 | # OS X 3 | ############################ 4 | 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | Icon 9 | .Spotlight-V100 10 | .Trashes 11 | ._* 12 | 13 | 14 | ############################ 15 | # Linux 16 | ############################ 17 | 18 | *~ 19 | 20 | 21 | ############################ 22 | # Windows 23 | ############################ 24 | 25 | Thumbs.db 26 | ehthumbs.db 27 | Desktop.ini 28 | $RECYCLE.BIN/ 29 | *.cab 30 | *.msi 31 | *.msm 32 | *.msp 33 | 34 | 35 | ############################ 36 | # Packages 37 | ############################ 38 | 39 | *.7z 40 | *.csv 41 | *.dat 42 | *.dmg 43 | *.gz 44 | *.iso 45 | *.jar 46 | *.rar 47 | *.tar 48 | *.zip 49 | *.com 50 | *.class 51 | *.dll 52 | *.exe 53 | *.o 54 | *.seed 55 | *.so 56 | *.swo 57 | *.swp 58 | *.swn 59 | *.swm 60 | *.out 61 | *.pid 62 | 63 | 64 | ############################ 65 | # Logs and databases 66 | ############################ 67 | 68 | .tmp 69 | *.log 70 | *.sql 71 | *.sqlite 72 | *.sqlite3 73 | 74 | 75 | ############################ 76 | # Misc. 77 | ############################ 78 | 79 | *# 80 | ssl 81 | .idea 82 | nbproject 83 | public/uploads/* 84 | !public/uploads/.gitkeep 85 | 86 | ############################ 87 | # Node.js 88 | ############################ 89 | 90 | lib-cov 91 | lcov.info 92 | pids 93 | logs 94 | results 95 | node_modules 96 | .node_history 97 | 98 | ############################ 99 | # Tests 100 | ############################ 101 | 102 | testApp 103 | coverage 104 | 105 | ############################ 106 | # Strapi 107 | ############################ 108 | 109 | .env 110 | license.txt 111 | exports 112 | *.cache 113 | build 114 | .strapi-updater.json 115 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/.nvmrc: -------------------------------------------------------------------------------- 1 | v18.14.0 -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/README.md: -------------------------------------------------------------------------------- 1 | # Strapi application 2 | 3 | A quick description of your strapi application 4 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/config/admin.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | auth: { 3 | secret: env('ADMIN_JWT_SECRET', '4f1122df6b0ce4ca4d3ff45c613886e6'), 4 | }, 5 | }); 6 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/config/api.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rest: { 3 | defaultLimit: 25, 4 | maxLimit: 100, 5 | withCount: true, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/config/database.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = ({ env }) => ({ 4 | connection: { 5 | client: 'sqlite', 6 | connection: { 7 | filename: path.join(__dirname, '..', env('DATABASE_FILENAME', '.tmp/data.db')), 8 | }, 9 | useNullAsDefault: true, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/config/middlewares.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | 'strapi::errors', 3 | 'strapi::security', 4 | 'strapi::cors', 5 | 'strapi::poweredBy', 6 | 'strapi::logger', 7 | 'strapi::query', 8 | 'strapi::body', 9 | 'strapi::favicon', 10 | 'strapi::public', 11 | ]; 12 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/config/plugins.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'comments': { enabled: true }, 3 | 'graphql': { enabled: true }, 4 | }; -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/config/server.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | host: env('HOST', '0.0.0.0'), 3 | port: env.int('PORT', 1337), 4 | }); 5 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-v4-plugin-comments/favicon.ico -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "strapi-v4-examples-comments", 3 | "private": true, 4 | "version": "0.1.1", 5 | "description": "Strapi (v4) examples - Plugin: Comments", 6 | "scripts": { 7 | "develop": "strapi develop --watch-admin", 8 | "start": "strapi start", 9 | "build": "strapi build", 10 | "strapi": "strapi" 11 | }, 12 | "devDependencies": {}, 13 | "dependencies": { 14 | "@strapi/plugin-graphql": "^4.9.2", 15 | "@strapi/plugin-i18n": "^4.9.2", 16 | "@strapi/plugin-users-permissions": "^4.9.2", 17 | "@strapi/strapi": "^4.9.2", 18 | "strapi-plugin-comments": "^2.2.10", 19 | "sqlite3": "^5.0.2" 20 | }, 21 | "author": { 22 | "name": "VirtusLab // Mateusz Ziarko", 23 | "email": "mziarko@virtuslab.com", 24 | "url": "https://virtuslab.com" 25 | }, 26 | "maintainers": [ 27 | { 28 | "name": "VirtusLab // Mateusz Ziarko", 29 | "email": "mziarko@virtuslab.com", 30 | "url": "https://virtuslab.com" 31 | } 32 | ], 33 | "strapi": { 34 | "uuid": "a6595005-482b-4791-91c9-27af3e5e923b" 35 | }, 36 | "engines": { 37 | "node": ">=14.19.1 <=18.x.x", 38 | "npm": ">=7.x.x" 39 | }, 40 | "license": "MIT" 41 | } 42 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/public/robots.txt: -------------------------------------------------------------------------------- 1 | # To prevent search engines from seeing the site altogether, uncomment the next two lines: 2 | # User-Agent: * 3 | # Disallow: / 4 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/public/uploads/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-v4-plugin-comments/public/uploads/.gitkeep -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/admin/app.js: -------------------------------------------------------------------------------- 1 | export default { 2 | config: { 3 | locales: [ 4 | // 'ar', 5 | 'fr', 6 | // 'cs', 7 | // 'de', 8 | // 'dk', 9 | // 'es', 10 | // 'he', 11 | // 'id', 12 | // 'it', 13 | // 'ja', 14 | // 'ko', 15 | // 'ms', 16 | // 'nl', 17 | // 'no', 18 | // 'pl', 19 | // 'pt-BR', 20 | // 'pt', 21 | // 'ru', 22 | // 'sk', 23 | // 'sv', 24 | // 'th', 25 | // 'tr', 26 | // 'uk', 27 | // 'vi', 28 | // 'zh-Hans', 29 | // 'zh', 30 | ], 31 | }, 32 | bootstrap() {}, 33 | }; 34 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/admin/webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* eslint-disable no-unused-vars */ 4 | module.exports = (config, webpack) => { 5 | // Note: we provide webpack above so you should not `require` it 6 | // Perform customizations to webpack config 7 | // Important: return the modified config 8 | return config; 9 | }; 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/api/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-v4-plugin-comments/src/api/.gitkeep -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/api/blog-post/content-types/blog-post/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "collectionType", 3 | "collectionName": "blog_posts", 4 | "info": { 5 | "singularName": "blog-post", 6 | "pluralName": "blog-posts", 7 | "displayName": "Blog post" 8 | }, 9 | "options": { 10 | "draftAndPublish": true 11 | }, 12 | "pluginOptions": { 13 | "i18n": { 14 | "localized": true 15 | } 16 | }, 17 | "attributes": { 18 | "subject": { 19 | "pluginOptions": { 20 | "i18n": { 21 | "localized": true 22 | } 23 | }, 24 | "type": "string" 25 | }, 26 | "alternative_subject": { 27 | "pluginOptions": { 28 | "i18n": { 29 | "localized": true 30 | } 31 | }, 32 | "type": "string" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/api/blog-post/controllers/blog-post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * blog-post controller 5 | */ 6 | 7 | const { createCoreController } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreController('api::blog-post.blog-post'); 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/api/blog-post/routes/blog-post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * blog-post router. 5 | */ 6 | 7 | const { createCoreRouter } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreRouter('api::blog-post.blog-post'); 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/api/blog-post/services/blog-post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * blog-post service. 5 | */ 6 | 7 | const { createCoreService } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreService('api::blog-post.blog-post'); 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/api/page/content-types/page/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "collectionType", 3 | "collectionName": "pages", 4 | "info": { 5 | "singularName": "page", 6 | "pluralName": "pages", 7 | "displayName": "Page", 8 | "description": "" 9 | }, 10 | "options": { 11 | "draftAndPublish": true 12 | }, 13 | "pluginOptions": { 14 | "i18n": { 15 | "localized": true 16 | } 17 | }, 18 | "attributes": { 19 | "Title": { 20 | "pluginOptions": { 21 | "i18n": { 22 | "localized": true 23 | } 24 | }, 25 | "type": "string", 26 | "required": true 27 | }, 28 | "Content": { 29 | "pluginOptions": { 30 | "i18n": { 31 | "localized": true 32 | } 33 | }, 34 | "type": "richtext" 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/api/page/controllers/page.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * page controller 5 | */ 6 | 7 | const { createCoreController } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreController('api::page.page'); 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/api/page/routes/page.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * page router. 5 | */ 6 | 7 | const { createCoreRouter } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreRouter('api::page.page'); 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/api/page/services/page.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * page service. 5 | */ 6 | 7 | const { createCoreService } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreService('api::page.page'); 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/components/elements/accordion-item.json: -------------------------------------------------------------------------------- 1 | { 2 | "collectionName": "components_elements_accordion_items", 3 | "info": { 4 | "displayName": "Accordion item", 5 | "icon": "align-justify" 6 | }, 7 | "options": {}, 8 | "attributes": { 9 | "Content": { 10 | "type": "richtext" 11 | }, 12 | "Image": { 13 | "allowedTypes": [ 14 | "images", 15 | "files", 16 | "videos" 17 | ], 18 | "type": "media", 19 | "multiple": false 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/components/elements/accordion.json: -------------------------------------------------------------------------------- 1 | { 2 | "collectionName": "components_elements_accordions", 3 | "info": { 4 | "displayName": "Accordion", 5 | "icon": "pencil-ruler" 6 | }, 7 | "options": {}, 8 | "attributes": { 9 | "Header": { 10 | "type": "string" 11 | }, 12 | "Item": { 13 | "displayName": "Accordion item", 14 | "type": "component", 15 | "repeatable": true, 16 | "component": "elements.accordion-item" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/extensions/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-v4-plugin-comments/src/extensions/.gitkeep -------------------------------------------------------------------------------- /strapi-v4-plugin-comments/src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | /** 5 | * An asynchronous register function that runs before 6 | * your application is initialized. 7 | * 8 | * This gives you an opportunity to extend code. 9 | */ 10 | register(/*{ strapi }*/) {}, 11 | 12 | /** 13 | * An asynchronous bootstrap function that runs before 14 | * your application gets started. 15 | * 16 | * This gives you an opportunity to set up your data model, 17 | * run jobs, or perform some special logic. 18 | */ 19 | bootstrap(/*{ strapi }*/) {}, 20 | }; 21 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{package.json,*.yml}] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/.env.example: -------------------------------------------------------------------------------- 1 | HOST=0.0.0.0 2 | PORT=1337 3 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/.eslintignore: -------------------------------------------------------------------------------- 1 | .cache 2 | build 3 | **/node_modules/** 4 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "eslint:recommended", 4 | "env": { 5 | "commonjs": true, 6 | "es6": true, 7 | "node": true, 8 | "browser": false 9 | }, 10 | "parserOptions": { 11 | "ecmaFeatures": { 12 | "experimentalObjectRestSpread": true, 13 | "jsx": false 14 | }, 15 | "sourceType": "module" 16 | }, 17 | "globals": { 18 | "strapi": true 19 | }, 20 | "rules": { 21 | "indent": ["error", 2, { "SwitchCase": 1 }], 22 | "linebreak-style": ["error", "unix"], 23 | "no-console": 0, 24 | "quotes": ["error", "single"], 25 | "semi": ["error", "always"] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/.gitignore: -------------------------------------------------------------------------------- 1 | ############################ 2 | # OS X 3 | ############################ 4 | 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | Icon 9 | .Spotlight-V100 10 | .Trashes 11 | ._* 12 | 13 | 14 | ############################ 15 | # Linux 16 | ############################ 17 | 18 | *~ 19 | 20 | 21 | ############################ 22 | # Windows 23 | ############################ 24 | 25 | Thumbs.db 26 | ehthumbs.db 27 | Desktop.ini 28 | $RECYCLE.BIN/ 29 | *.cab 30 | *.msi 31 | *.msm 32 | *.msp 33 | 34 | 35 | ############################ 36 | # Packages 37 | ############################ 38 | 39 | *.7z 40 | *.csv 41 | *.dat 42 | *.dmg 43 | *.gz 44 | *.iso 45 | *.jar 46 | *.rar 47 | *.tar 48 | *.zip 49 | *.com 50 | *.class 51 | *.dll 52 | *.exe 53 | *.o 54 | *.seed 55 | *.so 56 | *.swo 57 | *.swp 58 | *.swn 59 | *.swm 60 | *.out 61 | *.pid 62 | 63 | 64 | ############################ 65 | # Logs and databases 66 | ############################ 67 | 68 | .tmp 69 | *.log 70 | *.sql 71 | *.sqlite 72 | *.sqlite3 73 | 74 | 75 | ############################ 76 | # Misc. 77 | ############################ 78 | 79 | *# 80 | ssl 81 | .idea 82 | nbproject 83 | public/uploads/* 84 | !public/uploads/.gitkeep 85 | 86 | ############################ 87 | # Node.js 88 | ############################ 89 | 90 | lib-cov 91 | lcov.info 92 | pids 93 | logs 94 | results 95 | node_modules 96 | .node_history 97 | 98 | ############################ 99 | # Tests 100 | ############################ 101 | 102 | testApp 103 | coverage 104 | 105 | ############################ 106 | # Strapi 107 | ############################ 108 | 109 | .env 110 | license.txt 111 | exports 112 | *.cache 113 | build 114 | .strapi-updater.json 115 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/.nvmrc: -------------------------------------------------------------------------------- 1 | v18.14.0 -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/README.md: -------------------------------------------------------------------------------- 1 | # Strapi application 2 | 3 | A quick description of your strapi application 4 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/config/admin.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | auth: { 3 | secret: env('ADMIN_JWT_SECRET', '4f1122df6b0ce4ca4d3ff45c613886e6'), 4 | }, 5 | }); 6 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/config/api.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rest: { 3 | defaultLimit: 25, 4 | maxLimit: 100, 5 | withCount: true, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/config/database.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = ({ env }) => ({ 4 | connection: { 5 | client: 'sqlite', 6 | connection: { 7 | filename: path.join(__dirname, '..', env('DATABASE_FILENAME', '.tmp/data.db')), 8 | }, 9 | useNullAsDefault: true, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/config/middlewares.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | 'strapi::errors', 3 | 'strapi::security', 4 | 'strapi::cors', 5 | 'strapi::poweredBy', 6 | 'strapi::logger', 7 | 'strapi::query', 8 | 'strapi::body', 9 | 'strapi::favicon', 10 | 'strapi::public', 11 | ]; 12 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/config/plugins.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'graphql': { 3 | enabled: true, 4 | config: { 5 | endpoint: '/graphql', 6 | shadowCRUD: true, 7 | playgroundAlways: false, 8 | depthLimit: 7, 9 | amountLimit: 100, 10 | apolloServer: { 11 | tracing: false, 12 | }, 13 | }, 14 | }, 15 | 'navigation': { 16 | enabled: true, 17 | config: { 18 | additionalFields: ['audience'], 19 | allowedLevels: 2, 20 | contentTypes: ['api::page.page'], 21 | contentTypesNameFields: { 22 | 'api::page.page': ['Title'], 23 | }, 24 | }, 25 | }, 26 | }; -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/config/server.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | host: env('HOST', '0.0.0.0'), 3 | port: env.int('PORT', 1337), 4 | }); 5 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-v4-plugin-navigation/favicon.ico -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "strapi-v4-examples-navigation", 3 | "private": true, 4 | "version": "0.1.0", 5 | "description": "Strapi (v4) examples - Plugin: Navigation", 6 | "scripts": { 7 | "develop": "strapi develop --watch-admin", 8 | "start": "strapi start", 9 | "build": "strapi build", 10 | "strapi": "strapi" 11 | }, 12 | "devDependencies": {}, 13 | "dependencies": { 14 | "@strapi/plugin-graphql": "^4.9.2", 15 | "@strapi/plugin-i18n": "^4.9.2", 16 | "@strapi/plugin-users-permissions": "^4.9.2", 17 | "@strapi/strapi": "^4.9.2", 18 | "strapi-plugin-navigation": "^2.2.8", 19 | "sqlite3": "^5.0.2" 20 | }, 21 | "author": { 22 | "name": "VirtusLab // Mateusz Ziarko", 23 | "email": "mziarko@virtuslab.com", 24 | "url": "https://virtuslab.com" 25 | }, 26 | "maintainers": [ 27 | { 28 | "name": "VirtusLab // Mateusz Ziarko", 29 | "email": "mziarko@virtuslab.com", 30 | "url": "https://virtuslab.com" 31 | } 32 | ], 33 | "strapi": { 34 | "uuid": "a6595005-482b-4791-91c9-27af3e5e923b" 35 | }, 36 | "engines": { 37 | "node": ">=14.19.1 <=18.x.x", 38 | "npm": ">=7.x.x" 39 | }, 40 | "license": "MIT" 41 | } 42 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/public/robots.txt: -------------------------------------------------------------------------------- 1 | # To prevent search engines from seeing the site altogether, uncomment the next two lines: 2 | # User-Agent: * 3 | # Disallow: / 4 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/public/uploads/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-v4-plugin-navigation/public/uploads/.gitkeep -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/admin/app.js: -------------------------------------------------------------------------------- 1 | export default { 2 | config: { 3 | locales: [ 4 | // 'ar', 5 | 'fr', 6 | // 'cs', 7 | // 'de', 8 | // 'dk', 9 | // 'es', 10 | // 'he', 11 | // 'id', 12 | // 'it', 13 | // 'ja', 14 | // 'ko', 15 | // 'ms', 16 | // 'nl', 17 | // 'no', 18 | // 'pl', 19 | // 'pt-BR', 20 | // 'pt', 21 | // 'ru', 22 | // 'sk', 23 | // 'sv', 24 | // 'th', 25 | // 'tr', 26 | // 'uk', 27 | // 'vi', 28 | // 'zh-Hans', 29 | // 'zh', 30 | ], 31 | }, 32 | bootstrap() {}, 33 | }; 34 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/admin/webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* eslint-disable no-unused-vars */ 4 | module.exports = (config, webpack) => { 5 | // Note: we provide webpack above so you should not `require` it 6 | // Perform customizations to webpack config 7 | // Important: return the modified config 8 | return config; 9 | }; 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/api/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-v4-plugin-navigation/src/api/.gitkeep -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/api/blog-post/content-types/blog-post/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "collectionType", 3 | "collectionName": "blog_posts", 4 | "info": { 5 | "singularName": "blog-post", 6 | "pluralName": "blog-posts", 7 | "displayName": "Blog post" 8 | }, 9 | "options": { 10 | "draftAndPublish": true 11 | }, 12 | "pluginOptions": { 13 | "i18n": { 14 | "localized": true 15 | } 16 | }, 17 | "attributes": { 18 | "subject": { 19 | "pluginOptions": { 20 | "i18n": { 21 | "localized": true 22 | } 23 | }, 24 | "type": "string" 25 | }, 26 | "alternative_subject": { 27 | "pluginOptions": { 28 | "i18n": { 29 | "localized": true 30 | } 31 | }, 32 | "type": "string" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/api/blog-post/controllers/blog-post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * blog-post controller 5 | */ 6 | 7 | const { createCoreController } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreController('api::blog-post.blog-post'); 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/api/blog-post/routes/blog-post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * blog-post router. 5 | */ 6 | 7 | const { createCoreRouter } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreRouter('api::blog-post.blog-post'); 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/api/blog-post/services/blog-post.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * blog-post service. 5 | */ 6 | 7 | const { createCoreService } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreService('api::blog-post.blog-post'); 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/api/page/content-types/page/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "collectionType", 3 | "collectionName": "pages", 4 | "info": { 5 | "singularName": "page", 6 | "pluralName": "pages", 7 | "displayName": "Page", 8 | "description": "" 9 | }, 10 | "options": { 11 | "draftAndPublish": true 12 | }, 13 | "pluginOptions": { 14 | "i18n": { 15 | "localized": true 16 | } 17 | }, 18 | "attributes": { 19 | "Title": { 20 | "pluginOptions": { 21 | "i18n": { 22 | "localized": true 23 | } 24 | }, 25 | "type": "string", 26 | "required": true 27 | }, 28 | "Content": { 29 | "pluginOptions": { 30 | "i18n": { 31 | "localized": true 32 | } 33 | }, 34 | "type": "richtext" 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/api/page/controllers/page.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * page controller 5 | */ 6 | 7 | const { createCoreController } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreController('api::page.page'); 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/api/page/routes/page.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * page router. 5 | */ 6 | 7 | const { createCoreRouter } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreRouter('api::page.page'); 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/api/page/services/page.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * page service. 5 | */ 6 | 7 | const { createCoreService } = require('@strapi/strapi').factories; 8 | 9 | module.exports = createCoreService('api::page.page'); 10 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/components/elements/accordion-item.json: -------------------------------------------------------------------------------- 1 | { 2 | "collectionName": "components_elements_accordion_items", 3 | "info": { 4 | "displayName": "Accordion item", 5 | "icon": "align-justify" 6 | }, 7 | "options": {}, 8 | "attributes": { 9 | "Content": { 10 | "type": "richtext" 11 | }, 12 | "Image": { 13 | "allowedTypes": [ 14 | "images", 15 | "files", 16 | "videos" 17 | ], 18 | "type": "media", 19 | "multiple": false 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/components/elements/accordion.json: -------------------------------------------------------------------------------- 1 | { 2 | "collectionName": "components_elements_accordions", 3 | "info": { 4 | "displayName": "Accordion", 5 | "icon": "pencil-ruler" 6 | }, 7 | "options": {}, 8 | "attributes": { 9 | "Header": { 10 | "type": "string" 11 | }, 12 | "Item": { 13 | "displayName": "Accordion item", 14 | "type": "component", 15 | "repeatable": true, 16 | "component": "elements.accordion-item" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/extensions/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab-Open-Source/strapi-examples/96001f463186e9517b9d6de48293f8cc432dad6a/strapi-v4-plugin-navigation/src/extensions/.gitkeep -------------------------------------------------------------------------------- /strapi-v4-plugin-navigation/src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | /** 5 | * An asynchronous register function that runs before 6 | * your application is initialized. 7 | * 8 | * This gives you an opportunity to extend code. 9 | */ 10 | register(/*{ strapi }*/) {}, 11 | 12 | /** 13 | * An asynchronous bootstrap function that runs before 14 | * your application gets started. 15 | * 16 | * This gives you an opportunity to set up your data model, 17 | * run jobs, or perform some special logic. 18 | */ 19 | bootstrap(/*{ strapi }*/) {}, 20 | }; 21 | --------------------------------------------------------------------------------