├── .development.env ├── client ├── assets │ ├── robots.txt │ └── favicon.ico ├── environment │ ├── .env │ └── README.md ├── global.css ├── views │ ├── About.jsx │ ├── Home.test.js │ ├── About.test.js │ └── Home.jsx ├── components │ ├── Footer │ │ ├── Footer.jsx │ │ └── Footer.test.js │ ├── Header │ │ ├── Header.jsx │ │ └── Header.test.js │ └── Loader │ │ ├── Loader.jsx │ │ ├── Loader.test.js │ │ └── Loader.css ├── index.jsx ├── index.html └── app.jsx ├── .gitignore ├── .dockerignore ├── postcss.config.js ├── server ├── index.js ├── __tests__ │ └── demo.js └── app.js ├── jest.config.js ├── tailwind.config.js ├── babel.config.js ├── .eslintrc.js ├── vite.config.js ├── Dockerfile ├── .github └── workflows │ ├── docker.yml │ └── test.yml ├── README.md └── package.json /.development.env: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/assets/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | allow: / 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | .DS_Store 4 | .production.env 5 | -------------------------------------------------------------------------------- /client/environment/.env: -------------------------------------------------------------------------------- 1 | VITE_CLIENT_API_KEY='this_is_some_key_that_is_not_secret' 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .git 3 | .development.env 4 | Dockerfile 5 | README.md 6 | .gitignore 7 | -------------------------------------------------------------------------------- /client/global.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | @tailwind variants; 5 | -------------------------------------------------------------------------------- /client/environment/README.md: -------------------------------------------------------------------------------- 1 | # Environment 2 | 3 | Your client-side, non-secret environment files go in here. 4 | -------------------------------------------------------------------------------- /client/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harrisoncramer/fullstack-template/HEAD/client/assets/favicon.ico -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | const app = require("./app"); 2 | 3 | app.listen(process.env.PORT, () => { 4 | console.log(`API listening on port ${process.env.PORT}.`); 5 | }); 6 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | verbose: true, 3 | moduleNameMapper: { '\\.(css|scss|sass)$': 'identity-obj-proxy' }, 4 | }; 5 | 6 | module.exports = config; 7 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: ["./client/index.html", "./client/**/*.{vue,js,ts,jsx,tsx}"], 3 | theme: { 4 | extend: {}, 5 | }, 6 | plugins: [], 7 | }; 8 | -------------------------------------------------------------------------------- /client/views/About.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const About = () => { 4 | return ( 5 | <> 6 |
About page
7 | 8 | ); 9 | }; 10 | 11 | export default About; 12 | -------------------------------------------------------------------------------- /client/components/Footer/Footer.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Footer = () => { 4 | return ( 5 | <> 6 |
This is the footer
7 | 8 | ); 9 | }; 10 | 11 | export default Footer; 12 | -------------------------------------------------------------------------------- /client/components/Header/Header.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Header = () => { 4 | return ( 5 | <> 6 |
This is the header
7 | 8 | ); 9 | }; 10 | 11 | export default Header; 12 | -------------------------------------------------------------------------------- /client/index.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { BrowserRouter } from "react-router-dom"; 3 | import { render } from "react-dom"; 4 | import App from "./app.jsx"; 5 | 6 | render( 7 | 8 | 9 | , 10 | document.getElementById("root") 11 | ); 12 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: ["babel-plugin-transform-vite-meta-env"], 3 | presets: [ 4 | [ 5 | "@babel/preset-env", 6 | { 7 | targets: { 8 | node: "current", 9 | }, 10 | }, 11 | ], 12 | "@babel/preset-react", 13 | ], 14 | }; 15 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | node: true, 6 | jest: true, 7 | }, 8 | extends: ['eslint:recommended', 'plugin:react/recommended'], 9 | parserOptions: { 10 | ecmaFeatures: { 11 | jsx: true, 12 | }, 13 | ecmaVersion: 12, 14 | sourceType: 'module', 15 | }, 16 | plugins: ['react'], 17 | rules: {}, 18 | }; 19 | -------------------------------------------------------------------------------- /client/views/Home.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | 5 | import '@testing-library/jest-dom'; 6 | import React from 'react'; 7 | import { screen, render } from '@testing-library/react'; 8 | import Home from './Home'; 9 | 10 | test('Renders home view', () => { 11 | render(); 12 | const home = screen.getByText(/Home page/i); 13 | expect(home).toBeInTheDocument(); 14 | }); 15 | -------------------------------------------------------------------------------- /server/__tests__/demo.js: -------------------------------------------------------------------------------- 1 | const request = require('supertest'); 2 | const express = require('express'); 3 | 4 | const app = require('../app'); 5 | 6 | describe('Should test the dummy route', () => { 7 | it('Should recieve the response string', async () => { 8 | const response = await request(app).get('/api/v1'); 9 | expect(response.body).toMatchObject({ hello: 'world' }); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /client/views/About.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | 5 | import '@testing-library/jest-dom'; 6 | import React from 'react'; 7 | import { screen, render } from '@testing-library/react'; 8 | import About from './About'; 9 | 10 | test('Renders about view', () => { 11 | render(); 12 | const about = screen.getByText(/About page/i); 13 | expect(about).toBeInTheDocument(); 14 | }); 15 | -------------------------------------------------------------------------------- /client/components/Footer/Footer.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | 5 | import '@testing-library/jest-dom'; 6 | import React from 'react'; 7 | import { screen, render } from '@testing-library/react'; 8 | import Footer from './Footer'; 9 | 10 | test('Renders footer', () => { 11 | render(