GithubHelp home page GithubHelp logo

async-labs / builderbook Goto Github PK

View Code? Open in Web Editor NEW
3.7K 96.0 881.0 6.28 MB

Open source web application to learn JS stack: React, Material-UI, Next.js, Node.js, Express.js, Mongoose, MongoDB database.

Home Page: https://builderbook.org

License: MIT License

JavaScript 99.42% CSS 0.58%
aws-ses express-session github-api material-ui mongoose passport react mongodb javascript nodejs

builderbook's Introduction

image

Support Ukraine: link

Builder Book

Open source web app to self-publish and sell books or other online content.

If you want to learn how to build this project from scratch, check out our book: https://builderbook.org.

The open source project is located in the builderbook folder. If you purchased our book, codebases for each of the book's chapters are located in the book folder.

We've used this builderbook project to build:

  • Builder Book - learn how to build full-stack web apps from scratch
  • SaaS Boilerplate - open source web app to build your own SaaS product
  • Work in biotech - job board for biotech startup companies
  • AI-cruiter - browser extension is built for recruiters managing a high volume of job applicants. AI-cruiter uses LLMs - like ChatGPT and PaLM 2 - to generate succinct and relevant summaries of your job applicants' resumes
  • Async - open source urgent vs non-urgent team communication tool for small teams
  • Async Labs - many custom dev projects

Live app:

https://builderbook.org/books/builder-book/introduction

Sponsors

aws-activate-logo

1password-logo

Showcase

Check out projects built with the help of this open source app. Feel free to add your own project by creating a pull request.

  • Retaino by Earl Lee: Save, annotate, review, and share great web content. Receive smart email digests to retain key information.
  • michaelstromer.nyc by Michael Stromer: Books and articles by Michael Stromer.
  • SaaS Boilerplate: Open source web app to build your own SaaS product.
  • Work in biotech: Job board for small and young biotech companies
  • Async: Open source web app for team communication, separate urgent vs. non-urgent conversations.
  • Async Labs: We build custom SaaS web applications.

Contents

What can I learn from this project?

You will learn how to structure your project and build many internal and external API infrastructures.

On the browser, the main technologies you will learn are: Next.js, React.js, Material-UI. On the server, the main technologies you will learn are: Next.js, Node.js, Express.js, Mongoose.js, MongoDB database.

In addition to the above technologies, you can learn how to integrate your web application with the following external API services:

Plus, you can learn many concepts such as session and cookie, headers, HTTP request-response, Express middleware, Promise, async/await, and more. You have to know these concepts to be a confident web developer, no matter what language you use.

The main use cases for this project, besides learning, are:

  • To write and host free documentation with Github being a source of truth for content.
  • To sell online content, such as books.
  • To extend it (see our second book, SaaS Boilerplate Book) to start software business.

Creating a Google OAuth Client

This guide will walk you through the steps to create a Google OAuth client for your application.

Prerequisites

Before you begin, make sure you have the following:

  1. Sign in to Google Cloud Console:
  • Go to the Google Cloud Console.
  • Sign in with your Google account or create one if you don't have it.
  1. Create a New Project:
  • Click on the project dropdown in the top navigation bar.
  • Click on "New Project."
  • Give your project a name and click "Create."
  1. Enable the Google+ API (if required):
  • If you plan to use Google+ Sign-In for authentication, enable the "Google+ API" for your project.
  • In the Cloud Console, go to the API & Services > Library.
  • Search for "Google+ API" and enable it.
  1. Create OAuth Client ID:
  • In the Cloud Console, navigate to the API & Services > Credentials page.
  • Click on "Create Credentials" and then select "OAuth client ID."
  • Select the application type, typically "Web application" for a website or web application.
  • Fill out the necessary information, such as the name of the OAuth client and authorized redirect URIs (where Google should redirect the user after authentication). You can use http://localhost as a redirect URI for development.
  • Click "Create" to generate your OAuth client credentials. It will provide you with a client ID and client secret.

Creating a GitHub Client ID and Client Secret

To create a GitHub Client ID and Client Secret, follow these steps:

  1. Sign in to your GitHub Account: If you don't have a GitHub account, create one.

  2. Go to Developer Settings: Click on your profile picture in the top right corner of GitHub and select "Settings." In the left sidebar, under "Developer settings," click on "OAuth Apps."

  3. Create a New OAuth App: Click on the "Register a new application" button.

  4. Fill in the Application Details: You'll be prompted to fill in details about your application:

    • Application Name: The name of your application.
    • Homepage URL: The URL to your application's website.
    • Application Description: A brief description of your application.
    • Authorization callback URL: This is the URL to which GitHub will redirect users after they authorize your application. For testing purposes, you can use http://localhost if you're developing locally.
  5. Generate Your Client ID and Client Secret: After you've filled in the details, click the "Register application" button. GitHub will generate a Client ID and Client Secret for your application.

Run locally

  • Clone the project and run yarn to add packages.

  • Before you start the app, create a .env file at the app's root. This file must have values for some env variables specified below.

  • To use all features and third-party integrations (such as Stripe, Google OAuth, Mailchimp), create a .env file and add values for all variables as shown below. These variables are also listed in .env.example, which you can use as a template to create your own .env file.

.env :

# Used in server/server.js
MONGO_URL=
MONGO_URL_TEST=
SESSION_SECRET=

# Used in lib/getRootUrl.js
NEXT_PUBLIC_URL_APP=
NEXT_PUBLIC_PRODUCTION_URL_APP="https://heroku.builderbook.org"

# Used in server/google.js
GOOGLE_CLIENTID=
GOOGLE_CLIENTSECRET=

# Used in server/aws.js
AWS_ACCESSKEYID=
AWS_SECRETACCESSKEY=
AWS_REGION=

# Used in server/models/User.js
EMAIL_ADDRESS_FROM=

----------
# All environmental variables above this line are required for successful sign up

# Used in server/github.js
GITHUB_TEST_CLIENTID=
GITHUB_LIVE_CLIENTID=
GITHUB_TEST_SECRETKEY=
GITHUB_LIVE_SECRETKEY=

# Used in server/stripe.js
NEXT_PUBLIC_STRIPE_TEST_PUBLISHABLEKEY=
NEXT_PUBLIC_STRIPE_LIVE_PUBLISHABLEKEY=
STRIPE_TEST_SECRETKEY=
STRIPE_LIVE_SECRETKEY=
STRIPE_TEST_DEMO_BOOK_PRICE_ID=
STRIPE_LIVE_DEMO_BOOK_PRICE_ID=
STRIPE_TEST_SECOND_BOOK_PRICE_ID=
STRIPE_LIVE_SECOND_BOOK_PRICE_ID=

# Used in server/mailchimp.js
MAILCHIMP_API_KEY=
MAILCHIMP_REGION=
MAILCHIMP_PURCHASED_LIST_ID=
MAILCHIMP_SIGNEDUP_LIST_ID=

# Used in pages/_document.js and pages/_app.js
NEXT_PUBLIC_GA_MEASUREMENT_ID=
COOKIE_DOMAIN=".builderbook.org"

  • IMPORTANT: do not publish your actual values for environmentable variables in .env.example; this file is public and only meant to show you how your .env file should look.

  • Add your value (domain that you own) for COOKIE_DOMAIN and NEXT_PUBLIC_PRODUCTION_URL_APP.

  • Start the app with yarn dev.

    • To get NEXT_PUBLIC_GA_MEASUREMENT_ID, set up Google Analytics and follow these instructions to find your tracking ID.
    • To get Stripe-related API keys, set up or log into your Stripe account and find your key here.
  • Env keys NEXT_PUBLIC_GA_MEASUREMENT_ID and NEXT_PUBLIC_STRIPE_TEST_PUBLISHABLEKEY/NEXT_PUBLIC_STRIPE_LIVE_PUBLISHABLEKEY are universally available (client and server). Env keys inside .env file are used in server code only unless they have NEXT_PUBLIC_ prepended to their name. In that case, they are universally available.

  • To make user a book's owner, set "isAdmin": true on corresponding MongoDB document in your database (default value is false for any new user).

Important: if you don't add values for environmental variables to .env file, corresponding functionality will not work. For example, login with Google account, purchasing book, getting repo information via GitHub API and other third-party API infrastructures.

Add a new book

  • Create a new Github repo (public or private).

  • In that repo, create an introduction.md file and write some content.

  • At the top of your introduction.md file, add metadata in the format shown below. See this file as an example.

    ---
    title: Introduction
    seoTitle: title for search engines
    seoDescription: description for search engines
    isFree: true
    ---
    
  • Go to the app, click "Connect Github".

  • Click "Add Book". Enter details and select the Github repo you created.

  • Click "Save".

When you add new .md files or update content, go to the BookDetail page of your app and click Sync with Github.

Important: All .md files in your Github repo must have metadata in the format shown above.

Important: All .md files in your Github repo must have name introduction.md or chapter-N.md.

To make the content of a .md file private (meaning a person must purchase the content to see it), remove isFree:true and add excerpt:"". Add some excerpt content - this content is public and serves as a free preview.

Add your own styles

To change the color scheme of this app, modify the primary and secondary theme colors inside lib/context.js. Select any colors from Material UI's official color palette.

Recommended ways to add your own styles to this app:

  1. Inline style for a single element
  2. Reusable style for multiple elements within single page or component
  3. Reusable/importable style for multiple pages or components
  4. Global style for all pages in application

Inline style for a single element

USE CASE: apply a style to one element on a single page/component
For example, in our book page, we wrote this single inline style:

<p style={{ textAlign: 'center' }}>
  ...
</p>

See usage

Reusable style for multiple elements within single page or component

USE CASE: apply the same style to multiple elements on a single page/component.
For example, in our tutorials page, we created styleExcerpt and applied it to a <p> element within the page:

const styleExcerpt = {
  margin: '0px 20px',
  opacity: '0.75',
  fontSize: '13px',
};

<p style={styleExcerpt}>
  ...
</p>

See usage

Reusable/importable style for multiple pages or components

USE CASE: apply the same style to elements on multiple pages/components.
For example, we created styleH1 inside components/SharedStyles.js and exported the style at the bottom of the file:

const styleH1 = {
  textAlign: 'center',
  fontWeight: '400',
  lineHeight: '45px',
};

module.exports = {
  styleH1,
};

See usage

We then imported styleH1 into our book page, as well as our index page, and applied the style to a <h1> element:

import {
  styleH1,
} from '../components/SharedStyles';

<h1 style={styleH1}>
  ...
</h1>

See usage

Global style for all pages in application

USE CASE: apply the same style to elements on all pages of your app.
Create your style in pages/_document.js. For example, we specified a style for all hyperlinks that use the <a> element:

<style>
  {`
    a, a:focus {
      font-weight: 400;
      color: #1565C0;
      text-decoration: none;
      outline: none
    }
  `}
</style>

See usage

Deploy to Heroku

In this section, we will learn how to deploy our app to Heroku cloud. We will deploy our React-Next-Express app to lightweight Heroku container called dyno.

Instructions are for app located at /book/8-end. Adjust route if you are deploying app from the root of this public repo.

We will discuss the following topics in this section:

  1. installing Heroku on Linux-based OS
  2. creating app on Heroku dashboard
  3. preparing app for deployment
  4. configuring env variables
  5. deploying app
  6. checking logs
  7. adding custom domain

Let's go step by step.

  1. Install Heroku CLI (command-line interface) on your OS. Follow the official guide. In this book we provide instructions for Linux-based systems, in particular, a Ubuntu OS. For Ubuntu OS, run in your terminal:
sudo snap install --classic heroku

To confirm a successful installation, run:

heroku --version

As example, my output that confirms successful installation, looks like:

heroku/7.22.7 linux-x64 node-v11.10.1
  1. Sign up for Heroku, go to your Heroku dashboard and click purple New button on the right:

    image

    On the next screen, give a name to your app and select a region. Click purple Create app button at the bottom:

    image

    You will be redirected to Deploy tab of your newly created Heroku app:

    image

  2. As you can see from the above screenshot, you have two options. You can deploy the app directly from your local machine using Heroku CLI or directly from GitHub. In this tutorial, we will deploy a async-labs/builderbook/book/8-end app from our public async-labs/builderbook repo hosted on GitHub. Deploying from a private repo will be a similar process.

    Deploying from GitHub has a few advantages. Heroku uses git to track changes in a codebase. It's possible to deploy app from the local machine using Heroku CLI, however you have to create a Git repo for async-labs/builderbook/book/8-end with package.json file at the root level. A first advantage is that we can deploy from a non-root folder using GitHub instead of Heroku CLI.

    A second advantage is automation, later on you can create a branch that automatically deploy every new commit to Heroku. For example, we have a deploy branch for our demo for SaaS boilerplate. When we commit to master branch - there is no new deployment, when we commit to deploy branch - new change is automatically deployed to Heroku app.

    Let's set up deploying from GitHub. On Deploy tab of your Heroku app at Heroku dashboard, click Connect to GitHub, then search for your repo, then click Connect next to the name of the proper repo:

    image

    If successful, you will see green text Connected and be offered to select a branch and deploy app automatically or manually. Automatic deployment will deploy every new commit, manual deployment requires you to manually click on Deploy Branch button. For simplicity, we will deploy manually from master branch of our async-labs/builderbook repo.

    Before we perform a manual deployment via GitHub, we need Heroku to run some additional code while app is being deploying. Firstly, we need to tell Heroku that 8-end app in the async-labs/builderbook repo is not at the root level, it's actually nested at /book/8-end. Secondly, Heroku needs to know that our app is Node.js app so Heroku finds package.json file, properly installs dependencies and runs proper scripts (such as build and start scripts from package.json). To achieve this, we need to add so called buildpacks to our Heroku app. Click Settings tab, scroll to Buildpacks section and click purple Add buildpack button:

    image

    Add two buildpacks, first is https://github.com/timanovsky/subdir-heroku-buildpack and second is heroku/nodejs:

    image

    Next, scroll up while on Settings tab and click purple Reveal Config Vars button, create a new environmental variable PROJECT_PATH with value book/8-end:

    image

    The above variable will be used by the first buildpack subdir-heroku-buildpack to deploy app from repo's subdirectory.

  3. If we deploy app at this point, our app will deploy with errors since we did not add environmental variables. Similar to how you added PROJECT_PATH variable, add all environmental variables from book/8-end/.env file to your Heroku app. Remember to add the rest of env variables for all features to work, including signup event.

  4. While on Settings tab, scroll to Domains and certificates section and note your app's URL. My app's URL is: https://builderbook-8-end.herokuapp.com Let's deploy, go to Deploy tab, scroll to Manual deploy section and click Deploy branch button. After deployment process is complete , navigate to your app's URL:

    image

  5. Server logs are not available on Heroku dashboard. To see logs, you have to use Heroku CLI. In your terminal, run:

    heroku login

    Follow instructions to log in to Heroku CLI.

    After successful login, terminal will print:

    Logged in as [email protected]

    Where [email protected] is an email address that you used to create your Heroku account.

    To see logs, in your terminal run:

    heroku logs --app builderbook-8-end --tail

    In your terminal, you will see your most recent logs and be able to see a real-time logs.

    You can output certain number of lines (N) for retrieved logs by adding --num N to the heroku logs command. You can print only app's logs by adding --source app or system's logs by adding --source heroku.

  6. Time to add a custom domain. The Heroku app that we created is deployed on free dyno. Free dyno plan does not let you to add a custom domain to your app. To add custom domain, go to Resources tab and click purple Change Dyno Type button:

    image

    Select a Hobby plan and click Save button.

    Navigate to Settings tab and scroll to the Domains and certificates and click purple Add domain button:

    image

    Type your custom domain name, I added heroku.builderbook.org as a custom domain, click Save changes button.

    Heroku will display you a value for CNAME record that you have to create for your custom domain. For me, custom domain is heroku.builderbook.org and I manage DNS records at Now by Zeit.

    After you create a CNAME, ACM status on Heroku's dashboard will change to Ok:

    image

It's important that you remember to manually add your custom domain to the settings of your Google OAuth app (Chapter 3) and GitHub OAuth app (Chapter 6). If you forget to do it, you will see errors when you try to log in to your app or when you try to connect GitHub to your app.

Scaling

You may want to consider splitting single Next/Express server into two servers:

  • Next server for serving pages, server-side caching, sitemap and robots
  • Express server for internal and external APIs

Here is an example of a web application with split servers: https://github.com/async-labs/saas

Splitting servers will get you:

  • faster page loads since Next rendering does not block internal and external APIs,
  • faster code reload times during development,
  • faster deployment and more flexible scaling of individual apps.

Docker

Screenshots

Chapter excerpt with Buy Button for Public/Guest visitor:

builderbook-public-readchapter

Chapter content and Table of Contents for book Customer:

builderbook-customer-readchapter

Add-book/Edit-book page for Admin user:

builderbook-admin-editbook

Book-detail page for Admin user:

builderbook-admin-bookdetails

Built with

Core stack

Third party APIs

  • Google OAuth
  • Github
  • AWS SES
  • Stripe
  • MailChimp

Check out package.json.

Contributing

We welcome suggestions and bug reports via issues and and pull requests.

By participating in this project, you are expected to uphold Builder Book's Code of Conduct.

Want to support this project? Consider buying our books, which teach you how to build web apps from scratch. Also check out our open source SaaS boilerplate.

Team

You can contact us at [email protected]

If you are interested in working with us, check out Async Labs.

License

All code in this repository is provided under the MIT License.

Project structure

.
โ”œโ”€โ”€ .vscode
โ”‚   โ”œโ”€โ”€ extensions.json
โ”‚   โ”œโ”€โ”€ settings.json
โ”œโ”€โ”€ book
โ”œโ”€โ”€ builderbook
โ”‚   โ”œโ”€โ”€ .elasticbeanstalk
โ”‚   โ”‚   โ”œโ”€โ”€ config.yml
โ”‚   โ”œโ”€โ”€ components
โ”‚   โ”‚   โ”œโ”€โ”€ admin
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ EditBook.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ customer
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ BuyButton.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ Header.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ MenuWithAvatar.jsx                   
โ”‚   โ”‚   โ”œโ”€โ”€ Notifier.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ SharedStyles.js
โ”œโ”€โ”€ lib
โ”‚   โ”œโ”€โ”€ api
โ”‚   โ”‚   โ”œโ”€โ”€ admin.js
โ”‚   โ”‚   โ”œโ”€โ”€ customer.js
โ”‚   โ”‚   โ”œโ”€โ”€ getRootURL.js
โ”‚   โ”‚   โ”œโ”€โ”€ public.js
โ”‚   โ”‚   โ”œโ”€โ”€ sendRequest.js
โ”‚   โ”œโ”€โ”€ notify.js
โ”‚   โ”œโ”€โ”€ theme.js
โ”‚   โ”œโ”€โ”€ withAuth.jsx
โ”œโ”€โ”€ pages
โ”‚   โ”œโ”€โ”€ admin
โ”‚   โ”‚   โ”œโ”€โ”€ add-book.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ book-detail.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ edit-book.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ index.jsx
โ”‚   โ”œโ”€โ”€ customer
โ”‚   โ”‚   โ”œโ”€โ”€ my-books.jsx
โ”‚   โ”œโ”€โ”€ public
โ”‚   โ”‚   โ”œโ”€โ”€ login.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ read-chapter.jsx
โ”‚   โ”œโ”€โ”€ _app.jsx
โ”‚   โ”œโ”€โ”€ _document.jsx
โ”‚   โ”œโ”€โ”€ index.jsx
โ”œโ”€โ”€ public
โ”‚   โ”œโ”€โ”€ robots.txt
โ”œโ”€โ”€ server
โ”‚   โ”œโ”€โ”€ api
โ”‚   โ”‚   โ”œโ”€โ”€ admin.js
โ”‚   โ”‚   โ”œโ”€โ”€ customer.js
โ”‚   โ”‚   โ”œโ”€โ”€ index.js
โ”‚   โ”‚   โ”œโ”€โ”€ public.js
โ”‚   โ”œโ”€โ”€ models
โ”‚   โ”‚   โ”œโ”€โ”€ Book.js
โ”‚   โ”‚   โ”œโ”€โ”€ Chapter.js
โ”‚   โ”‚   โ”œโ”€โ”€ EmailTemplate.js
โ”‚   โ”‚   โ”œโ”€โ”€ Purchase.js
โ”‚   โ”‚   โ”œโ”€โ”€ User.js
โ”‚   โ”œโ”€โ”€ utils
โ”‚   โ”‚   โ”œโ”€โ”€slugify.js
โ”‚   โ”œโ”€โ”€ app.js
โ”‚   โ”œโ”€โ”€ aws.js
โ”‚   โ”œโ”€โ”€ github.js
โ”‚   โ”œโ”€โ”€ google.js
โ”‚   โ”œโ”€โ”€ logger.js
โ”‚   โ”œโ”€โ”€ mailchimp.js
โ”‚   โ”œโ”€โ”€ routesWithSlug.js
โ”‚   โ”œโ”€โ”€ sitemapAndRobots.js
โ”‚   โ”œโ”€โ”€ stripe.js
โ”œโ”€โ”€ test/server/utils
โ”‚   โ”œโ”€โ”€ slugify.test.js
โ”œโ”€โ”€ .eslintrc.js
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ yarn.lock

builderbook's People

Contributors

amirkx avatar athahersirnaik avatar batamar avatar delgermurun avatar greysdawn avatar helpse avatar jessebrack avatar johnking avatar johnmalcolm avatar klyburke avatar mohammadameer avatar nguyenda18 avatar paralax avatar rickhallett avatar tima101 avatar waterlesspiano2 avatar yurigor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

builderbook's Issues

when adding a new book, sync with Github on save event

When you add a new book and click the Save button on the /admin/add-book page - sync the book with its Github repo and redirect to the /admin/book-detail page.

This way the admin does not need to click Sync with Github for book creation, only for book updates.

Add data to main admin page

Decide which data to move to pages/admin/index.js
Decide if need pages/admin/book-detail.js

Data:

  • book details, sync button, edit button
  • book sales stats: sold count and free book count

Deploying with babel-node

Hi Kelly and Timur,

Question about the user of babel-node to start the server on Now. I was reading the babel docs which states the babel-node should not be used in production (link). What's the benefit of doing so in Chapter 8? Is it just to make the deploy process easier? What would the alternative be?

Btw, just finished the final chapter. Good stuff, thank you!

editable text next to Buy Button

Create a new entry field on the add-book.js and edit-book.js pages so that an Admin user can add text next to the Buy Button for a book. For example, the text could be "On sale" or "Pre-order ends on Friday", etc.

close TOC on mobile

On mobile, when a user clicks any link in the Table of Contents (in sidebar of the read-chapter page) - the TOC should close, and the user should see the content of the section clicked

SubscribeForm component

Use SubscribeForm component to let readers subscribe to newsletters

Add Tutorial model and tutorials page

TOC highlight disappears past h4 heading

When you scroll past content under an

heading, the current section (which is under

heading) on the TOC becomes un-highlighted.

We want the section to remain highlighted when reading any content within that section.

Chapter 7: returnSidebar and returnSection

In the beginning of chapter 7, the book goes over how to build the returnSection() function. However, that function is already built in 7-start. Furthermore, the book begins discussing how to build returnSidebar. However, 7-start already has code for returnSidebar() that appears to be fully built out. This makes it very confusing to follow, since I'm not sure what code I should be writing.

add `noPrefetch` prop to `MenuDrop` component

Set prefetch to false for the /logout route in the MenuDrop component

Otherwise, we get a browser console error like this:
GET https://demo.builderbook.org/_next/c3fa3d01-d44e-4ae4-88c9-0f836d00d8c2/page/logout.js net::ERR_ABORTED

Missing Avatar and headersAlreadySent error w/3-end and 4-start

After copying my .env into book/4-start and running yarn then yarn dev, I get the following error after logging in with Google:

    at SendStream.headersAlreadySent (/Users/earl/dev/builderbook/book/4-start/node_modules/send/index.js:390:13)
    at SendStream.send (/Users/earl/dev/builderbook/book/4-start/node_modules/send/index.js:618:10)
    at onstat (/Users/earl/dev/builderbook/book/4-start/node_modules/send/index.js:730:10)
    at FSReqWrap.oncomplete (fs.js:171:5) expose: false, statusCode: 500, status: 500 }

Furthermore, the app looks like this when logged in:

image

The user I am logged in with does have an avatar.

Failed to load css file from module

Hi,

Im trying to add 'react-big-calendar' to your boilerplate project, but getting the following error:

Module parse failed: C:\source\repos\KvutzatYavne\node_modules\react-big-calendar\lib\css\react-big-calendar.css Unexpected token (1:0) You may need an appropriate loader to handle this file type. | .rbc-btn { | color: inherit; | font: inherit;

maybe adding webpack will solve this issue

Example with relational database

This is just a suggestion, but it would be nice to have an example of how Builder Book can be made with a relational database like SQL instead of using MongoDB, Mongoose, etc.

UI improvements

  • decrease font weight of header tags
  • change colors of section names in table of contents
  • add chapter order, in addition to chapter title, in title tag

Fix logic on bookmark

Instead of requiring the user to select a chapter section to create a bookmark, let's have the user bookmark the section he/she is currently reading

  • when a user is within a chapter section, the bookmark button should say Bookmark "section"
  • after creating a bookmark in a chapter, the button should have options to Go to "section" or Bookmark "current section"

remove sanitize-html

@tima101 sanitize-html causes issues with displaying some content in books. Since users will write all code in books (and will not add anything unsafe), we can remove sanitize-html.

Can't set headers after they are sent.

Below error is not always reproducible and not crucial (app runs):

most recent: vercel/next.js@7b2cd84#diff-bec864430eb5752a683c8798d0c6bd6c
old: vercel/next.js@c210a2e

vercel/next.js#2152
vercel/next.js#3778

{ Error: Can't set headers after they are sent.
    at SendStream.headersAlreadySent (/home/tima/apps/builderbook/book/4-end/node_modules/send/index.js:390:13)
    at SendStream.send (/home/tima/apps/builderbook/book/4-end/node_modules/send/index.js:618:10)
    at onstat (/home/tima/apps/builderbook/book/4-end/node_modules/send/index.js:730:10)
    at FSReqWrap.oncomplete (fs.js:153:5) expose: false, statusCode: 500, status: 500 }

add boilerplate app

Boilerplate app should have:

  • React, Next.js, Material-UI
  • Express, Express Session
  • connected to MongoDB with Mongoose
  • Google OAuth 2.0

Add title to pages

please add title to AddBook and EditBook pages using Head from next/head

no need for description since pages are not indexed

Snapshots of important pages

Add snapshots to readme:

  • Public user on read-chapter.js page,
  • Customer user on read-chapter.js page,
  • Admin user add-book.js page,
  • Admin user book-detail.js page

What else?

Add google and github callback's to Readme

We could add the following info to the README, in order to configure Google and Github apps:

Google auth callback:
[host]/oauth2callback

Github auth callback:
[host]/auth/github/callback

move marked.Renderer from page to server

Instead of running marked on every page load, let's save html content to DB in addition to markdown content

  • markdown content is used to compare content between database and Github
  • html content is used for data on the page

improve demo

create intro chapter to show scrolling and TOC in action

Example with TypeScript

This is just a suggestion, but it would be nice to have an example of how one could use TypeScript instead of PropTypes and Babel for Builder Book given the rising popularity of and support for TypeScript.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.