├── .gitignore ├── LICENSE ├── README.md ├── docs ├── .gitignore ├── App.css ├── App.jsx ├── dist │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── browserconfig.xml │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── mstile-150x150.png │ ├── safari-pinned-tab.svg │ └── static │ │ ├── fonts │ │ ├── noto-sans-v21-latin-700.woff │ │ ├── noto-sans-v21-latin-700.woff2 │ │ ├── noto-sans-v21-latin-regular.woff │ │ └── noto-sans-v21-latin-regular.woff2 │ │ └── images │ │ ├── Logo-white.svg │ │ ├── Logo.svg │ │ ├── book-open.svg │ │ ├── book.svg │ │ ├── client-side.svg │ │ ├── discord.svg │ │ ├── dist-folder-example.svg │ │ ├── esbuild-benchmark.jpg │ │ ├── fast-forward.svg │ │ ├── github.svg │ │ ├── host-your-site.svg │ │ ├── logo-icon.png │ │ ├── prerendering.svg │ │ ├── react-code.svg │ │ ├── server-side.svg │ │ ├── slack.svg │ │ ├── twitter.svg │ │ └── upload-cloud.svg ├── greenjs.config.js ├── package-lock.json ├── package.json ├── src │ ├── common.jsx │ ├── landing.jsx │ └── topics │ │ ├── base-doc-page.jsx │ │ ├── comparisons │ │ ├── nextjs.jsx │ │ └── vite.jsx │ │ ├── configuration │ │ ├── esbuild.jsx │ │ ├── performance.jsx │ │ └── plugins.jsx │ │ ├── getting-started │ │ ├── examples.jsx │ │ ├── getting-started.jsx │ │ ├── hosting.jsx │ │ └── why.jsx │ │ ├── integrations │ │ └── tailwindcss.jsx │ │ └── react-components │ │ ├── header.jsx │ │ └── router.jsx └── tailwind.config.js ├── examples ├── docs │ ├── .gitignore │ ├── App.css │ ├── App.js │ ├── greenjs.json │ ├── package-lock.json │ ├── package.json │ └── pages │ │ ├── common │ │ └── docs-layout.js │ │ ├── docs │ │ ├── Links.js │ │ ├── docs-search.js │ │ ├── index.js │ │ ├── introduction │ │ │ ├── confused.md │ │ │ ├── docs-template.md │ │ │ ├── index.js │ │ │ ├── linking.md │ │ │ ├── search.md │ │ │ ├── using-this.md │ │ │ └── welcome.md │ │ └── resources │ │ │ ├── another.md │ │ │ ├── index.js │ │ │ └── intro.md │ │ ├── introduction.js │ │ └── resources.js ├── hello-world-react │ ├── .gitignore │ ├── App.jsx │ ├── package-lock.json │ ├── package.json │ └── pages │ │ ├── About.jsx │ │ ├── Env.jsx │ │ └── Home.jsx ├── profile │ ├── .gitignore │ ├── App.css │ ├── App.js │ ├── common │ │ ├── Navbar.css │ │ ├── Navbar.js │ │ ├── ProjectCard.css │ │ └── ProjectCard.js │ ├── lines-background.svg │ ├── mui-theme.js │ ├── package-lock.json │ ├── package.json │ └── pages │ │ ├── index.css │ │ ├── index.js │ │ ├── projects.css │ │ └── projects.js └── saas-landing │ ├── .gitignore │ ├── App.css │ ├── App.js │ ├── common │ ├── FeatureCard.css │ ├── FeatureCard.js │ ├── Footer.css │ ├── Footer.js │ ├── Navbar.css │ ├── Navbar.js │ ├── TestimonialCard.css │ ├── TestimonialCard.js │ └── placeholder-image.js │ ├── data.js │ ├── mui-theme.js │ ├── package-lock.json │ ├── package.json │ └── pages │ ├── index.css │ └── index.js ├── go.mod ├── go.sum ├── modd.conf └── npm ├── create-greenjs-app ├── .gitignore ├── main.js ├── package-lock.json ├── package.json └── templates │ ├── .gitignore │ ├── base-template │ ├── App.css │ ├── App.js │ ├── dist │ │ └── static │ │ │ └── greenjs-white.svg │ ├── package.json │ └── pages │ │ ├── index.js │ │ └── pricing.js │ ├── docs │ ├── App.css │ ├── App.js │ ├── greenjs.json │ ├── package.json │ └── pages │ │ ├── common │ │ └── docs-layout.js │ │ ├── docs │ │ ├── Links.js │ │ ├── docs-search.js │ │ ├── index.js │ │ ├── introduction │ │ │ ├── confused.md │ │ │ ├── docs-template.md │ │ │ ├── index.js │ │ │ ├── linking.md │ │ │ ├── search.md │ │ │ ├── using-this.md │ │ │ └── welcome.md │ │ └── resources │ │ │ ├── another.md │ │ │ ├── index.js │ │ │ └── intro.md │ │ ├── introduction.js │ │ └── resources.js │ ├── profile │ ├── App.css │ ├── App.js │ ├── common │ │ ├── Navbar.css │ │ ├── Navbar.js │ │ ├── ProjectCard.css │ │ └── ProjectCard.js │ ├── lines-background.svg │ ├── mui-theme.js │ ├── package.json │ └── pages │ │ ├── index.css │ │ ├── index.js │ │ ├── projects.css │ │ └── projects.js │ └── saas-landing │ ├── App.css │ ├── App.js │ ├── common │ ├── FeatureCard.css │ ├── FeatureCard.js │ ├── Footer.css │ ├── Footer.js │ ├── Navbar.css │ ├── Navbar.js │ ├── TestimonialCard.css │ ├── TestimonialCard.js │ └── placeholder-image.js │ ├── data.js │ ├── mui-theme.js │ ├── package.json │ └── pages │ ├── index.css │ └── index.js ├── greenjs ├── .eslintignore ├── .eslintrc ├── .github │ └── dependabot.yml ├── .gitignore ├── LICENSE ├── README.md ├── package.json ├── src │ ├── commands │ │ ├── build.ts │ │ └── start.ts │ ├── greenjs-entry-plugin.ts │ ├── index.ts │ ├── resources.ts │ └── routeMatches.ts └── tsconfig.json ├── head ├── .gitignore ├── Head.js ├── package-lock.json ├── package.json └── vite.config.js └── router ├── .gitignore ├── package-lock.json ├── package.json ├── router.jsx └── vite.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Colin Chartier & the GreenJS authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Fast React pages for existing sites](https://pimp-my-readme.webapp.io/pimp-my-readme/sliding-text?emojis=1f3d7-fe0f&text=Fast%2520React%2520pages%2520for%2520existing%2520sites)](https://pimp-my-readme.webapp.io) 2 | 3 | GreenJS combines esbuild, Go, and prerendering into a great developer experience for React users. 4 | 5 | ### Build faster with a familiar interface 6 | Iterate without reading our docs, the GreenJS `` and `` elements are already familiar to most React developers. 7 | 8 | ### 'npm build' is 10x faster 9 | GreenJS is written entirely in Go, and uses esbuild to finish builds in milliseconds instead of minutes. 10 | 11 | ### Add react components to existing sites 12 | The GreenJS production webserver can act as a proxy to forward traffic to an existing site effortlessly. 13 | 14 | # How to Get Started 15 | 16 | 17 | ### 1. Write React code like you usually would 18 | 19 | Instead of using complex file-based routing, use routes directly within React to define pages. GreenJS comes with drop-in replacements for react-helmet, react-router and react-dom. 20 |







21 | 22 | 23 | 24 | ### 2. Run greenjs build to prerender your site 25 | 26 | At build-time, we’ll discover all of your routes. We’ll use a headless browser to visit all of your pages and run your React code. The resulting pages will be saved as HTML. 27 |




28 | 29 | 30 | 31 | ### 3. Host your site as you usually would 32 | 33 | GreenJS automatically emits a high performance webserver in the dist folder to distribute the entire application with ease. 34 |





35 | 36 | ## Ready to get started? 37 | - [Getting started guide](https://greenjs.io/docs/getting-started) 38 | - [Learn more](https://greenjs.io/docs/why) 39 | - [See examples](https://greenjs.io/docs/examples) 40 | - [Join the slack](https://join.slack.com/t/webappdevelopers/shared_invite/zt-12tklqflc-7y~sYb7K3kkLyqY_hHofXg) -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist/* 3 | !dist/static/ 4 | !dist/android-chrome-192x192.png 5 | !dist/android-chrome-512x512.png 6 | !dist/mstile-150x150.png 7 | !dist/favicon-16x16.png 8 | !dist/favicon-32x32.png 9 | !dist/safari-pinned-tab.svg 10 | !dist/favicon.ico 11 | !dist/apple-touch-icon.png 12 | !dist/browserconfig.xml 13 | built-app.css -------------------------------------------------------------------------------- /docs/App.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | /* noto-sans-regular - latin */ 6 | @font-face { 7 | font-family: 'Noto Sans'; 8 | font-style: normal; 9 | font-weight: 400; 10 | src: url('/static/fonts/noto-sans-v21-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ 11 | url('/static/fonts/noto-sans-v21-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ 12 | } 13 | 14 | /* noto-sans-700 - latin */ 15 | @font-face { 16 | font-family: 'Noto Sans'; 17 | font-style: normal; 18 | font-weight: 700; 19 | src: url('/static/fonts/noto-sans-v21-latin-700.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ 20 | url('/static/fonts/noto-sans-v21-latin-700.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ 21 | } 22 | 23 | body { 24 | font-family: Noto Sans, sans-serif; 25 | } 26 | 27 | .green-gradient-text { 28 | background: -webkit-linear-gradient(#17BF3C, #0D9D2D); 29 | -webkit-background-clip: text; 30 | -webkit-text-fill-color: transparent; 31 | } -------------------------------------------------------------------------------- /docs/App.jsx: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React from "react"; 4 | import {Head} from "@greenio/head"; 5 | import {Route, Router, Redirect, Switch} from "@greenio/router"; 6 | 7 | export default function Site () { 8 | return
9 | 10 | GreenJS Docs 11 | 12 | 13 | 14 | 23 | 24 | 25 | import("./src/topics/getting-started/getting-started")} path="/docs/getting-started" /> 26 | import("./src/topics/getting-started/hosting")} /> 27 | import("./src/topics/getting-started/examples")} /> 28 | import("./src/topics/getting-started/why")} /> 29 | import("./src/topics/react-components/router")} /> 30 | import("./src/topics/react-components/header")} /> 31 | import("./src/topics/configuration/esbuild")} /> 32 | import("./src/topics/configuration/performance")} /> 33 | import("./src/topics/configuration/plugins")} /> 34 | import("./src/topics/integrations/tailwindcss")} /> 35 | import("./src/topics/comparisons/nextjs")} /> 36 | import("./src/topics/comparisons/vite")} /> 37 | 38 | import("./src/landing")}/> 39 | 40 |
41 | } -------------------------------------------------------------------------------- /docs/dist/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webappio/greenjs/62c56632d0b4674e975cde8446d1602a71e99d47/docs/dist/android-chrome-192x192.png -------------------------------------------------------------------------------- /docs/dist/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webappio/greenjs/62c56632d0b4674e975cde8446d1602a71e99d47/docs/dist/android-chrome-512x512.png -------------------------------------------------------------------------------- /docs/dist/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webappio/greenjs/62c56632d0b4674e975cde8446d1602a71e99d47/docs/dist/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/dist/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #da532c 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/dist/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webappio/greenjs/62c56632d0b4674e975cde8446d1602a71e99d47/docs/dist/favicon-16x16.png -------------------------------------------------------------------------------- /docs/dist/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webappio/greenjs/62c56632d0b4674e975cde8446d1602a71e99d47/docs/dist/favicon-32x32.png -------------------------------------------------------------------------------- /docs/dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webappio/greenjs/62c56632d0b4674e975cde8446d1602a71e99d47/docs/dist/favicon.ico -------------------------------------------------------------------------------- /docs/dist/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webappio/greenjs/62c56632d0b4674e975cde8446d1602a71e99d47/docs/dist/mstile-150x150.png -------------------------------------------------------------------------------- /docs/dist/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.14, written by Peter Selinger 2001-2017 9 | 10 | 12 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /docs/dist/static/fonts/noto-sans-v21-latin-700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webappio/greenjs/62c56632d0b4674e975cde8446d1602a71e99d47/docs/dist/static/fonts/noto-sans-v21-latin-700.woff -------------------------------------------------------------------------------- /docs/dist/static/fonts/noto-sans-v21-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webappio/greenjs/62c56632d0b4674e975cde8446d1602a71e99d47/docs/dist/static/fonts/noto-sans-v21-latin-700.woff2 -------------------------------------------------------------------------------- /docs/dist/static/fonts/noto-sans-v21-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webappio/greenjs/62c56632d0b4674e975cde8446d1602a71e99d47/docs/dist/static/fonts/noto-sans-v21-latin-regular.woff -------------------------------------------------------------------------------- /docs/dist/static/fonts/noto-sans-v21-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webappio/greenjs/62c56632d0b4674e975cde8446d1602a71e99d47/docs/dist/static/fonts/noto-sans-v21-latin-regular.woff2 -------------------------------------------------------------------------------- /docs/dist/static/images/Logo-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/dist/static/images/Logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/dist/static/images/book-open.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/dist/static/images/book.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/dist/static/images/discord.svg: -------------------------------------------------------------------------------- 1 | Discord -------------------------------------------------------------------------------- /docs/dist/static/images/esbuild-benchmark.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webappio/greenjs/62c56632d0b4674e975cde8446d1602a71e99d47/docs/dist/static/images/esbuild-benchmark.jpg -------------------------------------------------------------------------------- /docs/dist/static/images/fast-forward.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/dist/static/images/github.svg: -------------------------------------------------------------------------------- 1 | GitHub -------------------------------------------------------------------------------- /docs/dist/static/images/logo-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webappio/greenjs/62c56632d0b4674e975cde8446d1602a71e99d47/docs/dist/static/images/logo-icon.png -------------------------------------------------------------------------------- /docs/dist/static/images/slack.svg: -------------------------------------------------------------------------------- 1 | Slack -------------------------------------------------------------------------------- /docs/dist/static/images/twitter.svg: -------------------------------------------------------------------------------- 1 | Twitter -------------------------------------------------------------------------------- /docs/dist/static/images/upload-cloud.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/greenjs.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | server: { 7 | host: "0.0.0.0", 8 | }, 9 | plugins: [ 10 | { 11 | resolveId(source, importer, options) { 12 | console.log("resolving " + source); 13 | } 14 | } 15 | ] 16 | }) 17 | 18 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@greenio/docs", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "@greenio/head": "file:../npm/head", 6 | "@greenio/router": "file:../npm/router", 7 | "@mui/material": "^5.2.5", 8 | "hamburger-react": "^2.4.1", 9 | "prismjs": "^1.26.0", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2" 12 | }, 13 | "scripts": { 14 | "build": "greenjs build && tailwindcss -i App.css -o ./dist/Site.css --minify && git checkout -- dist", 15 | "start": "mkdir -p dist && concurrently 'greenjs start' 'tailwindcss -i App.css -o ./dist/Site.css --watch'", 16 | "start-dev": "mkdir -p dist && concurrently '../npm/greenjs/bin/dev start' 'tailwindcss -i App.css -o ./dist/Site.css --watch'" 17 | }, 18 | "devDependencies": { 19 | "@emotion/react": "^11.7.1", 20 | "@emotion/styled": "^11.6.0", 21 | "concurrently": "^6.5.1", 22 | "greenjs": "^2.0.3", 23 | "tailwindcss": "^3.0.7" 24 | }, 25 | "license": "MIT", 26 | "author": "Colin Chartier", 27 | "type": "commonjs" 28 | } 29 | -------------------------------------------------------------------------------- /docs/src/common.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Link} from "@greenio/router"; 3 | 4 | export function Navbar() { 5 | return
6 | 7 | GreenJS logo 8 | 9 |
10 | Docs 13 | Community 15 | GitHub 17 |
18 |
19 | } 20 | 21 | 22 | export function Footer() { 23 | return
24 |
25 | GreenJS logo 26 |
27 |
28 |
Docs
29 | Why GreenJS 30 | Getting started 31 | Hosting 32 | Examples 33 |
34 |
35 |
Comparisons
36 | NextJS vs GreenJS 37 | Vite vs GreenJS 39 |
40 |
41 |
42 | 43 | GreenJS GitHub 45 | 46 | 47 | GreenJS Twitter 49 | 50 | 51 | GreenJS Discord 53 | 54 |
55 | ©2021 Colin Chartier and the GreenJS authors 56 |
57 |
58 |
59 |
60 | } 61 | -------------------------------------------------------------------------------- /docs/src/topics/comparisons/nextjs.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {DocBase, DocLink} from "../base-doc-page"; 3 | 4 | export default function Page() { 5 | return 6 |

NextJS vs GreenJS

7 |

NextJS is both similar and different to GreenJS:

8 | 18 |
19 | } -------------------------------------------------------------------------------- /docs/src/topics/comparisons/vite.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {DocBase, DocCmd, DocLink} from "../base-doc-page"; 3 | 4 | export default function Page() { 5 | return 6 |

Vite vs GreenJS

7 |

Vite is similar in many ways to GreenJS, but different in others:

8 | 19 |
20 | } -------------------------------------------------------------------------------- /docs/src/topics/configuration/esbuild.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Code, DocBase} from "../base-doc-page"; 3 | 4 | export default function Page() { 5 | return 6 |

ESBuild configuration

7 |

GreenJS comes with a default configuration, but you can edit greenjs.json to customize the configuration. To create this file, use npx greenjs genconfig

8 |

9 | esbuild is the library that GreenJS uses to create the html and javascript in the dist folder. 10 |

11 |

Description of greenjs.json

12 | {` 13 | { 14 | "esbuild": { 15 | "entry_point_name": "App.js", //the name of the main app file, usually the one that calls Render(site) 16 | "file_import_types": { //see https://esbuild.github.io/content-types/ for advanced details 17 | ".css": "css", //when you import Thing from "./hello.css", it's a list of css rules - if you'd like the string contents, use ".css": "text" 18 | ".jpeg": "file", 19 | ".jpg": "file", 20 | ".js": "jsx", 21 | ".jsx": "jsx", 22 | ".png": "file", 23 | ".svg": "file", 24 | ".ts": "tsx", 25 | ".tsx": "tsx" 26 | }, 27 | "out_dir": "dist", //output to dist/(files) 28 | "minify_whitespace": "only-prod", //only minify destination files in production 29 | "minify_syntax": "only-prod" 30 | }, 31 | (other greenjs configuration) 32 | } 33 | 34 | `} 35 |
36 | } -------------------------------------------------------------------------------- /docs/src/topics/configuration/performance.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Code, DocBase, DocCmd, DocLink} from "../base-doc-page"; 3 | 4 | export default function Page() { 5 | return 6 |

Tuning configuration for build speed

7 |

8 | You can make GreenJS preload links by using the Route and Link components. 9 |

10 |

11 | When you mouse over the links in the sidebar, if they correspond to a <Route> with the asyncPage attribute set, your browser will download the corresponding page. Look at the following example: 12 |

13 | {` 14 | 15 | import("./pages/index")} /> 16 | import("./pages/docs")} /> 17 | 18 | View docs 19 | `} 20 | 21 |

22 | In the example above, neither ./pages/index.js nor ./pages/docs.js are sent when you first visit the site. 23 | When you mouse over the "View docs" link, GreenJS detects that you are about to visit the &let;Route> which corresponds to the file ./pages/docs, and predownloads the file. 24 | That means that when you visit the page, it's already been downloaded. 25 |

26 |
27 | } -------------------------------------------------------------------------------- /docs/src/topics/configuration/plugins.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {DocBase, DocCmd} from "../base-doc-page"; 3 | import {Link} from "@greenio/router"; 4 | 5 | export default function Page() { 6 | return 7 |

Plugin configuration

8 |

GreenJS support esbuild plugins

9 |

To use them, add a "plugins": [...] block in your configuration.

10 |

Example plugins:

11 | 16 |
17 | } -------------------------------------------------------------------------------- /docs/src/topics/getting-started/examples.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {DocBase, DocLink} from "../base-doc-page"; 3 | 4 | 5 | const EXAMPLES = [ 6 | { 7 | Name: "Docs", 8 | Description: "A Docs template that uses markdown files. Use this template to build a quick documentation page for your business.", 9 | Src: "https://raw.githubusercontent.com/webappio/assets/main/greenjs-example-docs.png", 10 | Alt: "Screenshot of Docs Template Page", 11 | Command: "npx create-greenjs-app --template=docs", 12 | Link: "https://github.com/webappio/greenjs/tree/master/examples/docs", 13 | }, 14 | { 15 | Name: "Profile", 16 | Description: "A profile template to showcase your projects. This includes a dark mode!", 17 | Src: "https://raw.githubusercontent.com/webappio/assets/main/greenjs-example-profile.png", 18 | Alt: "Screenshot of Profile Template Page", 19 | Command: "npx create-greenjs-app --template=profile", 20 | Link: "https://github.com/webappio/greenjs/tree/master/examples/profile" 21 | }, 22 | { 23 | Name: "SaaS Landing Page", 24 | Description: "A template for your SaaS product which includes a section for features, testimonials, and various pictures.", 25 | Src: "https://raw.githubusercontent.com/webappio/assets/main/greenjs-example-saas.png", 26 | Alt: "Screenshot of SaaS Landing Template Page", 27 | Command: "npx create-greenjs-app --template=saas-landing", 28 | Link: "https://github.com/webappio/greenjs/tree/master/examples/saas-landing" 29 | }, 30 | ] 31 | 32 | export default function Page() { 33 | return 34 |

Examples

35 |
44 | { 45 | EXAMPLES.map((ex) => ( 46 |
52 | {ex.Alt} 59 |

{ex.Name}

60 |

{ex.Description}

61 |

Command to Install:

62 |

{ex.Command}

63 | 64 | View on GitHub 65 | 66 |
67 | )) 68 | } 69 |
70 |
71 |

More Examples:

72 | 73 | A very simple 'hello world' app 74 | 75 | 76 | The GreenJS docs themselves 77 | 78 |
79 |
80 | } -------------------------------------------------------------------------------- /docs/src/topics/getting-started/getting-started.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {DocBase, DocCmd, DocLink} from "../base-doc-page"; 3 | 4 | export default function Page() { 5 | return 6 |

GreenJS Basics

7 |

To start using GreenJS, install node.js and NPM and run npx create-greenjs-app

8 |

This will create a folder named greenjs-example with the following directory structure:

9 | greenjs-example/ 10 | dist/ 11 | static/ 12 | greenjs-white.svg 13 | pages 14 | App.css 15 | App.js 16 | package.json 17 | node_modules 18 | package-lock.json 19 | .gitignore 20 |

Commands

21 |
greenjs start
22 |

To start a development webserver, enter the directory (for example, cd greenjs-example) and run npm run start

23 |

This will read the 'start' script from package.json which runs greenjs start to start the development webserver.

24 |

Assuming everything went well, you should be able to see your webserver running at localhost:8000

25 | 26 |
greenjs build
27 |

To build the application for production, run npm run build, which reads the 'build' script from package.json to run greenjs build

28 |

After building, your dist/ folder will contain an index.html file which can be hosted on a static site provider

29 |
30 | } -------------------------------------------------------------------------------- /docs/src/topics/getting-started/hosting.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {DocBase} from "../base-doc-page"; 3 | 4 | export default function Page() { 5 | return 6 |

Hosting GreenJS websites

7 |

There are many ways to host a GreenJS website, but if you're just getting started we recommend one of the following:

8 |

Simpler options with worse performance

9 |
    10 |
  1. Github Pages
  2. 11 |
  3. Netlify
  4. 12 |
  5. GitLab Pages
  6. 13 |
14 |

More involved options with better performance

15 |
    16 |
  1. Docker
  2. 17 |
  3. Kubernetes
  4. 18 |
19 |
20 | } -------------------------------------------------------------------------------- /docs/src/topics/integrations/tailwindcss.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Code, DocBase, DocCmd} from "../base-doc-page"; 3 | 4 | export default function Page() { 5 | return 6 |

Using TailwindCSS with GreenJS

7 |

8 | 1. Install three packages: npm install --save-dev tailwindcss concurrently greenjs 9 |

10 |

11 | 2. Change package.json to include the following lines: 12 |

13 | {` 14 | "scripts": { 15 | "build": "tailwindcss -i App.css -o ./dist/Site.css --minify && greenjs build", 16 | "start": "mkdir -p dist && concurrently 'greenjs start' 'tailwindcss -i App.css -o ./dist/Site.css --watch'" 17 | } 18 | `} 19 |

20 | 3. Reference your TailwindCSS file by adding it to App.js 21 |

22 | {` 23 | 24 | 25 | 26 | 27 | `} 28 |
29 | } -------------------------------------------------------------------------------- /docs/src/topics/react-components/header.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Code, DocBase, DocCmd} from "../base-doc-page"; 3 | import {Link} from "@greenio/router"; 4 | import {Head} from "@greenio/head"; 5 | 6 | export default function Page() { 7 | return 8 | 9 | The GreenJS Head Component 10 | 11 |

The GreenJS <Head> tag

12 |

Installation

13 | npm install --save @greenio/head 14 |

The <Head> tag for these docs

15 | {` 16 | 17 | GreenJS Docs 18 | 19 | 20 | 21 | 22 | 30 | 31 | `} 32 |

<Head> tags can be nested

33 |

34 | If you use the Route component, 35 | you can override the <Head> tag of the parent component with the inner component. 36 | For example, this specific page has the following code:

37 | {` 38 | 39 | The GreenJS Head Component 40 | 41 | `} 42 |

43 | When you navigate away from this page, the <Head> element above will be unrendered, 44 | so the title of the page will change. 45 |

46 |
47 | } 48 | -------------------------------------------------------------------------------- /docs/src/topics/react-components/router.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Code, DocBase, DocCmd} from "../base-doc-page"; 3 | 4 | export default function Page() { 5 | return 6 |

GreenJS router examples

7 |

Installation

8 | npm install --save @greenio/router 9 |

Route to a page if possible

10 | {` 11 | import DocPage from "./pages/docs"; 12 | import OrgDashboard from "./pages/orgdash"; 13 | import PricingPage from "./pages/pricing"; 14 | import IndexPage from "./pages/index"; 15 | import NotFoundPage from "./pages/404"; 16 | import {Route, Router} from "@greenio/router"; 17 | export default function App() { 18 | return 19 | {/* /docs/hello but not /docs/hello/world */} 20 | 21 | {/* /myorg/settings and /myorg/settings/hello/world*/} 22 | 23 | {/* /pricing only, not /pricing/tiers */} 24 | 25 | {/* / but not /unknown */} 26 | 27 | 28 | 29 | }`} 30 | 31 |

Follow-up to example above, getting path attributes for the current route

32 | {` 33 | import {useRoute} from "@greenio/router"; 34 | export default function DocPage() { 35 | //params: /docs/:page -> page is a param 36 | const {params} = useRoute(); 37 | return
38 | Current doc page is {params.page}, query params are: {Object.keys(query).join(", ")} 39 | Path is: {params.path} 40 |
41 | }`}
42 | 43 |

Using async import to improve performance

44 | {` 45 | import {Route, Router} from "@greenio/router"; 46 | export default function App() { 47 | return 48 | {/* /docs/hello but not /docs/hello/world */} 49 | import("./pages/docs")} /> 50 | {/* /myorg/settings and /myorg/settings/hello/world*/} 51 | import("./pages/orgdash")} /> 52 | {/* /pricing only, not /pricing/tiers */} 53 | import("./pages/pricing")} /> 54 | {/* / but not /unknown */} 55 | import("./pages/index")} /> 56 | import("./pages/404")} /> 57 | 58 | }`} 59 | 60 |

Redirects

61 | {` 62 | import {Route, Router, Redirect} from "@greenio/router"; 63 | export default function App() { 64 | return 65 | import("./pages/docs")} /> 66 | 67 | import("./pages/404")} /> 68 | 69 | }`} 70 |

This example redirects /docs to /docs/getting-started

71 |
72 | } -------------------------------------------------------------------------------- /docs/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: ["./src/**/*.{html,js,jsx}", "./App.js"], 3 | theme: { 4 | extend: {}, 5 | }, 6 | plugins: [], 7 | } 8 | -------------------------------------------------------------------------------- /examples/docs/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules -------------------------------------------------------------------------------- /examples/docs/App.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | margin: 0; 3 | font-family: sans-serif; 4 | } 5 | 6 | a { 7 | text-decoration: none; 8 | } 9 | 10 | .flex { 11 | display: flex; 12 | } 13 | 14 | .flex-col { 15 | flex-direction: column; 16 | } 17 | 18 | .flex-row { 19 | flex-direction: row; 20 | } 21 | 22 | .justify-content-center { 23 | justify-content: center; 24 | } 25 | 26 | .justify-content-between { 27 | justify-content: space-between; 28 | } 29 | 30 | .w-100 { 31 | width: 100%; 32 | } 33 | 34 | .items-center { 35 | align-items: center; 36 | } 37 | 38 | .bg-emerald-900 { 39 | background-color: #064E3B; 40 | } 41 | 42 | .text-white { 43 | color: white; 44 | } 45 | 46 | .font-bold { 47 | font-weight: bold; 48 | } 49 | 50 | .mx-8 { 51 | margin-left: 2rem; 52 | margin-right: 2rem; 53 | } 54 | 55 | .py-4 { 56 | padding-top: 1rem; 57 | padding-bottom: 1rem; 58 | } 59 | 60 | .text-lg { 61 | font-size: 1.125rem; 62 | line-height: 1.75rem; 63 | } 64 | 65 | 66 | h1 { 67 | font-size: 24px; 68 | font-weight: 600; 69 | color: rgb(25, 118, 210); 70 | } 71 | 72 | p, ul, ol { 73 | font-size: 16px; 74 | line-height: 25px; 75 | } 76 | 77 | code { 78 | color: red; 79 | } 80 | 81 | .nav--link { 82 | color: rgb(25, 118, 210); 83 | font-weight: 600; 84 | } 85 | 86 | .nav--link:hover { 87 | cursor: pointer; 88 | } 89 | 90 | .nav--sublink { 91 | color: black; 92 | font-weight: 400; 93 | } 94 | 95 | .nav--sublink__not-active { 96 | border-left: 2px solid lightgray; 97 | } 98 | .nav--sublink__active { 99 | border-left: 2px solid rgb(25, 118, 210); 100 | } -------------------------------------------------------------------------------- /examples/docs/App.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React from "react"; 4 | import {Render} from "@greenio/react"; 5 | import {Head} from "@greenio/head"; 6 | import {Route, Router} from "@greenio/router"; 7 | import Introduction from "./pages/introduction"; 8 | import Resources from "./pages/resources"; 9 | import { DocsLayout } from "./pages/common/docs-layout"; 10 | 11 | import "./App.css"; 12 | 13 | const Docs = () => { 14 | return
15 | 16 | Docs Template 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | } 28 | 29 | Render(); -------------------------------------------------------------------------------- /examples/docs/greenjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "esbuild": { 3 | "entry_point_name": "App.js", 4 | "file_import_types": { 5 | ".css": "css", 6 | ".jpeg": "file", 7 | ".jpg": "file", 8 | ".js": "jsx", 9 | ".jsx": "jsx", 10 | ".png": "file", 11 | ".svg": "file", 12 | ".ts": "tsx", 13 | ".tsx": "tsx", 14 | ".md": "text" 15 | }, 16 | "out_dir": "dist", 17 | "minify_whitespace": "only-prod", 18 | "minify_syntax": "only-prod" 19 | }, 20 | "parallel_tasks": 16 21 | } 22 | -------------------------------------------------------------------------------- /examples/docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "greenjs-example", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "@emotion/css": "^11.7.1", 6 | "@emotion/react": "^11.7.1", 7 | "@emotion/styled": "^11.6.0", 8 | "@greenio/head": "0.0.4", 9 | "@greenio/react": "0.0.1", 10 | "@greenio/router": "0.0.3", 11 | "@mui/material": "^5.2.8", 12 | "markdown-to-jsx": "^7.1.5", 13 | "react": "^17.0.2", 14 | "react-dom": "^17.0.2", 15 | "react-feather": "^2.0.9" 16 | }, 17 | "devDependencies": { 18 | "greenjs": "^1.0.0" 19 | }, 20 | "scripts": { 21 | "build": "greenjs build", 22 | "start": "greenjs start" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/docs/pages/docs/Links.js: -------------------------------------------------------------------------------- 1 | class DocLink { 2 | constructor(name, link, content) { 3 | this.name = name; 4 | this.link = link; 5 | this.content = content; 6 | } 7 | } 8 | 9 | export { 10 | DocLink, 11 | } -------------------------------------------------------------------------------- /examples/docs/pages/docs/docs-search.js: -------------------------------------------------------------------------------- 1 | import { ALL_CONTENT } from "./index"; 2 | 3 | const getSearchResults = (searchQuery = "") => { 4 | if (searchQuery.length === 0) return {}; 5 | 6 | const query = searchQuery.toUpperCase().trim(); 7 | 8 | const searchResults = []; 9 | 10 | // Search by Section Title 11 | for (let i = 0; i < ALL_CONTENT.length; i++) { 12 | const page = ALL_CONTENT[i]; 13 | const main = page.MAIN; 14 | if (main?.name?.toUpperCase().includes(query)) { 15 | const searchContent = { 16 | Link: main.link, 17 | Name: main.name, 18 | Content: main.content, 19 | IsTitle: true, 20 | } 21 | searchResults.push(searchContent); 22 | } 23 | } 24 | 25 | 26 | // Search by Page Content Title 27 | 28 | // Search by Page Content 29 | for (let i = 0; i { 10 | return [ 11 | ...arr, 12 | { 13 | MAIN: content[0], 14 | CONTENT: content[1], 15 | } 16 | ]; 17 | }, []); 18 | 19 | export { 20 | ALL_CONTENT, 21 | } -------------------------------------------------------------------------------- /examples/docs/pages/docs/introduction/confused.md: -------------------------------------------------------------------------------- 1 | ## Confused? 2 | 3 | If these docs are confusing to you, feel free to change them directly! Simply make a change locally and open a PR in the `examples/docs` repo for the greenjs project [here.](https://github.com/webappio/greenjs) 4 | 5 |
-------------------------------------------------------------------------------- /examples/docs/pages/docs/introduction/docs-template.md: -------------------------------------------------------------------------------- 1 | ## Docs Template Structure 2 | 3 | This documentation template is structured in the following manner. After cloning or forking this template, you'll see the following: 4 | 5 | - docs 6 | - docs/pages 7 | - docs/pages/docs 8 | - docs/pages/common 9 | 10 | The `docs/pages/docs` folder contains all the relevant documentation in markdown files, the `DocLink` class, and the function needed to search through the docs. 11 | 12 | If you want to add to the existing docs do the following: 13 | 14 | 1. Create a Markdown file in one of the existing folders. 15 | 2. Import the Markdown file into the index.js file within the same folder. 16 | 3. Add a DocLink to the `CONTENT` array with the relevant information you need in the side navigation. 17 | 18 | If you want to add a new section to the docs, do the following: 19 | 20 | 1. Create a folder for the new sectiion in the `docs/pages/docs` folder. 21 | 2. Create a Markdown file with the necessary information. 22 | 3. Create an `index.js` file. 23 | 4. Copy an existing `index.js` structure from another folder. This must include a CONTENT array, and a MAIN `DocLink` which is to be exported. 24 | 5. Import the CONTENT array and MAIN `DocLink` created into the `docs/pages/docs/index.js` file and add it in the following order [MAIN, CONTENT]. 25 | 6. That's all! 26 | 27 |
-------------------------------------------------------------------------------- /examples/docs/pages/docs/introduction/index.js: -------------------------------------------------------------------------------- 1 | import { DocLink } from "../Links"; 2 | import Welcome from "./welcome.md"; 3 | import UsingThis from "./using-this.md"; 4 | import DocsTemplate from "./docs-template.md"; 5 | import Linking from "./linking.md"; 6 | import Search from "./search.md"; 7 | import Confused from "./confused.md"; 8 | 9 | 10 | const CONTENT = [ 11 | new DocLink("Welcome", "/#introduction", Welcome), 12 | new DocLink("Docs Structure", "/#docs-template-structure", DocsTemplate), 13 | new DocLink("Linking to a Section", "/#linking-to-a-section", Linking), 14 | new DocLink("Search", "/#docs-search", Search), 15 | new DocLink("Confused?", "/#confused", Confused), 16 | new DocLink("End", "/#end-of-docs", UsingThis), 17 | ]; 18 | 19 | const MAIN = new DocLink("Introduction", "/", ""); 20 | 21 | export { 22 | CONTENT, 23 | MAIN, 24 | } -------------------------------------------------------------------------------- /examples/docs/pages/docs/introduction/linking.md: -------------------------------------------------------------------------------- 1 | ## Linking to a Section 2 | 3 | The `markdown-to-jsx` module creates id's for all text headers that you add. For example if in your markdown you have the following: 4 | 5 | ``` 6 | ## Some Header 7 | ``` 8 | 9 | Then an id will be inserted in the HTML as follows: 10 | 11 | ``` 12 |

Some Header

13 | ``` 14 | 15 | This way, you don't have to specify each id in your markdown when creating/adding a `DocLink` to the navigation. 16 | 17 |
-------------------------------------------------------------------------------- /examples/docs/pages/docs/introduction/search.md: -------------------------------------------------------------------------------- 1 | ## Docs Search 2 | 3 | For the purpose of these simple and fast docs, we use a string match to search through the documentation. When a user types into the search bar and hits the "Enter" key or clicks the search icon, we iterate through the content in the `DocLink` classes as exported from the `docs/pages/docs/index.js` file. 4 | 5 |
-------------------------------------------------------------------------------- /examples/docs/pages/docs/introduction/using-this.md: -------------------------------------------------------------------------------- 1 | # END OF DOCS 2 | 3 | ## Some Random Text 4 | 5 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus ultrices justo, nec tincidunt diam venenatis sit amet. Nullam non aliquam arcu. Etiam velit massa, pellentesque vel ante id, ultrices lacinia leo. Sed a felis dictum nisl blandit tincidunt. Curabitur condimentum et augue et bibendum. Fusce semper nisl eu lacus auctor bibendum. Morbi ipsum felis, sagittis in consectetur porttitor, gravida sed elit. Nullam suscipit felis sed orci malesuada luctus. Proin eget magna dui. Quisque egestas lobortis luctus. Nam tincidunt luctus nibh in tristique. Nunc ac arcu ex.a 6 | 7 |
8 | 9 | ## More Random Text 10 | 11 | Vivamus scelerisque eget urna ac porta. Fusce id sem porttitor tortor efficitur accumsan quis at felis. Vivamus ultrices dictum ante. Mauris a sollicitudin urna. Nulla justo erat, facilisis commodo libero sit amet, iaculis molestie massa. Fusce urna erat, imperdiet fringilla enim vitae, imperdiet auctor lacus. Pellentesque turpis nisi, aliquet et iaculis sit amet, mollis ut erat. Proin mattis massa dolor, ultricies accumsan purus tristique interdum. Mauris sed massa erat. Nam sit amet turpis id nibh cursus commodo. Quisque sapien ante, ultricies eget mi et, ullamcorper scelerisque ligula. Etiam et eros commodo, finibus dolor a, ornare velit. Praesent nunc lectus, pulvinar rutrum tortor eu, viverra pharetra velit. Pellentesque consequat finibus dui, quis hendrerit lorem vestibulum ut. 12 | 13 |
14 | 15 | ### Some Random Text 16 | 17 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus ultrices justo, nec tincidunt diam venenatis sit amet. Nullam non aliquam arcu. Etiam velit massa, pellentesque vel ante id, ultrices lacinia leo. Sed a felis dictum nisl blandit tincidunt. Curabitur condimentum et augue et bibendum. Fusce semper nisl eu lacus auctor bibendum. Morbi ipsum felis, sagittis in consectetur porttitor, gravida sed elit. Nullam suscipit felis sed orci malesuada luctus. Proin eget magna dui. Quisque egestas lobortis luctus. Nam tincidunt luctus nibh in tristique. Nunc ac arcu ex.a 18 | 19 |
20 | 21 | ### More Random Text 22 | 23 | Vivamus scelerisque eget urna ac porta. Fusce id sem porttitor tortor efficitur accumsan quis at felis. Vivamus ultrices dictum ante. Mauris a sollicitudin urna. Nulla justo erat, facilisis commodo libero sit amet, iaculis molestie massa. Fusce urna erat, imperdiet fringilla enim vitae, imperdiet auctor lacus. Pellentesque turpis nisi, aliquet et iaculis sit amet, mollis ut erat. Proin mattis massa dolor, ultricies accumsan purus tristique interdum. Mauris sed massa erat. Nam sit amet turpis id nibh cursus commodo. Quisque sapien ante, ultricies eget mi et, ullamcorper scelerisque ligula. Etiam et eros commodo, finibus dolor a, ornare velit. Praesent nunc lectus, pulvinar rutrum tortor eu, viverra pharetra velit. Pellentesque consequat finibus dui, quis hendrerit lorem vestibulum ut. 24 | 25 |
26 | 27 | ## How to Use This 28 | 29 | Vivamus scelerisque eget urna ac porta. Fusce id sem porttitor tortor efficitur accumsan quis at felis. Vivamus ultrices dictum ante. Mauris a sollicitudin urna. Nulla justo erat, facilisis commodo libero sit amet, iaculis molestie massa. Fusce urna erat, imperdiet fringilla enim vitae, imperdiet auctor lacus. Pellentesque turpis nisi, aliquet et iaculis sit amet, mollis ut erat. Proin mattis massa dolor, ultricies accumsan purus tristique interdum. Mauris sed massa erat. Nam sit amet turpis id nibh cursus commodo. Quisque sapien ante, ultricies eget mi et, ullamcorper scelerisque ligula. Etiam et eros commodo, finibus dolor a, ornare velit. Praesent nunc lectus, pulvinar rutrum tortor eu, viverra pharetra velit. Pellentesque consequat finibus dui, quis hendrerit lorem vestibulum ut. -------------------------------------------------------------------------------- /examples/docs/pages/docs/introduction/welcome.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Welcome to the template Docs page! 4 | 5 |
6 | 7 | ## Green JS 8 | 9 | For more information on Green JS check out the official page [here.](https://greenjs.io/) 10 | 11 |
-------------------------------------------------------------------------------- /examples/docs/pages/docs/resources/another.md: -------------------------------------------------------------------------------- 1 | ## Another 2 | 3 | Vivamus scelerisque eget urna ac porta. Fusce id sem porttitor tortor efficitur accumsan quis at felis. Vivamus ultrices dictum ante. Mauris a sollicitudin urna. Nulla justo erat, facilisis commodo libero sit amet, iaculis molestie massa. Fusce urna erat, imperdiet fringilla enim vitae, imperdiet auctor lacus. Pellentesque turpis nisi, aliquet et iaculis sit amet, mollis ut erat. Proin mattis massa dolor, ultricies accumsan purus tristique interdum. Mauris sed massa erat. Nam sit amet turpis id nibh cursus commodo. Quisque sapien ante, ultricies eget mi et, ullamcorper scelerisque ligula. Etiam et eros commodo, finibus dolor a, ornare velit. Praesent nunc lectus, pulvinar rutrum tortor eu, viverra pharetra velit. Pellentesque consequat finibus dui, quis hendrerit lorem vestibulum ut. -------------------------------------------------------------------------------- /examples/docs/pages/docs/resources/index.js: -------------------------------------------------------------------------------- 1 | import { DocLink } from "../Links"; 2 | import Intro from "./intro.md"; 3 | import Another from "./another.md"; 4 | 5 | const CONTENT = [ 6 | new DocLink("Extra", "/resources#something-else", Intro), 7 | new DocLink("Extra", "/resources#another", Another), 8 | ]; 9 | 10 | const MAIN = new DocLink("Resources", "/", ""); 11 | 12 | export { 13 | CONTENT, 14 | MAIN, 15 | } -------------------------------------------------------------------------------- /examples/docs/pages/docs/resources/intro.md: -------------------------------------------------------------------------------- 1 | ### Something Else 2 | 3 | Vivamus scelerisque eget urna ac porta. Fusce id sem porttitor tortor efficitur accumsan quis at felis. Vivamus ultrices dictum ante. Mauris a sollicitudin urna. Nulla justo erat, facilisis commodo libero sit amet, iaculis molestie massa. Fusce urna erat, imperdiet fringilla enim vitae, imperdiet auctor lacus. Pellentesque turpis nisi, aliquet et iaculis sit amet, mollis ut erat. Proin mattis massa dolor, ultricies accumsan purus tristique interdum. Mauris sed massa erat. Nam sit amet turpis id nibh cursus commodo. Quisque sapien ante, ultricies eget mi et, ullamcorper scelerisque ligula. Etiam et eros commodo, finibus dolor a, ornare velit. Praesent nunc lectus, pulvinar rutrum tortor eu, viverra pharetra velit. Pellentesque consequat finibus dui, quis hendrerit lorem vestibulum ut. 4 | 5 | -------------------------------------------------------------------------------- /examples/docs/pages/introduction.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Head} from "@greenio/head"; 3 | import Markdown from "markdown-to-jsx"; 4 | import { CONTENT } from "./docs/introduction"; 5 | 6 | const Introduction = () => { 7 | return
8 | 9 | Introduction | Template Documentation 10 | 11 |
12 | { 13 | CONTENT.map((cont, index) => ( 14 | 15 | {cont.content} 16 | 17 | )) 18 | } 19 |
20 |
21 | } 22 | 23 | export default Introduction; -------------------------------------------------------------------------------- /examples/docs/pages/resources.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Head } from "@greenio/head"; 3 | import { CONTENT } from "./docs/resources"; 4 | import Markdown from "markdown-to-jsx"; 5 | 6 | const Resources = () => { 7 | return
8 | 9 | Resources | Template Documentation 10 | 11 |
12 | { 13 | CONTENT.map((cont, index) => ( 14 | 15 | {cont.content} 16 | 17 | )) 18 | } 19 |
20 |
21 | } 22 | 23 | export default Resources; -------------------------------------------------------------------------------- /examples/hello-world-react/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | -------------------------------------------------------------------------------- /examples/hello-world-react/App.jsx: -------------------------------------------------------------------------------- 1 | import {Head} from "@greenio/head" 2 | import {Route, Link, Switch} from "@greenio/router" 3 | 4 | export default function App() { 5 | return ( 6 | <> 7 | 8 | app! 9 | 10 | 19 | 20 | 21 | import("./pages/Home")} /> 22 | import("./pages/Env")} /> 23 | import("./pages/Env")} /> 24 | import("./pages/About")} /> 25 | 26 | 27 | ) 28 | } 29 | -------------------------------------------------------------------------------- /examples/hello-world-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-ssr-react", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "commonjs", 6 | "scripts": { 7 | "dev": "greenjs start", 8 | "build": "greenjs build", 9 | "generate": "vite build --outDir dist/static && npm run build:server && node prerender", 10 | "serve": "cross-env NODE_ENV=production node server", 11 | "debug": "node --inspect-brk server" 12 | }, 13 | "dependencies": { 14 | "@greenio/head": "file:../../npm/head/dist", 15 | "@greenio/router": "file:../../npm/router/dist", 16 | "react": "^17.0.2", 17 | "react-dom": "^17.0.2", 18 | "react-router": "^5.2.1", 19 | "react-router-dom": "^5.3.0" 20 | }, 21 | "devDependencies": { 22 | "@vitejs/plugin-react": "^1.2.0", 23 | "compression": "^1.7.4", 24 | "cross-env": "^7.0.3", 25 | "express": "^4.17.1", 26 | "greenjs": "file:../../npm/greenjs", 27 | "serve-static": "^1.14.1", 28 | "vite": "^2.8.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/hello-world-react/pages/About.jsx: -------------------------------------------------------------------------------- 1 | import {Head} from "@greenio/head"; 2 | 3 | export default function About() { 4 | return ( 5 | <> 6 | 7 | About page 8 | 9 |

About this page

10 | 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /examples/hello-world-react/pages/Env.jsx: -------------------------------------------------------------------------------- 1 | import {Head} from "@greenio/head"; 2 | import {useRoute} from "@greenio/router"; 3 | 4 | export default function Env() { 5 | let {params} = (useRoute() || {}); 6 | let msg = 'default message here' + (params?.envParam || ''); 7 | try { 8 | msg = process.env.MY_CUSTOM_SECRET || msg 9 | } catch {} 10 | return

11 | 12 | Env page 13 | 14 | {msg} 15 |

16 | } 17 | -------------------------------------------------------------------------------- /examples/hello-world-react/pages/Home.jsx: -------------------------------------------------------------------------------- 1 | import {Head} from "@greenio/head"; 2 | 3 | export default function Home() { 4 | return ( 5 | <> 6 | 7 | Home page 8 | 9 |

Home

10 | 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /examples/profile/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules -------------------------------------------------------------------------------- /examples/profile/App.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | margin: 0; 3 | font-family: sans-serif; 4 | } 5 | 6 | a { 7 | text-decoration: none; 8 | } 9 | 10 | .container { 11 | width: 100%; 12 | } 13 | 14 | .Page-Background { 15 | min-height: 100vh !important; 16 | width: 100vw !important; 17 | } 18 | 19 | .Content--Container { 20 | display: flex; 21 | justify-content: center; 22 | align-items: center; 23 | } 24 | 25 | 26 | @media (min-width: 640px) { 27 | .container { 28 | max-width: 640px; 29 | } 30 | } 31 | 32 | @media (min-width: 768px) { 33 | .container { 34 | max-width: 768px; 35 | } 36 | } 37 | 38 | @media (min-width: 1024px) { 39 | .container { 40 | max-width: 1024px; 41 | } 42 | } 43 | 44 | @media (min-width: 1280px) { 45 | .container { 46 | max-width: 1280px; 47 | } 48 | } 49 | 50 | @media (min-width: 1536px) { 51 | .container { 52 | max-width: 1536px; 53 | } 54 | } -------------------------------------------------------------------------------- /examples/profile/App.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React, { useState } from "react"; 4 | import {Render} from "@greenio/react"; 5 | import {Head} from "@greenio/head"; 6 | import {Route, Router} from "@greenio/router"; 7 | import Projects from "./pages/projects"; 8 | import Index from "./pages"; 9 | import "./App.css"; 10 | import { renderToStaticMarkup } from "react-dom/server"; 11 | import { ThemeProvider } from "@mui/material/styles"; 12 | import { theme } from "./mui-theme"; 13 | 14 | const SVGBackground = ({ colour }) => { 15 | const lineColour = colour === COLOURS.DARK ? "white" : "black"; 16 | return ( 17 | 18 | 19 | 20 | 21 | ) 22 | }; 23 | 24 | const COLOURS = { 25 | LIGHT: "light", 26 | DARK: "dark", 27 | }; 28 | 29 | const ColourContext = React.createContext(COLOURS.LIGHT); 30 | 31 | const Hello = () => { 32 | const [colour, setColour] = useState(COLOURS.LIGHT); 33 | 34 | 35 | const backgroundStyles = { 36 | color: colour === COLOURS.LIGHT ? "black" : "#292929", 37 | backgroundColor: colour === COLOURS.LIGHT ? "#F3F3F3" : "#292929", 38 | }; 39 | const svgString = encodeURIComponent(renderToStaticMarkup()); 40 | const svgBackground = { 41 | backgroundImage: `url("data:image/svg+xml,${svgString}")`, 42 | backgroundRepeat: "no-repeat", 43 | backgroundPosition: "center", 44 | backgroundSize: "cover", 45 | } 46 | 47 | 48 | return ( 49 | 50 | 51 |
52 | 53 | Your Name | Profile 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 |
63 |
64 | ) 65 | } 66 | 67 | export { 68 | COLOURS, 69 | ColourContext, 70 | } 71 | 72 | Render(); -------------------------------------------------------------------------------- /examples/profile/common/Navbar.css: -------------------------------------------------------------------------------- 1 | .Navbar--Div { 2 | display: flex; 3 | padding: 30px; 4 | height: 100px; 5 | } 6 | .Navbar--Link { 7 | margin-right: 20px; 8 | } -------------------------------------------------------------------------------- /examples/profile/common/Navbar.js: -------------------------------------------------------------------------------- 1 | import { Link } from "@greenio/router"; 2 | import React, { useContext } from "react"; 3 | import { Typography } from "@mui/material"; 4 | import "./Navbar.css"; 5 | import { COLOURS, ColourContext } from "../App"; 6 | import { Moon } from "react-feather"; 7 | 8 | 9 | const Navbar = () => { 10 | const { colour, setColour } = useContext(ColourContext); 11 | 12 | const fontStyles = { 13 | color: colour === COLOURS.LIGHT ? "black" : "white", 14 | }; 15 | const moonColor = colour === COLOURS.LIGHT ? "black" : "white"; 16 | 17 | return ( 18 |
19 | 20 | 21 | HOME 22 | 23 | 24 | 25 | 26 | PROJECTS 27 | 28 | 29 |
30 | { 33 | if (colour === COLOURS.LIGHT) { 34 | setColour(COLOURS.DARK); 35 | } else { 36 | setColour(COLOURS.LIGHT); 37 | } 38 | }} 39 | /> 40 |
41 |
42 | ) 43 | } 44 | 45 | export { 46 | Navbar, 47 | } -------------------------------------------------------------------------------- /examples/profile/common/ProjectCard.css: -------------------------------------------------------------------------------- 1 | .ProjectCard--Div { 2 | width: calc(50% - 80px); 3 | height: 250px; 4 | margin: 20px; 5 | display: flex; 6 | justify-content: center; 7 | align-items: center; 8 | } 9 | 10 | .ProjectCard--Div:hover { 11 | cursor: pointer; 12 | } 13 | 14 | @media only screen and (max-width: 900px) { 15 | .ProjectCard--Div { 16 | width: 100%; 17 | } 18 | } -------------------------------------------------------------------------------- /examples/profile/common/ProjectCard.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import "./ProjectCard.css"; 3 | import { COLOURS } from "../App"; 4 | import { Typography } from "@mui/material"; 5 | 6 | const ProjectCard = ({ name = "", description = "", link = "", images = [], colour, setOpen, setProject }) => { 7 | const cardStyles = { 8 | backgroundColor: colour === COLOURS.LIGHT ? "white" : "#292929", 9 | border: `5px solid ${colour === COLOURS.LIGHT ? "#292929" : "white" }` 10 | } 11 | const textColour = colour === COLOURS.LIGHT ? "black" : "white"; 12 | return ( 13 | <> 14 |
{ 16 | setProject({ 17 | NAME: name, 18 | DESCRIPTION: description, 19 | LINK: link, 20 | IMAGES: images 21 | }); 22 | setOpen(true); 23 | }} 24 | > 25 | 26 | {name} 27 | 28 |
29 | 30 | ) 31 | }; 32 | 33 | export { 34 | ProjectCard, 35 | } -------------------------------------------------------------------------------- /examples/profile/lines-background.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/profile/mui-theme.js: -------------------------------------------------------------------------------- 1 | import { createTheme } from "@mui/material/styles"; 2 | 3 | 4 | const theme = createTheme({ 5 | typography: { 6 | h1: { 7 | '@media (max-width:600px)': { 8 | fontSize: "35px", 9 | } 10 | }, 11 | h2: { 12 | '@media (max-width:600px)': { 13 | fontSize: "30px", 14 | } 15 | }, 16 | h3: { 17 | '@media (max-width:600px)': { 18 | fontSize: "25px", 19 | } 20 | }, 21 | h4: { 22 | '@media (max-width:600px)': { 23 | fontSize: "22px", 24 | } 25 | }, 26 | h5: { 27 | '@media (max-width:600px)': { 28 | fontSize: "20px", 29 | } 30 | }, 31 | h6: { 32 | '@media (max-width:600px)': { 33 | fontSize: "18px", 34 | } 35 | }, 36 | } 37 | }) 38 | 39 | export { 40 | theme, 41 | } -------------------------------------------------------------------------------- /examples/profile/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "greenjs-example", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "@emotion/react": "^11.7.1", 6 | "@emotion/styled": "^11.6.0", 7 | "@greenio/head": "0.0.4", 8 | "@greenio/react": "0.0.1", 9 | "@greenio/router": "0.0.3", 10 | "@mui/material": "^5.2.8", 11 | "react": "^17.0.2", 12 | "react-dom": "^17.0.2", 13 | "react-feather": "^2.0.9" 14 | }, 15 | "devDependencies": { 16 | "greenjs": "^1.0.0" 17 | }, 18 | "scripts": { 19 | "build": "greenjs build", 20 | "start": "greenjs start" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/profile/pages/index.css: -------------------------------------------------------------------------------- 1 | .Landing--Content { 2 | display: flex; 3 | flex-direction: column; 4 | width: 100%; 5 | justify-content: center; 6 | align-items: center; 7 | text-align: center; 8 | margin-top: 100px; 9 | } 10 | 11 | .Landing--Content--Image { 12 | height: 200px; 13 | width: 200px; 14 | border-radius: 50%; 15 | } 16 | 17 | .Landing--Content--Item { 18 | margin-bottom: 10px; 19 | } 20 | 21 | @media only screen and (max-width: 600px) { 22 | .Landing--Content { 23 | margin-top: 0px; 24 | } 25 | } -------------------------------------------------------------------------------- /examples/profile/pages/index.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { Navbar } from "../common/Navbar"; 3 | import { COLOURS, ColourContext } from "../App"; 4 | import "./index.css"; 5 | import { Typography } from "@mui/material"; 6 | import { renderToStaticMarkup } from "react-dom/server"; 7 | 8 | const SVGBackground = ({ colour }) => { 9 | const lineColour = colour === COLOURS.DARK ? "white" : "black"; 10 | const backgroundColor = colour === COLOURS.DARK ? "#292929" : "#F3F3F3"; 11 | return ( 12 | 13 | 14 | 15 | 16 | 17 | ) 18 | }; 19 | 20 | const Index = () => { 21 | const { colour } = useContext(ColourContext); 22 | 23 | const textColour = colour === COLOURS.LIGHT ? "black" : "white"; 24 | 25 | const svgString = encodeURIComponent(renderToStaticMarkup()); 26 | const svgBackground = { 27 | backgroundImage: `url("data:image/svg+xml,${svgString}")`, 28 | backgroundRepeat: "no-repeat", 29 | backgroundPosition: "center", 30 | backgroundSize: "cover", 31 | } 32 | 33 | return ( 34 |
35 | 36 |
37 |
38 | Profile Image 43 | 44 | YOUR NAME 45 | 46 | 47 | YOUR POSITION 48 | 49 | 50 | +1 888-888-8888 51 | 52 | 53 | something@email.com 54 | 55 |
56 |
57 |
58 | ) 59 | } 60 | 61 | export default Index; -------------------------------------------------------------------------------- /examples/profile/pages/projects.css: -------------------------------------------------------------------------------- 1 | .ProjectCards--Div { 2 | display: flex; 3 | justify-content: space-between; 4 | align-items: center; 5 | flex-wrap: wrap; 6 | } 7 | 8 | .Project--Dialog { 9 | padding: 50px; 10 | } 11 | 12 | .LinkClass { 13 | padding: 10px 30px 10px 30px; 14 | text-align: center; 15 | font-weight: bold; 16 | } 17 | 18 | .ProjectImage--Div { 19 | display: flex; 20 | flex-direction: row; 21 | flex-wrap: wrap; 22 | justify-content: space-between; 23 | align-items: center; 24 | margin-top: 50px; 25 | } 26 | 27 | .ProjectImage--Container { 28 | width: calc(50% - 30px); 29 | height: 300px; 30 | margin-bottom: 20px; 31 | } 32 | 33 | .ProjectImage { 34 | width: 100%; 35 | height: 100%; 36 | object-fit: cover; 37 | border-radius: 20px; 38 | padding: 10px; 39 | background-color: black; 40 | } 41 | 42 | @media only screen and (max-width: 600px) { 43 | .LinkClass { 44 | padding: 10px; 45 | } 46 | .ProjectImage--Container { 47 | height: 200px; 48 | width: 100% !important; 49 | } 50 | } -------------------------------------------------------------------------------- /examples/profile/pages/projects.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState } from "react"; 2 | import {Head} from "@greenio/head"; 3 | import { Navbar } from "../common/Navbar"; 4 | import { ProjectCard } from "../common/ProjectCard"; 5 | import { ColourContext, COLOURS } from "../App"; 6 | import { Dialog, Typography } from "@mui/material"; 7 | import "./projects.css"; 8 | 9 | 10 | const PROJECTS = [ 11 | { 12 | NAME: "PROJECT 1", 13 | DESCRIPTION: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", 14 | LINK: "https://greenjs.io", 15 | IMAGES: [ 16 | "", 17 | "" 18 | ], 19 | }, 20 | { 21 | NAME: "ANOTHER PROJECT", 22 | DESCRIPTION: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", 23 | LINK: "https://greenjs.io", 24 | IMAGES: [], 25 | }, 26 | ]; 27 | 28 | const Projects = () => { 29 | const [project, setProject] = useState({}); 30 | const [open, setOpen] = useState(false); 31 | const { colour } = useContext(ColourContext); 32 | const textColour = colour === COLOURS.LIGHT ? "black" : "white"; 33 | const backgroundColor = colour === COLOURS.LIGHT ? "#F3F3F3" : "#292929"; 34 | 35 | const linkStyles = { 36 | color: textColour, 37 | backgroundColor: backgroundColor, 38 | border: `5px solid ${textColour}`, 39 | }; 40 | 41 | return ( 42 | <> 43 | 44 | Your Name | Projects 45 | 46 | 47 | 48 | setOpen(false)} 53 | > 54 |
55 | 56 | {project.NAME} 57 | 58 | 59 | {project.DESCRIPTION} 60 | 61 | 62 | 63 | VIEW PROJECT 64 | 65 | 66 |
67 | {project?.IMAGES?.map(src => ( 68 |
69 | 70 |
71 | ))} 72 |
73 |
74 |
75 | 76 |
77 | 78 |
79 |
80 | { 81 | PROJECTS.map((project, index) => ( 82 | 92 | )) 93 | } 94 |
95 |
96 |
97 | 98 | ) 99 | } 100 | 101 | export default Projects; -------------------------------------------------------------------------------- /examples/saas-landing/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules -------------------------------------------------------------------------------- /examples/saas-landing/App.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap'); 2 | 3 | body, html { 4 | font-family: 'Roboto', sans-serif; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /examples/saas-landing/App.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React from "react"; 4 | import {Render} from "@greenio/react"; 5 | import {Head} from "@greenio/head"; 6 | import {Route, Router} from "@greenio/router"; 7 | import Index from "./pages"; 8 | import { theme } from "./mui-theme"; 9 | import { ThemeProvider } from "@mui/material/styles"; 10 | import "./App.css"; 11 | import '@brainhubeu/react-carousel/lib/style.css'; 12 | 13 | const Hello = () => { 14 | return
15 | 16 | SaaS Landing Page 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 |
27 |
28 | } 29 | 30 | Render(); -------------------------------------------------------------------------------- /examples/saas-landing/common/FeatureCard.css: -------------------------------------------------------------------------------- 1 | .FeatureCard { 2 | width: 100%; 3 | min-width: 200px; 4 | max-width: 400px; 5 | padding: 30px; 6 | } 7 | 8 | @media only screen and (max-width: 600px) { 9 | .FeatureCard { 10 | padding: 0px; 11 | margin-bottom: 30px; 12 | width: 100%; 13 | max-width: 600px; 14 | } 15 | } -------------------------------------------------------------------------------- /examples/saas-landing/common/FeatureCard.js: -------------------------------------------------------------------------------- 1 | import { Link } from "@greenio/router"; 2 | import { Typography } from "@mui/material"; 3 | import React from "react"; 4 | import { PlaceholderImage } from "./placeholder-image"; 5 | import "./FeatureCard.css"; 6 | import { COLOURS } from "../mui-theme"; 7 | 8 | const FeatureCard = ({ title, description, link, linkText }) => { 9 | return ( 10 |
11 |
12 | 13 |
14 | 15 | {title} 16 | 17 | 18 | {description} 19 | 20 |
21 | 22 | 23 | {linkText} 24 | 25 | 26 |
27 |
28 | ) 29 | }; 30 | 31 | export { 32 | FeatureCard, 33 | } -------------------------------------------------------------------------------- /examples/saas-landing/common/Footer.css: -------------------------------------------------------------------------------- 1 | .Footer--Div { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: space-between; 5 | min-height: 350px; 6 | padding: 50px; 7 | background-color: #FBFBFB; 8 | } 9 | 10 | .Footer--Links { 11 | display: flex; 12 | flex-direction: row; 13 | flex-wrap: wrap; 14 | } 15 | 16 | .Footer--Base { 17 | padding-bottom: 40px; 18 | } 19 | 20 | .Footer--Base--Links { 21 | display: flex; 22 | flex-direction: row; 23 | justify-content: space-between; 24 | flex-wrap: wrap; 25 | } 26 | 27 | @media only screen and (max-width: 600px) { 28 | .Footer--Div { 29 | padding: 30px; 30 | } 31 | 32 | .Footer--Links > div { 33 | margin-bottom: 30px; 34 | } 35 | .Footer--Base--Links > div { 36 | margin-bottom: 10px; 37 | } 38 | } -------------------------------------------------------------------------------- /examples/saas-landing/common/Footer.js: -------------------------------------------------------------------------------- 1 | import { Typography } from "@mui/material"; 2 | import React from "react"; 3 | import "./Footer.css"; 4 | 5 | const Footer = () => { 6 | return ( 7 |
8 |
9 |
10 | 11 | Product 12 | 13 | 14 | Feature 1 15 | 16 | 17 | Feature 2 18 | 19 |
20 |
21 | 22 | Contact 23 | 24 | 25 | support@yourcompany.com 26 | 27 | 28 | +1 888-888-8888 29 | 30 |
31 |
32 |
33 |
34 |
35 |
36 | 37 | With love, from Green JS 38 | 39 |
40 |
41 | 42 | Privacy Policy 43 | 44 | 45 | Security 46 | 47 |
48 |
49 | 50 | YOUR COMPANY INC. 51 | 52 |
53 |
54 |
55 |
56 | ) 57 | } 58 | 59 | export { 60 | Footer, 61 | } -------------------------------------------------------------------------------- /examples/saas-landing/common/Navbar.css: -------------------------------------------------------------------------------- 1 | .Navbar-Items { 2 | display: block; 3 | } 4 | .Navbar--Items--Small { 5 | display: none !important; 6 | } 7 | 8 | @media only screen and (max-width: 600px) { 9 | .Navbar-Items { 10 | display: none !important; 11 | } 12 | .Navbar--Items--Small { 13 | display: block !important; 14 | } 15 | } -------------------------------------------------------------------------------- /examples/saas-landing/common/Navbar.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { Button, Typography, Box, Drawer } from "@mui/material"; 3 | import { PlaceholderImage } from "./placeholder-image"; 4 | import "./Navbar.css"; 5 | import { Menu } from "react-feather"; 6 | 7 | const flexRowStyle = { 8 | display: "flex", 9 | flexDirection: "row", 10 | justifyContent: "space-between", 11 | alignItems: "center" 12 | }; 13 | 14 | const Navbar = () => { 15 | const [open, setOpen] = useState(false); 16 | return ( 17 | <> 18 | setOpen(false)} 21 | > 22 |
23 |
24 | 25 |
26 |
27 | 28 | Product 29 | 30 | 31 | Pricing 32 | 33 |
34 |
35 | 38 | 39 |
40 | 41 |
42 | 43 | Product 44 | 45 | 46 | Pricing 47 | 48 |
49 | 50 | setOpen(true)} /> 51 | 52 | 58 | 64 | 65 | 66 | 67 | ) 68 | } 69 | 70 | export { 71 | Navbar, 72 | } -------------------------------------------------------------------------------- /examples/saas-landing/common/TestimonialCard.css: -------------------------------------------------------------------------------- 1 | .TestimonialCard--Div { 2 | width: 100%; 3 | min-width: 200px; 4 | max-width: 1000px; 5 | padding: 20px; 6 | display: flex; 7 | flex-direction: column; 8 | justify-content: space-evenly; 9 | align-items: center; 10 | height: 80%; 11 | min-height: 300px; 12 | border-radius: 20px; 13 | margin: 20px; 14 | } 15 | 16 | .TestimonialCard--Image { 17 | 18 | } 19 | 20 | .TestimonialCard--Quote { 21 | padding: 30px; 22 | text-align: center; 23 | } 24 | 25 | .TestimonialCard--Details { 26 | display: flex; 27 | flex-direction: column; 28 | justify-content: center; 29 | align-items: center; 30 | } 31 | 32 | @media only screen and (max-width: 600px) { 33 | .TestimonialCard--Div { 34 | width: 100%; 35 | max-width: 600px; 36 | margin: 10px; 37 | } 38 | } -------------------------------------------------------------------------------- /examples/saas-landing/common/TestimonialCard.js: -------------------------------------------------------------------------------- 1 | import { Typography } from "@mui/material"; 2 | import React from "react"; 3 | import { PlaceholderImage } from "./placeholder-image"; 4 | import "./TestimonialCard.css"; 5 | import { COLOURS } from "../mui-theme"; 6 | 7 | const DIV_STYLES = { 8 | border: `5px solid ${COLOURS.PRIMARY}`, 9 | }; 10 | 11 | const TestimonialCard = ({ testimonial, firstName, lastName, title, company }) => { 12 | return ( 13 |
14 |
15 | 16 |
17 |
18 | 19 | "{testimonial}" 20 | 21 |
22 |
23 | 24 | 25 | {firstName} {lastName} 26 | 27 | 28 | {title} @ {company} 29 | 30 |
31 |
32 | ) 33 | } 34 | 35 | export { 36 | TestimonialCard, 37 | } -------------------------------------------------------------------------------- /examples/saas-landing/common/placeholder-image.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const PlaceholderImage = ({ height, width, text, style = {} }) => { 4 | return ( 5 |
18 | {text} 19 |
20 | ) 21 | } 22 | 23 | export { 24 | PlaceholderImage, 25 | } -------------------------------------------------------------------------------- /examples/saas-landing/data.js: -------------------------------------------------------------------------------- 1 | const FEATURES = [ 2 | { 3 | title: "Get a quick dashboard", 4 | description: "Here’s some more text you can edit for your landing page, with three smaller images on the left.", 5 | link: "/", 6 | linkText: "Sign Up", 7 | }, 8 | { 9 | title: "Get a quick dashboard", 10 | description: "Here’s some more text you can edit for your landing page, with three smaller images on the left.", 11 | link: "/", 12 | linkText: "Sign Up", 13 | }, 14 | { 15 | title: "Get a quick dashboard", 16 | description: "Here’s some more text you can edit for your landing page, with three smaller images on the left.", 17 | link: "/", 18 | linkText: "Sign Up", 19 | }, 20 | { 21 | title: "Get a quick dashboard", 22 | description: "Here’s some more text you can edit for your landing page, with three smaller images on the left.", 23 | link: "/", 24 | linkText: "Sign Up", 25 | }, 26 | ]; 27 | 28 | // testimonial, firstName, lastName, title, company 29 | const TESTIMONIALS = [ 30 | { 31 | testimonial: "A testimonial quote from some user who uses your product and loves it!", 32 | firstName: "John", 33 | lastName: "Smith", 34 | title: "Software Engineer", 35 | company: "webapp.io" 36 | }, 37 | { 38 | testimonial: "A testimonial quote from some user who uses your product and loves it!", 39 | firstName: "John", 40 | lastName: "Smith", 41 | title: "Software Engineer", 42 | company: "webapp.io" 43 | }, 44 | { 45 | testimonial: "A testimonial quote from some user who uses your product and loves it!", 46 | firstName: "John", 47 | lastName: "Smith", 48 | title: "Software Engineer", 49 | company: "webapp.io" 50 | }, 51 | ] 52 | 53 | export { 54 | FEATURES, 55 | TESTIMONIALS, 56 | } -------------------------------------------------------------------------------- /examples/saas-landing/mui-theme.js: -------------------------------------------------------------------------------- 1 | import { createTheme } from "@mui/material"; 2 | 3 | const COLOURS = { 4 | PRIMARY: "#7689DE", 5 | SECONDARY: "#000000", 6 | }; 7 | 8 | const theme = createTheme({ 9 | palette: { 10 | primary: { 11 | main: COLOURS.PRIMARY, 12 | }, 13 | secondary: { 14 | main: COLOURS.SECONDARY 15 | }, 16 | contrastThreshold: 3, 17 | tonalOffset: 0.2, 18 | }, 19 | components: { 20 | MuiButton: { 21 | styleOverrides: { 22 | root: { 23 | borderRadius: "8px", 24 | } 25 | } 26 | } 27 | }, 28 | typography: { 29 | h1: { 30 | '@media (max-width: 600px)': { 31 | fontSize: "50px", 32 | } 33 | }, 34 | h2: { 35 | '@media (max-width: 600px)': { 36 | fontSize: "40px", 37 | } 38 | }, 39 | h3: { 40 | '@media (max-width: 600px)': { 41 | fontSize: "30px", 42 | } 43 | }, 44 | h4: { 45 | '@media (max-width: 600px)': { 46 | fontSize: "25px", 47 | } 48 | }, 49 | h5: { 50 | '@media (max-width: 600px)': { 51 | fontSize: "20px", 52 | } 53 | }, 54 | h6: { 55 | '@media (max-width: 600px)': { 56 | fontSize: "18px", 57 | } 58 | }, 59 | } 60 | }); 61 | 62 | export { 63 | theme, 64 | COLOURS, 65 | } -------------------------------------------------------------------------------- /examples/saas-landing/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "greenjs-example", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "@brainhubeu/react-carousel": "^2.0.4", 6 | "@emotion/react": "^11.7.1", 7 | "@emotion/styled": "^11.6.0", 8 | "@greenio/head": "0.0.4", 9 | "@greenio/react": "0.0.1", 10 | "@greenio/router": "0.0.3", 11 | "@mui/material": "^5.2.8", 12 | "react": "^17.0.2", 13 | "react-dom": "^17.0.2", 14 | "react-feather": "^2.0.9" 15 | }, 16 | "devDependencies": { 17 | "greenjs": "^1.0.0" 18 | }, 19 | "scripts": { 20 | "build": "greenjs build", 21 | "start": "greenjs start" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/saas-landing/pages/index.css: -------------------------------------------------------------------------------- 1 | .Hero--Div { 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | flex-wrap: wrap; 6 | margin-top: 80px; 7 | margin-bottom: 80px; 8 | padding: 40px; 9 | width: 80%; 10 | } 11 | .Hero--Text--Div { 12 | width: 50%; 13 | } 14 | 15 | .Hero--Image--Div { 16 | width: 50%; 17 | } 18 | .container { 19 | display: flex; 20 | justify-content: center; 21 | flex-wrap: wrap; 22 | } 23 | 24 | 25 | /* More Information */ 26 | .MoreInfo--Div { 27 | margin-top: 140px; 28 | margin-bottom: 140px; 29 | text-align: center; 30 | padding: 20px; 31 | } 32 | 33 | .MoreInfo--Main { 34 | display: flex; 35 | justify-content: center; 36 | align-items: center; 37 | margin-top: 140px; 38 | flex-wrap: wrap; 39 | } 40 | 41 | .MoreInfo--Main--Text { 42 | text-align: left; 43 | width: 100%; 44 | max-width: 750px; 45 | margin-left: 60px; 46 | } 47 | 48 | .MoreInfo--Main--Images { 49 | display: flex; 50 | flex-direction: row; 51 | align-items: flex-end; 52 | flex-wrap: wrap; 53 | margin-bottom: 30px; 54 | } 55 | 56 | .MoreInfo--Main--Image--Stacked { 57 | display: flex; 58 | flex-direction: column; 59 | padding-left: 20px; 60 | } 61 | /* End of More Inforamtion */ 62 | 63 | /* Large Image */ 64 | .LargeImage { 65 | display: flex; 66 | flex-direction: row; 67 | justify-content: center; 68 | text-align: center; 69 | margin-top: 100px; 70 | margin-bottom: 100px; 71 | } 72 | .LargeImage--Div { 73 | height: 60vh; 74 | width: 80%; 75 | } 76 | 77 | /* Feature Cards */ 78 | .FeatureCards { 79 | display: flex; 80 | flex-direction: row; 81 | justify-content: space-between; 82 | padding: 30px; 83 | flex-wrap: wrap; 84 | } 85 | .FeatureCard--Div { 86 | margin-top: 200px; 87 | margin-bottom: 200px; 88 | } 89 | 90 | /* TESTIMONIALS */ 91 | .Testimonials--Div { 92 | margin-top: 200px; 93 | margin-bottom: 200px; 94 | } 95 | .Testimonials { 96 | display: flex; 97 | flex-direction: row; 98 | justify-content: center; 99 | flex-wrap: wrap; 100 | padding: 30px; 101 | } 102 | 103 | .CTA { 104 | display: flex; 105 | justify-content: center; 106 | align-items: center; 107 | margin-bottom: 200px; 108 | flex-wrap: wrap; 109 | } 110 | .CTA--Button { 111 | font-size: 25px; 112 | width: 400px; 113 | max-width: 100%; 114 | margin: 10px; 115 | } 116 | 117 | .Carousel--ContainerDiv { 118 | display: flex; 119 | justify-content: center; 120 | align-items: center; 121 | } 122 | .Carousel--Container { 123 | width: 80%; 124 | } 125 | 126 | @media only screen and (max-width: 600px) { 127 | .MoreInfo--Main { 128 | margin-top: 50px; 129 | } 130 | .MoreInfo--Main--Images { 131 | display: none; 132 | } 133 | 134 | .Container { 135 | width: 100%; 136 | } 137 | 138 | .Hero--Div { 139 | margin-top: 30px; 140 | margin-bottom: 30px; 141 | padding: 10px; 142 | } 143 | 144 | .Hero--Text--Div { 145 | width: 100%; 146 | } 147 | 148 | .Hero--Image--Div { 149 | width: 100%; 150 | margin-top: 30px; 151 | } 152 | 153 | .LargeImage--Div { 154 | width: 95%; 155 | height: 40vh; 156 | } 157 | 158 | .MoreInfo--Div { 159 | margin-top: 80px; 160 | margin-bottom: 80px; 161 | } 162 | 163 | .MoreInfo--Main--Text { 164 | margin: 30px 5px 0px 5px; 165 | } 166 | 167 | .LargeImage { 168 | margin-top: 50px; 169 | margin-bottom: 50px; 170 | } 171 | .FeatureCard--Div { 172 | margin-top: 100px; 173 | margin-bottom: 50px; 174 | } 175 | .Testimonials--Div { 176 | margin-top: 50px; 177 | margin-bottom: 50px; 178 | } 179 | .Testimonials { 180 | padding: 10px; 181 | } 182 | } -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/webappio/greenjs 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/chromedp/cdproto v0.0.0-20211126220118-81fa0469ad77 7 | github.com/chromedp/chromedp v0.7.6 8 | github.com/evanw/esbuild v0.14.1 9 | github.com/fsnotify/fsnotify v1.5.1 10 | github.com/gorilla/websocket v1.4.2 11 | github.com/pkg/errors v0.9.1 12 | ) 13 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/chromedp/cdproto v0.0.0-20211126220118-81fa0469ad77 h1:Et/9YcQRCsaZVT74sy6AHwWy/FcbYqm39jNprlfXF7c= 2 | github.com/chromedp/cdproto v0.0.0-20211126220118-81fa0469ad77/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U= 3 | github.com/chromedp/chromedp v0.7.6 h1:2juGaktzjwULlsn+DnvIZXFUckEp5xs+GOBroaea+jA= 4 | github.com/chromedp/chromedp v0.7.6/go.mod h1:ayT4YU/MGAALNfOg9gNrpGSAdnU51PMx+FCeuT1iXzo= 5 | github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic= 6 | github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= 7 | github.com/evanw/esbuild v0.14.1 h1:ixWZ3MwLjTZp6WdDNfiZ6QhqgEryN8a0E5a8HDOmc58= 8 | github.com/evanw/esbuild v0.14.1/go.mod h1:GG+zjdi59yh3ehDn4ZWfPcATxjPDUH53iU4ZJbp7dkY= 9 | github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= 10 | github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= 11 | github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= 12 | github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= 13 | github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= 14 | github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= 15 | github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA= 16 | github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= 17 | github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= 18 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 19 | github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= 20 | github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= 21 | github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= 22 | github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 23 | github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5 h1:1SoBaSPudixRecmlHXb/GxmaD3fLMtHIDN13QujwQuc= 24 | github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= 25 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 26 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 27 | golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 28 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 29 | golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 30 | golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 h1:TyHqChC80pFkXWraUUf6RuB5IqFdQieMLwwCJokV2pc= 31 | golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 32 | -------------------------------------------------------------------------------- /modd.conf: -------------------------------------------------------------------------------- 1 | # to install modd: go get github.com/cortesi/modd/cmd/modd 2 | 3 | main.go **/*.go **/go.sum { 4 | prep: go build -o ~/go/bin/greenjs main.go 5 | } 6 | 7 | -------------------------------------------------------------------------------- /npm/create-greenjs-app/.gitignore: -------------------------------------------------------------------------------- 1 | template/package-lock.json -------------------------------------------------------------------------------- /npm/create-greenjs-app/main.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict'; 4 | 5 | const fs = require('fs'); 6 | const path = require('path'); 7 | const childProcess = require('child_process'); 8 | 9 | function copyFolderRecursiveSync(source, target) { 10 | if (!fs.existsSync(target)) { 11 | fs.mkdirSync(target); 12 | } 13 | 14 | if (fs.lstatSync(source).isDirectory()) { 15 | fs.readdirSync(source).forEach(file => { 16 | var curSource = path.join(source, file); 17 | if (fs.lstatSync(curSource).isDirectory()) { 18 | copyFolderRecursiveSync(curSource, path.join(target, path.basename(curSource))); 19 | } else { 20 | fs.writeFileSync(path.join(target, path.basename(curSource)), fs.readFileSync(curSource)); 21 | } 22 | }); 23 | } 24 | } 25 | 26 | // Check if the --template flag was used 27 | const TEMPLATES = { 28 | "docs": true, 29 | "profile": true, 30 | "saas-landing": true, 31 | "base-template": true, 32 | } 33 | let exampleTemplate = ""; 34 | for (let i = 0; i < process.argv.length; i++) { 35 | const command = process.argv[i]; 36 | if (command.includes("--template")) { 37 | const templateName = command.split("template=")[1]; 38 | if (templateName in TEMPLATES) { 39 | exampleTemplate = templateName; 40 | } 41 | } 42 | } 43 | 44 | if(process.argv.length > 4) { 45 | console.error("Usage: npx create-greenjs-example (destination directory) --template=\"\""); 46 | process.exit(1); 47 | } 48 | 49 | 50 | let dest = "saas-landing"; 51 | if((process.argv.length === 3 && exampleTemplate.length === 0) || process.argv.length === 4) { 52 | dest = process.argv[2]; 53 | } 54 | 55 | let templatePath = path.join(__dirname, "templates", "saas-landing"); 56 | if (exampleTemplate.length > 0) { 57 | templatePath = path.join(__dirname, "templates", exampleTemplate) 58 | } 59 | 60 | 61 | copyFolderRecursiveSync(templatePath, dest) 62 | 63 | process.chdir(dest); 64 | childProcess.execSync("npm install"); 65 | 66 | console.log("Successfully created greenjs project at " + dest); 67 | console.log("Go to the " + dest + " directory and run 'npm run start' to start the development server") -------------------------------------------------------------------------------- /npm/create-greenjs-app/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-greenjs-app", 3 | "version": "0.0.1", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /npm/create-greenjs-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-greenjs-app", 3 | "version": "0.0.13", 4 | "description": "Build greenjs projects with a single command", 5 | "bin": { 6 | "create-greenjs-app": "./main.js" 7 | }, 8 | "author": "Colin Chartier", 9 | "license": "MIT" 10 | } 11 | -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist/* 3 | !dist/static -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/base-template/App.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | margin: 0; 3 | font-family: sans-serif; 4 | } 5 | 6 | a { 7 | text-decoration: none; 8 | } 9 | 10 | .flex { 11 | display: flex; 12 | } 13 | 14 | .flex-col { 15 | flex-direction: column; 16 | } 17 | 18 | .items-center { 19 | align-items: center; 20 | } 21 | 22 | .bg-emerald-900 { 23 | background-color: #064E3B; 24 | } 25 | 26 | .text-white { 27 | color: white; 28 | } 29 | 30 | .font-bold { 31 | font-weight: bold; 32 | } 33 | 34 | .mx-8 { 35 | margin-left: 2rem; 36 | margin-right: 2rem; 37 | } 38 | 39 | .py-4 { 40 | padding-top: 1rem; 41 | padding-bottom: 1rem; 42 | } 43 | 44 | .text-lg { 45 | font-size: 1.125rem; 46 | line-height: 1.75rem; 47 | } 48 | 49 | .container { 50 | width: 100%; 51 | } 52 | 53 | @media (min-width: 640px) { 54 | .container { 55 | max-width: 640px; 56 | } 57 | } 58 | 59 | @media (min-width: 768px) { 60 | .container { 61 | max-width: 768px; 62 | } 63 | } 64 | 65 | @media (min-width: 1024px) { 66 | .container { 67 | max-width: 1024px; 68 | } 69 | } 70 | 71 | @media (min-width: 1280px) { 72 | .container { 73 | max-width: 1280px; 74 | } 75 | } 76 | 77 | @media (min-width: 1536px) { 78 | .container { 79 | max-width: 1536px; 80 | } 81 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/base-template/App.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React from "react"; 4 | import {Render} from "@greenio/react"; 5 | import {Head} from "@greenio/head"; 6 | import {Link, Route, Router} from "@greenio/router"; 7 | import Pricing from "./pages/pricing"; 8 | import Index from "./pages"; 9 | 10 | import "./App.css"; 11 | 12 | const Hello = () => { 13 | return
14 | {/* is how to specify metadata about the page*/} 15 | {/*Read more here: https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML*/} 16 | 17 | greenjs app! 18 | 19 | {/*this line is used to make sites mobile responsive*/} 20 | {/*Read more here: https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag*/} 21 | 22 | 23 | {/*Router lets you specify multiple pages, in this case one at localhost:8000/pricing and one at localhost:8000*/} 24 |
25 |
26 |
27 | 28 | GreenJS logo 29 | 30 | 31 | PRICING 32 | 33 |
34 |
35 |
36 | 37 | 38 | 39 | 40 |
41 |
42 |
43 | } 44 | 45 | Render(); -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/base-template/dist/static/greenjs-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/base-template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "greenjs-example", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "@greenio/head": "0.0.4", 6 | "@greenio/react": "0.0.1", 7 | "@greenio/router": "0.0.3", 8 | "react": "^17.0.2", 9 | "react-dom": "^17.0.2" 10 | }, 11 | "devDependencies": { 12 | "greenjs": "^1.0.6" 13 | }, 14 | "scripts": { 15 | "build": "greenjs build", 16 | "start": "greenjs start" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/base-template/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Index = () => { 4 | return
5 |

Index page

6 |
7 | } 8 | 9 | export default Index; -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/base-template/pages/pricing.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Head} from "@greenio/head"; 3 | 4 | const Pricing = () => { 5 | return
6 | 7 | Pricing page 8 | 9 |

Pricing!

10 |
11 | } 12 | 13 | export default Pricing; -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/App.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | margin: 0; 3 | font-family: sans-serif; 4 | } 5 | 6 | a { 7 | text-decoration: none; 8 | } 9 | 10 | .flex { 11 | display: flex; 12 | } 13 | 14 | .flex-col { 15 | flex-direction: column; 16 | } 17 | 18 | .flex-row { 19 | flex-direction: row; 20 | } 21 | 22 | .justify-content-center { 23 | justify-content: center; 24 | } 25 | 26 | .justify-content-between { 27 | justify-content: space-between; 28 | } 29 | 30 | .w-100 { 31 | width: 100%; 32 | } 33 | 34 | .items-center { 35 | align-items: center; 36 | } 37 | 38 | .bg-emerald-900 { 39 | background-color: #064E3B; 40 | } 41 | 42 | .text-white { 43 | color: white; 44 | } 45 | 46 | .font-bold { 47 | font-weight: bold; 48 | } 49 | 50 | .mx-8 { 51 | margin-left: 2rem; 52 | margin-right: 2rem; 53 | } 54 | 55 | .py-4 { 56 | padding-top: 1rem; 57 | padding-bottom: 1rem; 58 | } 59 | 60 | .text-lg { 61 | font-size: 1.125rem; 62 | line-height: 1.75rem; 63 | } 64 | 65 | 66 | h1 { 67 | font-size: 24px; 68 | font-weight: 600; 69 | color: rgb(25, 118, 210); 70 | } 71 | 72 | p, ul, ol { 73 | font-size: 16px; 74 | line-height: 25px; 75 | } 76 | 77 | code { 78 | color: red; 79 | } 80 | 81 | .nav--link { 82 | color: rgb(25, 118, 210); 83 | font-weight: 600; 84 | } 85 | 86 | .nav--link:hover { 87 | cursor: pointer; 88 | } 89 | 90 | .nav--sublink { 91 | color: black; 92 | font-weight: 400; 93 | } 94 | 95 | .nav--sublink__not-active { 96 | border-left: 2px solid lightgray; 97 | } 98 | .nav--sublink__active { 99 | border-left: 2px solid rgb(25, 118, 210); 100 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/App.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React from "react"; 4 | import {Render} from "@greenio/react"; 5 | import {Head} from "@greenio/head"; 6 | import {Route, Router} from "@greenio/router"; 7 | import Introduction from "./pages/introduction"; 8 | import Resources from "./pages/resources"; 9 | import { DocsLayout } from "./pages/common/docs-layout"; 10 | 11 | import "./App.css"; 12 | 13 | const Docs = () => { 14 | return
15 | 16 | Docs Template 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | } 28 | 29 | Render(); -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/greenjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "esbuild": { 3 | "entry_point_name": "App.js", 4 | "file_import_types": { 5 | ".css": "css", 6 | ".jpeg": "file", 7 | ".jpg": "file", 8 | ".js": "jsx", 9 | ".jsx": "jsx", 10 | ".png": "file", 11 | ".svg": "file", 12 | ".ts": "tsx", 13 | ".tsx": "tsx", 14 | ".md": "text" 15 | }, 16 | "out_dir": "dist", 17 | "minify_whitespace": "only-prod", 18 | "minify_syntax": "only-prod" 19 | }, 20 | "parallel_tasks": 16 21 | } 22 | -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "greenjs-example", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "@emotion/css": "^11.7.1", 6 | "@emotion/react": "^11.7.1", 7 | "@emotion/styled": "^11.6.0", 8 | "@greenio/head": "0.0.4", 9 | "@greenio/react": "0.0.1", 10 | "@greenio/router": "0.0.3", 11 | "@mui/material": "^5.2.8", 12 | "markdown-to-jsx": "^7.1.5", 13 | "react": "^17.0.2", 14 | "react-dom": "^17.0.2", 15 | "react-feather": "^2.0.9" 16 | }, 17 | "devDependencies": { 18 | "greenjs": "^1.0.6" 19 | }, 20 | "scripts": { 21 | "build": "greenjs build", 22 | "start": "greenjs start" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/docs/Links.js: -------------------------------------------------------------------------------- 1 | class DocLink { 2 | constructor(name, link, content) { 3 | this.name = name; 4 | this.link = link; 5 | this.content = content; 6 | } 7 | } 8 | 9 | export { 10 | DocLink, 11 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/docs/docs-search.js: -------------------------------------------------------------------------------- 1 | import { ALL_CONTENT } from "./index"; 2 | 3 | const getSearchResults = (searchQuery = "") => { 4 | if (searchQuery.length === 0) return {}; 5 | 6 | const query = searchQuery.toUpperCase().trim(); 7 | 8 | const searchResults = []; 9 | 10 | // Search by Section Title 11 | for (let i = 0; i < ALL_CONTENT.length; i++) { 12 | const page = ALL_CONTENT[i]; 13 | const main = page.MAIN; 14 | if (main?.name?.toUpperCase().includes(query)) { 15 | const searchContent = { 16 | Link: main.link, 17 | Name: main.name, 18 | Content: main.content, 19 | IsTitle: true, 20 | } 21 | searchResults.push(searchContent); 22 | } 23 | } 24 | 25 | 26 | // Search by Page Content Title 27 | 28 | // Search by Page Content 29 | for (let i = 0; i { 10 | return [ 11 | ...arr, 12 | { 13 | MAIN: content[0], 14 | CONTENT: content[1], 15 | } 16 | ]; 17 | }, []); 18 | 19 | export { 20 | ALL_CONTENT, 21 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/docs/introduction/confused.md: -------------------------------------------------------------------------------- 1 | ## Confused? 2 | 3 | If these docs are confusing to you, feel free to change them directly! Simply make a change locally and open a PR in the `examples/docs` repo for the greenjs project [here.](https://github.com/webappio/greenjs) 4 | 5 |
-------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/docs/introduction/docs-template.md: -------------------------------------------------------------------------------- 1 | ## Docs Template Structure 2 | 3 | This documentation template is structured in the following manner. After cloning or forking this template, you'll see the following: 4 | 5 | - docs 6 | - docs/pages 7 | - docs/pages/docs 8 | - docs/pages/common 9 | 10 | The `docs/pages/docs` folder contains all the relevant documentation in markdown files, the `DocLink` class, and the function needed to search through the docs. 11 | 12 | If you want to add to the existing docs do the following: 13 | 14 | 1. Create a Markdown file in one of the existing folders. 15 | 2. Import the Markdown file into the index.js file within the same folder. 16 | 3. Add a DocLink to the `CONTENT` array with the relevant information you need in the side navigation. 17 | 18 | If you want to add a new section to the docs, do the following: 19 | 20 | 1. Create a folder for the new sectiion in the `docs/pages/docs` folder. 21 | 2. Create a Markdown file with the necessary information. 22 | 3. Create an `index.js` file. 23 | 4. Copy an existing `index.js` structure from another folder. This must include a CONTENT array, and a MAIN `DocLink` which is to be exported. 24 | 5. Import the CONTENT array and MAIN `DocLink` created into the `docs/pages/docs/index.js` file and add it in the following order [MAIN, CONTENT]. 25 | 6. That's all! 26 | 27 |
-------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/docs/introduction/index.js: -------------------------------------------------------------------------------- 1 | import { DocLink } from "../Links"; 2 | import Welcome from "./welcome.md"; 3 | import UsingThis from "./using-this.md"; 4 | import DocsTemplate from "./docs-template.md"; 5 | import Linking from "./linking.md"; 6 | import Search from "./search.md"; 7 | import Confused from "./confused.md"; 8 | 9 | 10 | const CONTENT = [ 11 | new DocLink("Welcome", "/#introduction", Welcome), 12 | new DocLink("Docs Structure", "/#docs-template-structure", DocsTemplate), 13 | new DocLink("Linking to a Section", "/#linking-to-a-section", Linking), 14 | new DocLink("Search", "/#docs-search", Search), 15 | new DocLink("Confused?", "/#confused", Confused), 16 | new DocLink("End", "/#end-of-docs", UsingThis), 17 | ]; 18 | 19 | const MAIN = new DocLink("Introduction", "/", ""); 20 | 21 | export { 22 | CONTENT, 23 | MAIN, 24 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/docs/introduction/linking.md: -------------------------------------------------------------------------------- 1 | ## Linking to a Section 2 | 3 | The `markdown-to-jsx` module creates id's for all text headers that you add. For example if in your markdown you have the following: 4 | 5 | ``` 6 | ## Some Header 7 | ``` 8 | 9 | Then an id will be inserted in the HTML as follows: 10 | 11 | ``` 12 |

Some Header

13 | ``` 14 | 15 | This way, you don't have to specify each id in your markdown when creating/adding a `DocLink` to the navigation. 16 | 17 |
-------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/docs/introduction/search.md: -------------------------------------------------------------------------------- 1 | ## Docs Search 2 | 3 | For the purpose of these simple and fast docs, we use a string match to search through the documentation. When a user types into the search bar and hits the "Enter" key or clicks the search icon, we iterate through the content in the `DocLink` classes as exported from the `docs/pages/docs/index.js` file. 4 | 5 |
-------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/docs/introduction/using-this.md: -------------------------------------------------------------------------------- 1 | # END OF DOCS 2 | 3 | ## Some Random Text 4 | 5 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus ultrices justo, nec tincidunt diam venenatis sit amet. Nullam non aliquam arcu. Etiam velit massa, pellentesque vel ante id, ultrices lacinia leo. Sed a felis dictum nisl blandit tincidunt. Curabitur condimentum et augue et bibendum. Fusce semper nisl eu lacus auctor bibendum. Morbi ipsum felis, sagittis in consectetur porttitor, gravida sed elit. Nullam suscipit felis sed orci malesuada luctus. Proin eget magna dui. Quisque egestas lobortis luctus. Nam tincidunt luctus nibh in tristique. Nunc ac arcu ex.a 6 | 7 |
8 | 9 | ## More Random Text 10 | 11 | Vivamus scelerisque eget urna ac porta. Fusce id sem porttitor tortor efficitur accumsan quis at felis. Vivamus ultrices dictum ante. Mauris a sollicitudin urna. Nulla justo erat, facilisis commodo libero sit amet, iaculis molestie massa. Fusce urna erat, imperdiet fringilla enim vitae, imperdiet auctor lacus. Pellentesque turpis nisi, aliquet et iaculis sit amet, mollis ut erat. Proin mattis massa dolor, ultricies accumsan purus tristique interdum. Mauris sed massa erat. Nam sit amet turpis id nibh cursus commodo. Quisque sapien ante, ultricies eget mi et, ullamcorper scelerisque ligula. Etiam et eros commodo, finibus dolor a, ornare velit. Praesent nunc lectus, pulvinar rutrum tortor eu, viverra pharetra velit. Pellentesque consequat finibus dui, quis hendrerit lorem vestibulum ut. 12 | 13 |
14 | 15 | ### Some Random Text 16 | 17 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus ultrices justo, nec tincidunt diam venenatis sit amet. Nullam non aliquam arcu. Etiam velit massa, pellentesque vel ante id, ultrices lacinia leo. Sed a felis dictum nisl blandit tincidunt. Curabitur condimentum et augue et bibendum. Fusce semper nisl eu lacus auctor bibendum. Morbi ipsum felis, sagittis in consectetur porttitor, gravida sed elit. Nullam suscipit felis sed orci malesuada luctus. Proin eget magna dui. Quisque egestas lobortis luctus. Nam tincidunt luctus nibh in tristique. Nunc ac arcu ex.a 18 | 19 |
20 | 21 | ### More Random Text 22 | 23 | Vivamus scelerisque eget urna ac porta. Fusce id sem porttitor tortor efficitur accumsan quis at felis. Vivamus ultrices dictum ante. Mauris a sollicitudin urna. Nulla justo erat, facilisis commodo libero sit amet, iaculis molestie massa. Fusce urna erat, imperdiet fringilla enim vitae, imperdiet auctor lacus. Pellentesque turpis nisi, aliquet et iaculis sit amet, mollis ut erat. Proin mattis massa dolor, ultricies accumsan purus tristique interdum. Mauris sed massa erat. Nam sit amet turpis id nibh cursus commodo. Quisque sapien ante, ultricies eget mi et, ullamcorper scelerisque ligula. Etiam et eros commodo, finibus dolor a, ornare velit. Praesent nunc lectus, pulvinar rutrum tortor eu, viverra pharetra velit. Pellentesque consequat finibus dui, quis hendrerit lorem vestibulum ut. 24 | 25 |
26 | 27 | ## How to Use This 28 | 29 | Vivamus scelerisque eget urna ac porta. Fusce id sem porttitor tortor efficitur accumsan quis at felis. Vivamus ultrices dictum ante. Mauris a sollicitudin urna. Nulla justo erat, facilisis commodo libero sit amet, iaculis molestie massa. Fusce urna erat, imperdiet fringilla enim vitae, imperdiet auctor lacus. Pellentesque turpis nisi, aliquet et iaculis sit amet, mollis ut erat. Proin mattis massa dolor, ultricies accumsan purus tristique interdum. Mauris sed massa erat. Nam sit amet turpis id nibh cursus commodo. Quisque sapien ante, ultricies eget mi et, ullamcorper scelerisque ligula. Etiam et eros commodo, finibus dolor a, ornare velit. Praesent nunc lectus, pulvinar rutrum tortor eu, viverra pharetra velit. Pellentesque consequat finibus dui, quis hendrerit lorem vestibulum ut. -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/docs/introduction/welcome.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Welcome to the template Docs page! 4 | 5 |
6 | 7 | ## Green JS 8 | 9 | For more information on Green JS check out the official page [here.](https://greenjs.io/) 10 | 11 |
-------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/docs/resources/another.md: -------------------------------------------------------------------------------- 1 | ## Another 2 | 3 | Vivamus scelerisque eget urna ac porta. Fusce id sem porttitor tortor efficitur accumsan quis at felis. Vivamus ultrices dictum ante. Mauris a sollicitudin urna. Nulla justo erat, facilisis commodo libero sit amet, iaculis molestie massa. Fusce urna erat, imperdiet fringilla enim vitae, imperdiet auctor lacus. Pellentesque turpis nisi, aliquet et iaculis sit amet, mollis ut erat. Proin mattis massa dolor, ultricies accumsan purus tristique interdum. Mauris sed massa erat. Nam sit amet turpis id nibh cursus commodo. Quisque sapien ante, ultricies eget mi et, ullamcorper scelerisque ligula. Etiam et eros commodo, finibus dolor a, ornare velit. Praesent nunc lectus, pulvinar rutrum tortor eu, viverra pharetra velit. Pellentesque consequat finibus dui, quis hendrerit lorem vestibulum ut. -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/docs/resources/index.js: -------------------------------------------------------------------------------- 1 | import { DocLink } from "../Links"; 2 | import Intro from "./intro.md"; 3 | import Another from "./another.md"; 4 | 5 | const CONTENT = [ 6 | new DocLink("Extra", "/resources#something-else", Intro), 7 | new DocLink("Extra", "/resources#another", Another), 8 | ]; 9 | 10 | const MAIN = new DocLink("Resources", "/", ""); 11 | 12 | export { 13 | CONTENT, 14 | MAIN, 15 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/docs/resources/intro.md: -------------------------------------------------------------------------------- 1 | ### Something Else 2 | 3 | Vivamus scelerisque eget urna ac porta. Fusce id sem porttitor tortor efficitur accumsan quis at felis. Vivamus ultrices dictum ante. Mauris a sollicitudin urna. Nulla justo erat, facilisis commodo libero sit amet, iaculis molestie massa. Fusce urna erat, imperdiet fringilla enim vitae, imperdiet auctor lacus. Pellentesque turpis nisi, aliquet et iaculis sit amet, mollis ut erat. Proin mattis massa dolor, ultricies accumsan purus tristique interdum. Mauris sed massa erat. Nam sit amet turpis id nibh cursus commodo. Quisque sapien ante, ultricies eget mi et, ullamcorper scelerisque ligula. Etiam et eros commodo, finibus dolor a, ornare velit. Praesent nunc lectus, pulvinar rutrum tortor eu, viverra pharetra velit. Pellentesque consequat finibus dui, quis hendrerit lorem vestibulum ut. 4 | 5 | -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/introduction.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Head} from "@greenio/head"; 3 | import Markdown from "markdown-to-jsx"; 4 | import { CONTENT } from "./docs/introduction"; 5 | 6 | const Introduction = () => { 7 | return
8 | 9 | Introduction | Template Documentation 10 | 11 |
12 | { 13 | CONTENT.map((cont, index) => ( 14 | 15 | {cont.content} 16 | 17 | )) 18 | } 19 |
20 |
21 | } 22 | 23 | export default Introduction; -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/docs/pages/resources.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Head } from "@greenio/head"; 3 | import { CONTENT } from "./docs/resources"; 4 | import Markdown from "markdown-to-jsx"; 5 | 6 | const Resources = () => { 7 | return
8 | 9 | Resources | Template Documentation 10 | 11 |
12 | { 13 | CONTENT.map((cont, index) => ( 14 | 15 | {cont.content} 16 | 17 | )) 18 | } 19 |
20 |
21 | } 22 | 23 | export default Resources; -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/profile/App.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | margin: 0; 3 | font-family: sans-serif; 4 | } 5 | 6 | a { 7 | text-decoration: none; 8 | } 9 | 10 | .container { 11 | width: 100%; 12 | } 13 | 14 | .Page-Background { 15 | min-height: 100vh !important; 16 | width: 100vw !important; 17 | } 18 | 19 | .Content--Container { 20 | display: flex; 21 | justify-content: center; 22 | align-items: center; 23 | } 24 | 25 | 26 | @media (min-width: 640px) { 27 | .container { 28 | max-width: 640px; 29 | } 30 | } 31 | 32 | @media (min-width: 768px) { 33 | .container { 34 | max-width: 768px; 35 | } 36 | } 37 | 38 | @media (min-width: 1024px) { 39 | .container { 40 | max-width: 1024px; 41 | } 42 | } 43 | 44 | @media (min-width: 1280px) { 45 | .container { 46 | max-width: 1280px; 47 | } 48 | } 49 | 50 | @media (min-width: 1536px) { 51 | .container { 52 | max-width: 1536px; 53 | } 54 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/profile/App.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React, { useState } from "react"; 4 | import {Render} from "@greenio/react"; 5 | import {Head} from "@greenio/head"; 6 | import {Route, Router} from "@greenio/router"; 7 | import Projects from "./pages/projects"; 8 | import Index from "./pages"; 9 | import "./App.css"; 10 | import { renderToStaticMarkup } from "react-dom/server"; 11 | import { ThemeProvider } from "@mui/material/styles"; 12 | import { theme } from "./mui-theme"; 13 | 14 | const SVGBackground = ({ colour }) => { 15 | const lineColour = colour === COLOURS.DARK ? "white" : "black"; 16 | return ( 17 | 18 | 19 | 20 | 21 | ) 22 | }; 23 | 24 | const COLOURS = { 25 | LIGHT: "light", 26 | DARK: "dark", 27 | }; 28 | 29 | const ColourContext = React.createContext(COLOURS.LIGHT); 30 | 31 | const Hello = () => { 32 | const [colour, setColour] = useState(COLOURS.LIGHT); 33 | 34 | 35 | const backgroundStyles = { 36 | color: colour === COLOURS.LIGHT ? "black" : "#292929", 37 | backgroundColor: colour === COLOURS.LIGHT ? "#F3F3F3" : "#292929", 38 | }; 39 | const svgString = encodeURIComponent(renderToStaticMarkup()); 40 | const svgBackground = { 41 | backgroundImage: `url("data:image/svg+xml,${svgString}")`, 42 | backgroundRepeat: "no-repeat", 43 | backgroundPosition: "center", 44 | backgroundSize: "cover", 45 | } 46 | 47 | 48 | return ( 49 | 50 | 51 |
52 | 53 | Your Name | Profile 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 |
63 |
64 | ) 65 | } 66 | 67 | export { 68 | COLOURS, 69 | ColourContext, 70 | } 71 | 72 | Render(); -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/profile/common/Navbar.css: -------------------------------------------------------------------------------- 1 | .Navbar--Div { 2 | display: flex; 3 | padding: 30px; 4 | height: 100px; 5 | } 6 | .Navbar--Link { 7 | margin-right: 20px; 8 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/profile/common/Navbar.js: -------------------------------------------------------------------------------- 1 | import { Link } from "@greenio/router"; 2 | import React, { useContext } from "react"; 3 | import { Typography } from "@mui/material"; 4 | import "./Navbar.css"; 5 | import { COLOURS, ColourContext } from "../App"; 6 | import { Moon } from "react-feather"; 7 | 8 | 9 | const Navbar = () => { 10 | const { colour, setColour } = useContext(ColourContext); 11 | 12 | const fontStyles = { 13 | color: colour === COLOURS.LIGHT ? "black" : "white", 14 | }; 15 | const moonColor = colour === COLOURS.LIGHT ? "black" : "white"; 16 | 17 | return ( 18 |
19 | 20 | 21 | HOME 22 | 23 | 24 | 25 | 26 | PROJECTS 27 | 28 | 29 |
30 | { 33 | if (colour === COLOURS.LIGHT) { 34 | setColour(COLOURS.DARK); 35 | } else { 36 | setColour(COLOURS.LIGHT); 37 | } 38 | }} 39 | /> 40 |
41 |
42 | ) 43 | } 44 | 45 | export { 46 | Navbar, 47 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/profile/common/ProjectCard.css: -------------------------------------------------------------------------------- 1 | .ProjectCard--Div { 2 | width: calc(50% - 80px); 3 | height: 250px; 4 | margin: 20px; 5 | display: flex; 6 | justify-content: center; 7 | align-items: center; 8 | } 9 | 10 | .ProjectCard--Div:hover { 11 | cursor: pointer; 12 | } 13 | 14 | @media only screen and (max-width: 900px) { 15 | .ProjectCard--Div { 16 | width: 100%; 17 | } 18 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/profile/common/ProjectCard.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import "./ProjectCard.css"; 3 | import { COLOURS } from "../App"; 4 | import { Typography } from "@mui/material"; 5 | 6 | const ProjectCard = ({ name = "", description = "", link = "", images = [], colour, setOpen, setProject }) => { 7 | const cardStyles = { 8 | backgroundColor: colour === COLOURS.LIGHT ? "white" : "#292929", 9 | border: `5px solid ${colour === COLOURS.LIGHT ? "#292929" : "white" }` 10 | } 11 | const textColour = colour === COLOURS.LIGHT ? "black" : "white"; 12 | return ( 13 | <> 14 |
{ 16 | setProject({ 17 | NAME: name, 18 | DESCRIPTION: description, 19 | LINK: link, 20 | IMAGES: images 21 | }); 22 | setOpen(true); 23 | }} 24 | > 25 | 26 | {name} 27 | 28 |
29 | 30 | ) 31 | }; 32 | 33 | export { 34 | ProjectCard, 35 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/profile/lines-background.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/profile/mui-theme.js: -------------------------------------------------------------------------------- 1 | import { createTheme } from "@mui/material/styles"; 2 | 3 | 4 | const theme = createTheme({ 5 | typography: { 6 | h1: { 7 | '@media (max-width:600px)': { 8 | fontSize: "35px", 9 | } 10 | }, 11 | h2: { 12 | '@media (max-width:600px)': { 13 | fontSize: "30px", 14 | } 15 | }, 16 | h3: { 17 | '@media (max-width:600px)': { 18 | fontSize: "25px", 19 | } 20 | }, 21 | h4: { 22 | '@media (max-width:600px)': { 23 | fontSize: "22px", 24 | } 25 | }, 26 | h5: { 27 | '@media (max-width:600px)': { 28 | fontSize: "20px", 29 | } 30 | }, 31 | h6: { 32 | '@media (max-width:600px)': { 33 | fontSize: "18px", 34 | } 35 | }, 36 | } 37 | }) 38 | 39 | export { 40 | theme, 41 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/profile/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "greenjs-example", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "@emotion/react": "^11.7.1", 6 | "@emotion/styled": "^11.6.0", 7 | "@greenio/head": "0.0.4", 8 | "@greenio/react": "0.0.1", 9 | "@greenio/router": "0.0.3", 10 | "@mui/material": "^5.2.8", 11 | "react": "^17.0.2", 12 | "react-dom": "^17.0.2", 13 | "react-feather": "^2.0.9" 14 | }, 15 | "devDependencies": { 16 | "greenjs": "^1.0.6" 17 | }, 18 | "scripts": { 19 | "build": "greenjs build", 20 | "start": "greenjs start" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/profile/pages/index.css: -------------------------------------------------------------------------------- 1 | .Landing--Content { 2 | display: flex; 3 | flex-direction: column; 4 | width: 100%; 5 | justify-content: center; 6 | align-items: center; 7 | text-align: center; 8 | margin-top: 100px; 9 | } 10 | 11 | .Landing--Content--Image { 12 | height: 200px; 13 | width: 200px; 14 | border-radius: 50%; 15 | } 16 | 17 | .Landing--Content--Item { 18 | margin-bottom: 10px; 19 | } 20 | 21 | @media only screen and (max-width: 600px) { 22 | .Landing--Content { 23 | margin-top: 0px; 24 | } 25 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/profile/pages/index.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { Navbar } from "../common/Navbar"; 3 | import { COLOURS, ColourContext } from "../App"; 4 | import "./index.css"; 5 | import { Typography } from "@mui/material"; 6 | import { renderToStaticMarkup } from "react-dom/server"; 7 | 8 | const SVGBackground = ({ colour }) => { 9 | const lineColour = colour === COLOURS.DARK ? "white" : "black"; 10 | const backgroundColor = colour === COLOURS.DARK ? "#292929" : "#F3F3F3"; 11 | return ( 12 | 13 | 14 | 15 | 16 | 17 | ) 18 | }; 19 | 20 | const Index = () => { 21 | const { colour } = useContext(ColourContext); 22 | 23 | const textColour = colour === COLOURS.LIGHT ? "black" : "white"; 24 | 25 | const svgString = encodeURIComponent(renderToStaticMarkup()); 26 | const svgBackground = { 27 | backgroundImage: `url("data:image/svg+xml,${svgString}")`, 28 | backgroundRepeat: "no-repeat", 29 | backgroundPosition: "center", 30 | backgroundSize: "cover", 31 | } 32 | 33 | return ( 34 |
35 | 36 |
37 |
38 | Profile Image 43 | 44 | YOUR NAME 45 | 46 | 47 | YOUR POSITION 48 | 49 | 50 | +1 888-888-8888 51 | 52 | 53 | something@email.com 54 | 55 |
56 |
57 |
58 | ) 59 | } 60 | 61 | export default Index; -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/profile/pages/projects.css: -------------------------------------------------------------------------------- 1 | .ProjectCards--Div { 2 | display: flex; 3 | justify-content: space-between; 4 | align-items: center; 5 | flex-wrap: wrap; 6 | } 7 | 8 | .Project--Dialog { 9 | padding: 50px; 10 | } 11 | 12 | .LinkClass { 13 | padding: 10px 30px 10px 30px; 14 | text-align: center; 15 | font-weight: bold; 16 | } 17 | 18 | .ProjectImage--Div { 19 | display: flex; 20 | flex-direction: row; 21 | flex-wrap: wrap; 22 | justify-content: space-between; 23 | align-items: center; 24 | margin-top: 50px; 25 | } 26 | 27 | .ProjectImage--Container { 28 | width: calc(50% - 30px); 29 | height: 300px; 30 | margin-bottom: 20px; 31 | } 32 | 33 | .ProjectImage { 34 | width: 100%; 35 | height: 100%; 36 | object-fit: cover; 37 | border-radius: 20px; 38 | padding: 10px; 39 | background-color: black; 40 | } 41 | 42 | @media only screen and (max-width: 600px) { 43 | .LinkClass { 44 | padding: 10px; 45 | } 46 | .ProjectImage--Container { 47 | height: 200px; 48 | width: 100% !important; 49 | } 50 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/profile/pages/projects.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState } from "react"; 2 | import {Head} from "@greenio/head"; 3 | import { Navbar } from "../common/Navbar"; 4 | import { ProjectCard } from "../common/ProjectCard"; 5 | import { ColourContext, COLOURS } from "../App"; 6 | import { Dialog, Typography } from "@mui/material"; 7 | import "./projects.css"; 8 | 9 | 10 | const PROJECTS = [ 11 | { 12 | NAME: "PROJECT 1", 13 | DESCRIPTION: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", 14 | LINK: "https://greenjs.io", 15 | IMAGES: [ 16 | "", 17 | "" 18 | ], 19 | }, 20 | { 21 | NAME: "ANOTHER PROJECT", 22 | DESCRIPTION: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", 23 | LINK: "https://greenjs.io", 24 | IMAGES: [], 25 | }, 26 | ]; 27 | 28 | const Projects = () => { 29 | const [project, setProject] = useState({}); 30 | const [open, setOpen] = useState(false); 31 | const { colour } = useContext(ColourContext); 32 | const textColour = colour === COLOURS.LIGHT ? "black" : "white"; 33 | const backgroundColor = colour === COLOURS.LIGHT ? "#F3F3F3" : "#292929"; 34 | 35 | const linkStyles = { 36 | color: textColour, 37 | backgroundColor: backgroundColor, 38 | border: `5px solid ${textColour}`, 39 | }; 40 | 41 | return ( 42 | <> 43 | 44 | Your Name | Projects 45 | 46 | 47 | 48 | setOpen(false)} 53 | > 54 |
55 | 56 | {project.NAME} 57 | 58 | 59 | {project.DESCRIPTION} 60 | 61 | 62 | 63 | VIEW PROJECT 64 | 65 | 66 |
67 | {project?.IMAGES?.map(src => ( 68 |
69 | 70 |
71 | ))} 72 |
73 |
74 |
75 | 76 |
77 | 78 |
79 |
80 | { 81 | PROJECTS.map((project, index) => ( 82 | 92 | )) 93 | } 94 |
95 |
96 |
97 | 98 | ) 99 | } 100 | 101 | export default Projects; -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/App.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap'); 2 | 3 | body, html { 4 | font-family: 'Roboto', sans-serif; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/App.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React from "react"; 4 | import {Render} from "@greenio/react"; 5 | import {Head} from "@greenio/head"; 6 | import {Route, Router} from "@greenio/router"; 7 | import Index from "./pages"; 8 | import { theme } from "./mui-theme"; 9 | import { ThemeProvider } from "@mui/material/styles"; 10 | import "./App.css"; 11 | import '@brainhubeu/react-carousel/lib/style.css'; 12 | 13 | const Hello = () => { 14 | return
15 | 16 | SaaS Landing Page 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 |
27 |
28 | } 29 | 30 | Render(); -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/common/FeatureCard.css: -------------------------------------------------------------------------------- 1 | .FeatureCard { 2 | width: 100%; 3 | min-width: 200px; 4 | max-width: 400px; 5 | padding: 30px; 6 | } 7 | 8 | @media only screen and (max-width: 600px) { 9 | .FeatureCard { 10 | padding: 0px; 11 | margin-bottom: 30px; 12 | width: 100%; 13 | max-width: 600px; 14 | } 15 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/common/FeatureCard.js: -------------------------------------------------------------------------------- 1 | import { Link } from "@greenio/router"; 2 | import { Typography } from "@mui/material"; 3 | import React from "react"; 4 | import { PlaceholderImage } from "./placeholder-image"; 5 | import "./FeatureCard.css"; 6 | import { COLOURS } from "../mui-theme"; 7 | 8 | const FeatureCard = ({ title, description, link, linkText }) => { 9 | return ( 10 |
11 |
12 | 13 |
14 | 15 | {title} 16 | 17 | 18 | {description} 19 | 20 |
21 | 22 | 23 | {linkText} 24 | 25 | 26 |
27 |
28 | ) 29 | }; 30 | 31 | export { 32 | FeatureCard, 33 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/common/Footer.css: -------------------------------------------------------------------------------- 1 | .Footer--Div { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: space-between; 5 | min-height: 350px; 6 | padding: 50px; 7 | background-color: #FBFBFB; 8 | } 9 | 10 | .Footer--Links { 11 | display: flex; 12 | flex-direction: row; 13 | flex-wrap: wrap; 14 | } 15 | 16 | .Footer--Base { 17 | padding-bottom: 40px; 18 | } 19 | 20 | .Footer--Base--Links { 21 | display: flex; 22 | flex-direction: row; 23 | justify-content: space-between; 24 | flex-wrap: wrap; 25 | } 26 | 27 | @media only screen and (max-width: 600px) { 28 | .Footer--Div { 29 | padding: 30px; 30 | } 31 | 32 | .Footer--Links > div { 33 | margin-bottom: 30px; 34 | } 35 | .Footer--Base--Links > div { 36 | margin-bottom: 10px; 37 | } 38 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/common/Footer.js: -------------------------------------------------------------------------------- 1 | import { Typography } from "@mui/material"; 2 | import React from "react"; 3 | import "./Footer.css"; 4 | 5 | const Footer = () => { 6 | return ( 7 |
8 |
9 |
10 | 11 | Product 12 | 13 | 14 | Feature 1 15 | 16 | 17 | Feature 2 18 | 19 |
20 |
21 | 22 | Contact 23 | 24 | 25 | support@yourcompany.com 26 | 27 | 28 | +1 888-888-8888 29 | 30 |
31 |
32 |
33 |
34 |
35 |
36 | 37 | With love, from Green JS 38 | 39 |
40 |
41 | 42 | Privacy Policy 43 | 44 | 45 | Security 46 | 47 |
48 |
49 | 50 | YOUR COMPANY INC. 51 | 52 |
53 |
54 |
55 |
56 | ) 57 | } 58 | 59 | export { 60 | Footer, 61 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/common/Navbar.css: -------------------------------------------------------------------------------- 1 | .Navbar-Items { 2 | display: block; 3 | } 4 | .Navbar--Items--Small { 5 | display: none !important; 6 | } 7 | 8 | @media only screen and (max-width: 600px) { 9 | .Navbar-Items { 10 | display: none !important; 11 | } 12 | .Navbar--Items--Small { 13 | display: block !important; 14 | } 15 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/common/Navbar.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { Button, Typography, Box, Drawer } from "@mui/material"; 3 | import { PlaceholderImage } from "./placeholder-image"; 4 | import "./Navbar.css"; 5 | import { Menu } from "react-feather"; 6 | 7 | const flexRowStyle = { 8 | display: "flex", 9 | flexDirection: "row", 10 | justifyContent: "space-between", 11 | alignItems: "center" 12 | }; 13 | 14 | const Navbar = () => { 15 | const [open, setOpen] = useState(false); 16 | return ( 17 | <> 18 | setOpen(false)} 21 | > 22 |
23 |
24 | 25 |
26 |
27 | 28 | Product 29 | 30 | 31 | Pricing 32 | 33 |
34 |
35 | 38 | 39 |
40 | 41 |
42 | 43 | Product 44 | 45 | 46 | Pricing 47 | 48 |
49 | 50 | setOpen(true)} /> 51 | 52 | 58 | 64 | 65 | 66 | 67 | ) 68 | } 69 | 70 | export { 71 | Navbar, 72 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/common/TestimonialCard.css: -------------------------------------------------------------------------------- 1 | .TestimonialCard--Div { 2 | width: 100%; 3 | min-width: 200px; 4 | max-width: 1000px; 5 | padding: 20px; 6 | display: flex; 7 | flex-direction: column; 8 | justify-content: space-evenly; 9 | align-items: center; 10 | height: 80%; 11 | min-height: 300px; 12 | border-radius: 20px; 13 | margin: 20px; 14 | } 15 | 16 | .TestimonialCard--Image { 17 | 18 | } 19 | 20 | .TestimonialCard--Quote { 21 | padding: 30px; 22 | text-align: center; 23 | } 24 | 25 | .TestimonialCard--Details { 26 | display: flex; 27 | flex-direction: column; 28 | justify-content: center; 29 | align-items: center; 30 | } 31 | 32 | @media only screen and (max-width: 600px) { 33 | .TestimonialCard--Div { 34 | width: 100%; 35 | max-width: 600px; 36 | margin: 10px; 37 | } 38 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/common/TestimonialCard.js: -------------------------------------------------------------------------------- 1 | import { Typography } from "@mui/material"; 2 | import React from "react"; 3 | import { PlaceholderImage } from "./placeholder-image"; 4 | import "./TestimonialCard.css"; 5 | import { COLOURS } from "../mui-theme"; 6 | 7 | const DIV_STYLES = { 8 | border: `5px solid ${COLOURS.PRIMARY}`, 9 | }; 10 | 11 | const TestimonialCard = ({ testimonial, firstName, lastName, title, company }) => { 12 | return ( 13 |
14 |
15 | 16 |
17 |
18 | 19 | "{testimonial}" 20 | 21 |
22 |
23 | 24 | 25 | {firstName} {lastName} 26 | 27 | 28 | {title} @ {company} 29 | 30 |
31 |
32 | ) 33 | } 34 | 35 | export { 36 | TestimonialCard, 37 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/common/placeholder-image.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const PlaceholderImage = ({ height, width, text, style = {} }) => { 4 | return ( 5 |
18 | {text} 19 |
20 | ) 21 | } 22 | 23 | export { 24 | PlaceholderImage, 25 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/data.js: -------------------------------------------------------------------------------- 1 | const FEATURES = [ 2 | { 3 | title: "Get a quick dashboard", 4 | description: "Here’s some more text you can edit for your landing page, with three smaller images on the left.", 5 | link: "/", 6 | linkText: "Sign Up", 7 | }, 8 | { 9 | title: "Get a quick dashboard", 10 | description: "Here’s some more text you can edit for your landing page, with three smaller images on the left.", 11 | link: "/", 12 | linkText: "Sign Up", 13 | }, 14 | { 15 | title: "Get a quick dashboard", 16 | description: "Here’s some more text you can edit for your landing page, with three smaller images on the left.", 17 | link: "/", 18 | linkText: "Sign Up", 19 | }, 20 | { 21 | title: "Get a quick dashboard", 22 | description: "Here’s some more text you can edit for your landing page, with three smaller images on the left.", 23 | link: "/", 24 | linkText: "Sign Up", 25 | }, 26 | ]; 27 | 28 | // testimonial, firstName, lastName, title, company 29 | const TESTIMONIALS = [ 30 | { 31 | testimonial: "A testimonial quote from some user who uses your product and loves it!", 32 | firstName: "John", 33 | lastName: "Smith", 34 | title: "Software Engineer", 35 | company: "webapp.io" 36 | }, 37 | { 38 | testimonial: "A testimonial quote from some user who uses your product and loves it!", 39 | firstName: "John", 40 | lastName: "Smith", 41 | title: "Software Engineer", 42 | company: "webapp.io" 43 | }, 44 | { 45 | testimonial: "A testimonial quote from some user who uses your product and loves it!", 46 | firstName: "John", 47 | lastName: "Smith", 48 | title: "Software Engineer", 49 | company: "webapp.io" 50 | }, 51 | ] 52 | 53 | export { 54 | FEATURES, 55 | TESTIMONIALS, 56 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/mui-theme.js: -------------------------------------------------------------------------------- 1 | import { createTheme } from "@mui/material"; 2 | 3 | const COLOURS = { 4 | PRIMARY: "#7689DE", 5 | SECONDARY: "#000000", 6 | }; 7 | 8 | const theme = createTheme({ 9 | palette: { 10 | primary: { 11 | main: COLOURS.PRIMARY, 12 | }, 13 | secondary: { 14 | main: COLOURS.SECONDARY 15 | }, 16 | contrastThreshold: 3, 17 | tonalOffset: 0.2, 18 | }, 19 | components: { 20 | MuiButton: { 21 | styleOverrides: { 22 | root: { 23 | borderRadius: "8px", 24 | } 25 | } 26 | } 27 | }, 28 | typography: { 29 | h1: { 30 | '@media (max-width: 600px)': { 31 | fontSize: "50px", 32 | } 33 | }, 34 | h2: { 35 | '@media (max-width: 600px)': { 36 | fontSize: "40px", 37 | } 38 | }, 39 | h3: { 40 | '@media (max-width: 600px)': { 41 | fontSize: "30px", 42 | } 43 | }, 44 | h4: { 45 | '@media (max-width: 600px)': { 46 | fontSize: "25px", 47 | } 48 | }, 49 | h5: { 50 | '@media (max-width: 600px)': { 51 | fontSize: "20px", 52 | } 53 | }, 54 | h6: { 55 | '@media (max-width: 600px)': { 56 | fontSize: "18px", 57 | } 58 | }, 59 | } 60 | }); 61 | 62 | export { 63 | theme, 64 | COLOURS, 65 | } -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "greenjs-example", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "@brainhubeu/react-carousel": "^2.0.4", 6 | "@emotion/react": "^11.7.1", 7 | "@emotion/styled": "^11.6.0", 8 | "@greenio/head": "0.0.4", 9 | "@greenio/react": "0.0.1", 10 | "@greenio/router": "0.0.3", 11 | "@mui/material": "^5.2.8", 12 | "react": "^17.0.2", 13 | "react-dom": "^17.0.2", 14 | "react-feather": "^2.0.9" 15 | }, 16 | "devDependencies": { 17 | "greenjs": "^1.0.6" 18 | }, 19 | "scripts": { 20 | "build": "greenjs build", 21 | "start": "greenjs start" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /npm/create-greenjs-app/templates/saas-landing/pages/index.css: -------------------------------------------------------------------------------- 1 | .Hero--Div { 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | flex-wrap: wrap; 6 | margin-top: 80px; 7 | margin-bottom: 80px; 8 | padding: 40px; 9 | width: 80%; 10 | } 11 | .Hero--Text--Div { 12 | width: 50%; 13 | } 14 | 15 | .Hero--Image--Div { 16 | width: 50%; 17 | } 18 | .container { 19 | display: flex; 20 | justify-content: center; 21 | flex-wrap: wrap; 22 | } 23 | 24 | 25 | /* More Information */ 26 | .MoreInfo--Div { 27 | margin-top: 140px; 28 | margin-bottom: 140px; 29 | text-align: center; 30 | padding: 20px; 31 | } 32 | 33 | .MoreInfo--Main { 34 | display: flex; 35 | justify-content: center; 36 | align-items: center; 37 | margin-top: 140px; 38 | flex-wrap: wrap; 39 | } 40 | 41 | .MoreInfo--Main--Text { 42 | text-align: left; 43 | width: 100%; 44 | max-width: 750px; 45 | margin-left: 60px; 46 | } 47 | 48 | .MoreInfo--Main--Images { 49 | display: flex; 50 | flex-direction: row; 51 | align-items: flex-end; 52 | flex-wrap: wrap; 53 | margin-bottom: 30px; 54 | } 55 | 56 | .MoreInfo--Main--Image--Stacked { 57 | display: flex; 58 | flex-direction: column; 59 | padding-left: 20px; 60 | } 61 | /* End of More Inforamtion */ 62 | 63 | /* Large Image */ 64 | .LargeImage { 65 | display: flex; 66 | flex-direction: row; 67 | justify-content: center; 68 | text-align: center; 69 | margin-top: 100px; 70 | margin-bottom: 100px; 71 | } 72 | .LargeImage--Div { 73 | height: 60vh; 74 | width: 80%; 75 | } 76 | 77 | /* Feature Cards */ 78 | .FeatureCards { 79 | display: flex; 80 | flex-direction: row; 81 | justify-content: space-between; 82 | padding: 30px; 83 | flex-wrap: wrap; 84 | } 85 | .FeatureCard--Div { 86 | margin-top: 200px; 87 | margin-bottom: 200px; 88 | } 89 | 90 | /* TESTIMONIALS */ 91 | .Testimonials--Div { 92 | margin-top: 200px; 93 | margin-bottom: 200px; 94 | } 95 | .Testimonials { 96 | display: flex; 97 | flex-direction: row; 98 | justify-content: center; 99 | flex-wrap: wrap; 100 | padding: 30px; 101 | } 102 | 103 | .CTA { 104 | display: flex; 105 | justify-content: center; 106 | align-items: center; 107 | margin-bottom: 200px; 108 | flex-wrap: wrap; 109 | } 110 | .CTA--Button { 111 | font-size: 25px; 112 | width: 400px; 113 | max-width: 100%; 114 | margin: 10px; 115 | } 116 | 117 | .Carousel--ContainerDiv { 118 | display: flex; 119 | justify-content: center; 120 | align-items: center; 121 | } 122 | .Carousel--Container { 123 | width: 80%; 124 | } 125 | 126 | @media only screen and (max-width: 600px) { 127 | .MoreInfo--Main { 128 | margin-top: 50px; 129 | } 130 | .MoreInfo--Main--Images { 131 | display: none; 132 | } 133 | 134 | .Container { 135 | width: 100%; 136 | } 137 | 138 | .Hero--Div { 139 | margin-top: 30px; 140 | margin-bottom: 30px; 141 | padding: 10px; 142 | } 143 | 144 | .Hero--Text--Div { 145 | width: 100%; 146 | } 147 | 148 | .Hero--Image--Div { 149 | width: 100%; 150 | margin-top: 30px; 151 | } 152 | 153 | .LargeImage--Div { 154 | width: 95%; 155 | height: 40vh; 156 | } 157 | 158 | .MoreInfo--Div { 159 | margin-top: 80px; 160 | margin-bottom: 80px; 161 | } 162 | 163 | .MoreInfo--Main--Text { 164 | margin: 30px 5px 0px 5px; 165 | } 166 | 167 | .LargeImage { 168 | margin-top: 50px; 169 | margin-bottom: 50px; 170 | } 171 | .FeatureCard--Div { 172 | margin-top: 100px; 173 | margin-bottom: 50px; 174 | } 175 | .Testimonials--Div { 176 | margin-top: 50px; 177 | margin-bottom: 50px; 178 | } 179 | .Testimonials { 180 | padding: 10px; 181 | } 182 | } -------------------------------------------------------------------------------- /npm/greenjs/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist 2 | -------------------------------------------------------------------------------- /npm/greenjs/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "oclif", 4 | "oclif-typescript" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /npm/greenjs/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | versioning-strategy: increase 5 | directory: "/" 6 | schedule: 7 | interval: "monthly" 8 | labels: 9 | - "dependencies" 10 | open-pull-requests-limit: 100 11 | pull-request-branch-name: 12 | separator: "-" 13 | ignore: 14 | - dependency-name: "fs-extra" 15 | - dependency-name: "*" 16 | update-types: ["version-update:semver-major"] 17 | -------------------------------------------------------------------------------- /npm/greenjs/.gitignore: -------------------------------------------------------------------------------- 1 | *-debug.log 2 | *-error.log 3 | /.nyc_output 4 | /dist 5 | /lib 6 | /package-lock.json 7 | /tmp 8 | /yarn.lock 9 | node_modules 10 | oclif.manifest.json 11 | -------------------------------------------------------------------------------- /npm/greenjs/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Salesforce 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /npm/greenjs/README.md: -------------------------------------------------------------------------------- 1 | greenjs 2 | ================= 3 | 4 | GreenJS CLI 5 | 6 | 7 | * [Usage](#usage) 8 | * [Commands](#commands) 9 | 10 | # Usage 11 | 12 | ```sh-session 13 | $ npm install -g greenjs 14 | $ greenjs COMMAND 15 | running command... 16 | $ greenjs (--version) 17 | greenjs/2.0.9 linux-x64 node-v16.13.2 18 | $ greenjs --help [COMMAND] 19 | USAGE 20 | $ greenjs COMMAND 21 | ... 22 | ``` 23 | 24 | # Commands 25 | 26 | * [`greenjs build`](#greenjs-build) 27 | * [`greenjs help [COMMAND]`](#greenjs-help-command) 28 | * [`greenjs start`](#greenjs-start) 29 | 30 | ## `greenjs build` 31 | 32 | Make a production build of the project 33 | 34 | ``` 35 | USAGE 36 | $ greenjs build [-f ] 37 | 38 | FLAGS 39 | -f, --from= Whom is saying hello 40 | 41 | DESCRIPTION 42 | Make a production build of the project 43 | 44 | EXAMPLES 45 | $ greenjs build 46 | Source has been written to the dist/ folder! 47 | ``` 48 | 49 | _See code: [dist/commands/build.ts](https://github.com/ColinChartier/hello-world/blob/v2.0.9/dist/commands/build.ts)_ 50 | 51 | ## `greenjs help [COMMAND]` 52 | 53 | Display help for greenjs. 54 | 55 | ``` 56 | USAGE 57 | $ greenjs help [COMMAND] [-n] 58 | 59 | ARGUMENTS 60 | COMMAND Command to show help for. 61 | 62 | FLAGS 63 | -n, --nested-commands Include all nested commands in the output. 64 | 65 | DESCRIPTION 66 | Display help for greenjs. 67 | ``` 68 | 69 | _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.1.11/src/commands/help.ts)_ 70 | 71 | ## `greenjs start` 72 | 73 | Start a development server for the project 74 | 75 | ``` 76 | USAGE 77 | $ greenjs start [-h ] [-p ] [-u ] 78 | 79 | FLAGS 80 | -h, --host= Which address to listen to 81 | -p, --port= Which port to listen to 82 | -u, --upstream-addr= Where to forward upstream requests 83 | 84 | DESCRIPTION 85 | Start a development server for the project 86 | 87 | EXAMPLES 88 | $ greenjs start 89 | Pre-bundling dependencies: 90 | react-dom 91 | @greenio/head 92 | @greenio/router 93 | react/jsx-dev-runtime 94 | (this will be run only when your dependencies or config have changed) 95 | > Local: http://localhost:3000/ 96 | > Network: use `--host` to expose 97 | ``` 98 | 99 | _See code: [dist/commands/start.ts](https://github.com/ColinChartier/hello-world/blob/v2.0.9/dist/commands/start.ts)_ 100 | 101 | -------------------------------------------------------------------------------- /npm/greenjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "greenjs", 3 | "version": "2.0.12", 4 | "description": "GreenJS - Add React to existing sites", 5 | "author": "Colin Chartier", 6 | "bin": { 7 | "greenjs": "./dist/index.js" 8 | }, 9 | "homepage": "https://github.com/webappio/greenjs", 10 | "license": "MIT", 11 | "type": "module", 12 | "main": "dist/index.js", 13 | "module": "dist/index.js", 14 | "repository": "ColinChartier/hello-world", 15 | "files": [ 16 | "/dist", 17 | "/npm-shrinkwrap.json" 18 | ], 19 | "dependencies": { 20 | "@vitejs/plugin-react": "^1.2.0", 21 | "http-proxy-middleware": "^2.0.3", 22 | "minimist": "^1.2.5", 23 | "vite": "^2.8.3" 24 | }, 25 | "devDependencies": { 26 | "@types/babel__core": "^7.1.18", 27 | "@types/express": "^4.17.13", 28 | "@types/http-proxy": "^1.17.8", 29 | "@types/minimist": "^1.2.2", 30 | "@types/node": "^16.9.4", 31 | "eslint": "^7.32.0", 32 | "shx": "^0.3.3", 33 | "ts-node": "^10.2.1", 34 | "tslib": "^2.3.1", 35 | "typescript": "^4.4.3" 36 | }, 37 | "scripts": { 38 | "build": "shx rm -rf dist && tsc -b && chmod +x dist/index.js", 39 | "lint": "eslint . --ext .ts --config .eslintrc", 40 | "prepack": "npm run build" 41 | }, 42 | "engines": { 43 | "node": ">=12.0.0" 44 | }, 45 | "bugs": "https://github.com/ColinChartier/hello-world/issues", 46 | "types": "dist/index.d.ts" 47 | } 48 | -------------------------------------------------------------------------------- /npm/greenjs/src/commands/start.ts: -------------------------------------------------------------------------------- 1 | import {createServer} from 'vite' 2 | import react from '@vitejs/plugin-react'; 3 | import GreenJSEntryPlugin from "../greenjs-entry-plugin.js"; 4 | import {routeMatches} from "../routeMatches.js"; 5 | import {access} from "fs"; 6 | 7 | 8 | export default class Start { 9 | static description = 'Start a development server for the project' 10 | 11 | static examples = [ 12 | `$ greenjs start 13 | Pre-bundling dependencies: 14 | react-dom 15 | @greenio/head 16 | @greenio/router 17 | react/jsx-dev-runtime 18 | (this will be run only when your dependencies or config have changed) 19 | > Local: http://localhost:3000/ 20 | > Network: use \`--host\` to expose 21 | `, 22 | ] 23 | 24 | static args = [] 25 | 26 | // static flags = { 27 | // 'upstream-addr': Flags.string({char: 'u', description: 'Where to forward upstream requests', required: false}) 28 | // }; 29 | 30 | async run(upstreamAddr: string) { 31 | // const {args, flags} = await this.parse(Start) 32 | const knownRoutes = new Set(); 33 | const knownNotRoutes = new Set(); 34 | let checkKnownRoute: (route: string) => Promise = async route => {}; 35 | let isKnownRoute = async (path: string) => { 36 | try { 37 | await checkKnownRoute(path); 38 | } catch (e) { 39 | console.error(e); 40 | return true; //on error, show it to the user 41 | } 42 | if(knownRoutes.has(path)) { 43 | return true; 44 | } 45 | for(let route of knownRoutes) { 46 | if(routeMatches(route, path)) { 47 | return true; 48 | } 49 | } 50 | return false; 51 | }; 52 | 53 | let configAccessErr = await new Promise(resolve => access("greenjs.config.js", err => err ? resolve(err) : resolve(null))); 54 | 55 | if(configAccessErr) { 56 | console.log("Configuration file at greenjs.config.js does not exist. Using default configuration."); 57 | } 58 | const server = await createServer({ 59 | plugins: [ 60 | react(), 61 | GreenJSEntryPlugin(isKnownRoute, upstreamAddr), 62 | ], 63 | publicDir: "dist", 64 | configFile: !configAccessErr ? "greenjs.config.js" : false, 65 | }); 66 | (async () => { 67 | const {render} = await server.ssrLoadModule("/@greenjs-entry-server.jsx"); 68 | checkKnownRoute = async route => { 69 | if(knownRoutes.has(route)) { 70 | return; 71 | } 72 | const ctx = { 73 | routes: {}, 74 | headTags: [], 75 | }; 76 | await render("http://localhost" + route, ctx); 77 | Object.keys(ctx.routes).forEach(x => knownRoutes.add(x)); 78 | } 79 | })().catch(x => { 80 | console.error("Error finding routes: " + x) 81 | if(x.stack) { 82 | console.error(x.stack); 83 | } 84 | }); 85 | await server.listen(); 86 | server.printUrls(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /npm/greenjs/src/greenjs-entry-plugin.ts: -------------------------------------------------------------------------------- 1 | import {CustomPluginOptions, LoadResult, ResolveIdResult, TransformResult, OutputOptions} from "rollup"; 2 | import {GenerateEntryClient, GenerateEntryServer, GenerateIndex} from "./resources.js"; 3 | import {PluginOption, send} from "vite"; 4 | import {basename} from "path"; 5 | import {createProxyMiddleware} from 'http-proxy-middleware'; 6 | 7 | export default function GreenJSEntryPlugin( 8 | isKnownRoute?: (route: string) => Promise, 9 | upstreamAddr?: string 10 | ): PluginOption { 11 | return { 12 | name: 'greenjs-entry-plugin', 13 | resolveId(source: string, importer: string | undefined, options: { 14 | custom?: CustomPluginOptions; 15 | ssr?: boolean; 16 | }): Promise | ResolveIdResult { 17 | // console.log("resolve: " + source); 18 | if(basename(source) === "index.html") { 19 | return {id: 'index.html'}; 20 | } 21 | if(source.replace("/", "") === "@greenjs-entry-client.jsx") { 22 | return {id: "entry-client.jsx"} 23 | } 24 | if(source.replace("/", "") === "@greenjs-entry-server.jsx") { 25 | return {id: "entry-server.jsx"} 26 | } 27 | }, 28 | load(id: string, options?: { ssr?: boolean }): Promise | LoadResult { 29 | // console.log("load: " + id); 30 | if(id === 'index.html') { 31 | return GenerateIndex("", "", ``); 32 | } 33 | if(id === 'entry-client.jsx') { 34 | return GenerateEntryClient(); 35 | } 36 | if(id === 'entry-server.jsx') { 37 | return GenerateEntryServer(); 38 | } 39 | }, 40 | async configureServer(server): Promise<() => void> { 41 | const proxy = upstreamAddr ? createProxyMiddleware({target: upstreamAddr, changeOrigin: true}) : undefined; 42 | 43 | return () => { 44 | server.middlewares.use(async (req, res, next) => { 45 | if (!isKnownRoute || !await isKnownRoute(req.originalUrl || req.url || "")) { 46 | //for requests to get to this middleware but not be a route, they're legitimate 404s or for the upstream 47 | if(proxy) { 48 | req.url = req.originalUrl; 49 | // @ts-ignore 50 | proxy(req, res, next); 51 | return; 52 | } else { 53 | next(); 54 | return; 55 | } 56 | } 57 | 58 | let html = await server.pluginContainer.load("index.html"); 59 | html = await server.transformIndexHtml("index.html", String(html), req?.originalUrl) 60 | return send(req, res, html, 'html', { 61 | headers: server.config.server.headers 62 | }) 63 | }) 64 | } 65 | }, 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /npm/greenjs/src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import ParseFlags from 'minimist'; 4 | import Build from "./commands/build.js"; 5 | import Start from "./commands/start.js"; 6 | 7 | const {_: args, ...flags} = ParseFlags(process.argv.slice(2)) 8 | if(args.length === 1 && args[0] === "build") { 9 | (new Build()).run().catch(x => console.error(x)); 10 | } else if (args.length === 1 && args[0] === "start") { 11 | (new Start()).run(flags["upstream-addr"]).catch(x => console.error(x)); 12 | } else { 13 | console.error("Usage: greenjs [build|start]") 14 | } -------------------------------------------------------------------------------- /npm/greenjs/src/resources.ts: -------------------------------------------------------------------------------- 1 | const GenerateIndex = (head: string, appHTML: string, importStatements: string | string[]) => ` 2 | 3 | 4 | 5 | 6 | 7 | ${head} 8 | 9 | 10 |
${appHTML}
11 | ${typeof importStatements !== "string" ? importStatements.join("\n") : importStatements} 12 | 13 | 14 | `.trim() 15 | 16 | const GenerateEntryServer = () => ` 17 | import ReactDOMServer from 'react-dom/server' 18 | import App from './App' 19 | import {Router} from "@greenio/router"; 20 | import {SSRContext} from "@greenio/head"; 21 | 22 | export async function render(url, context) { 23 | const element = 24 | 25 | 26 | 27 | ; 28 | ReactDOMServer.renderToStaticMarkup(element); 29 | await Promise.all([...Object.values(context.routePromises || {}), context.headPromise].filter(x => !!x)); 30 | return ReactDOMServer.renderToString(element); 31 | } 32 | `.trim() 33 | 34 | 35 | const GenerateEntryClient = () => ` 36 | import ReactDOM from 'react-dom' 37 | import App from './App' 38 | import {Router} from "@greenio/router" 39 | 40 | ReactDOM.hydrate(, document.getElementById('app')); 41 | `.trim(); 42 | 43 | export { GenerateIndex, GenerateEntryClient, GenerateEntryServer } 44 | -------------------------------------------------------------------------------- /npm/greenjs/src/routeMatches.ts: -------------------------------------------------------------------------------- 1 | export function routeMatches(route: string, path: string): boolean { 2 | const pathSplit = path.split("/"); 3 | const routeSplit = route.split("/"); 4 | 5 | for (let i = 0; i < routeSplit.length; i += 1) { 6 | if (routeSplit[i].charAt(0) === ":") { 7 | //route is of the form /hello/:param/something 8 | } else if (routeSplit[i].charAt(0) === "*") { 9 | //route is of the form /hello/*param 10 | return true; 11 | } else if (i >= pathSplit.length || pathSplit[i] !== routeSplit[i]) { 12 | return false; 13 | } 14 | } 15 | return routeSplit.length === pathSplit.length; 16 | } 17 | -------------------------------------------------------------------------------- /npm/greenjs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "module": "es2020", 5 | "moduleResolution": "Node", 6 | "outDir": "dist", 7 | "rootDir": "src", 8 | "strict": true, 9 | "target": "es2020", 10 | "allowSyntheticDefaultImports": true, 11 | }, 12 | "include": [ 13 | "src/**/*" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /npm/head/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules -------------------------------------------------------------------------------- /npm/head/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@greenio/head", 3 | "version": "0.0.12", 4 | "description": "Embed your tag directly into your React code", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "build": "vite build", 8 | "prepack": "npm run build" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/webappio/greenjs.git" 13 | }, 14 | "keywords": [ 15 | "head", 16 | "meta", 17 | "title", 18 | "react", 19 | "react-helmet", 20 | "greenjs" 21 | ], 22 | "author": "The GreenJS Authors", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/webappio/greenjs/issues" 26 | }, 27 | "homepage": "https://github.com/webappio/greenjs#readme", 28 | "peerDependencies": { 29 | "react": ">=16.8", 30 | "react-dom": ">=16.8" 31 | }, 32 | "devDependencies": { 33 | "vite": "^2.8.4" 34 | }, 35 | "files": ["dist"], 36 | "main": "./dist/greenjs-head.umd.js", 37 | "module": "./dist/greenjs-head.es.js", 38 | "exports": { 39 | ".": { 40 | "import": "./dist/greenjs-head.es.js", 41 | "require": "./dist/greenjs-head.umd.js" 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /npm/head/vite.config.js: -------------------------------------------------------------------------------- 1 | // vite.config.js 2 | const path = require('path') 3 | const { defineConfig } = require('vite') 4 | 5 | module.exports = defineConfig({ 6 | build: { 7 | lib: { 8 | entry: path.resolve(__dirname, 'Head.js'), 9 | name: 'Head', 10 | fileName: (format) => `greenjs-head.${format}.js` 11 | }, 12 | rollupOptions: { 13 | external: ['react'], 14 | output: { 15 | globals: { 16 | react: 'React' 17 | } 18 | } 19 | } 20 | } 21 | }) 22 | -------------------------------------------------------------------------------- /npm/router/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules -------------------------------------------------------------------------------- /npm/router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@greenio/router", 3 | "version": "0.0.18", 4 | "description": "Replacement for react-router-dom for GreenJS", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "build": "vite build", 8 | "prepack": "npm run build" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/webappio/greenjs.git" 13 | }, 14 | "keywords": [ 15 | "react", 16 | "react-router", 17 | "react-router-dom", 18 | "router", 19 | "greenjs" 20 | ], 21 | "author": "The GreenJS Authors", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/webappio/greenjs/issues" 25 | }, 26 | "homepage": "https://github.com/webappio/greenjs#readme", 27 | "peerDependencies": { 28 | "react": ">=16.8", 29 | "react-dom": ">=16.8" 30 | }, 31 | "devDependencies": { 32 | "vite": "^2.8.4" 33 | }, 34 | "files": ["dist"], 35 | "main": "./dist/greenjs-router.umd.js", 36 | "module": "./dist/greenjs-router.es.js", 37 | "exports": { 38 | ".": { 39 | "import": "./dist/greenjs-router.es.js", 40 | "require": "./dist/greenjs-router.umd.js" 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /npm/router/vite.config.js: -------------------------------------------------------------------------------- 1 | // vite.config.js 2 | const path = require('path') 3 | const { defineConfig } = require('vite') 4 | 5 | module.exports = defineConfig({ 6 | build: { 7 | lib: { 8 | entry: path.resolve(__dirname, 'router.jsx'), 9 | name: 'router', 10 | fileName: (format) => `greenjs-router.${format}.js` 11 | }, 12 | rollupOptions: { 13 | external: ['react'], 14 | output: { 15 | globals: { 16 | react: 'React' 17 | } 18 | } 19 | } 20 | } 21 | }) 22 | --------------------------------------------------------------------------------