Welcome to the WDB Application Portal demo repository! Our goal with this project was to create an application portal that would automatically save student applications and allow students to conveniently apply to multiple different Berkeley clubs on the same website. This app was built with Convex and showcases some of the platform's most valuable functionality, including real-time data sync and easy to use backend logic.
There's a live version of the site at https://convex-application-portal.vercel.app! This version has checks for admin access disabled so anyone can access the admin portal. See here for instructions on how to re-enable the proper security logic for a real-world app.
Here's a quick clip of the real-time sync in action:
Application.Portal.Demo.mp4
If you you're looking to run this app locally, here's how to get started with development:
- Make sure you have Node.js installed.
- Clone the repository by running
git clone <your repository link>
in your terminal. - Check if you have Yarn installed by running
yarn -v
in your terminal. If you don't have it installed, runnpm install -g yarn
. - In the project directory, run
yarn
to install dependencies. - Delete the existing
convex.json
file so that you'll be able to use your own Convex deployment. - Run
npx convex dev
to run the Convex backend in development mode. The first time you run this command, you'll be prompted to create a free Convex account and project - you can follow the prompts to get this set up. - Follow the steps here to get Auth0 set up with your own developer account, up until (and including) running
npx convex auth add
to add your Auth0 credentials to your Convex project. - While Convex is running in development mode, run
yarn dev
at the same time to start the Next.js development server. - Navigate to
localhost:3000
in your browser to see the app running! - You'll need to seed the
applications
table with an application to use the other pages on the site. Navigate tolocalhost:3000/seed
and click on the button to seed the database with an example WDB application. Then, update theDEMO_APPLICATION_ID
variable insrc/pages/index.ts
to match the ID of the application you just created. - That's it - you're ready to start developing!
Here's a list of scripts defined in package.json
which can be run with yarn <script>
:
yarn dev
- starts the development serveryarn build
- builds the project for productionyarn start
- starts the production serveryarn lint
- runs ESLint and Prettier while also fixing any issues wherever possibleyarn lint-ci
- runs ESLint and Prettier without fixing issues (used by GitHub Actions)yarn depcheck
- checks for unused dependencies (used by GitHub Actions)yarn clean
- deletes any files which are.gitignore
'd but still exist in the project (includingnode_modules
) - useful if you want to reset the project to a clean state or if you're having issues with dependencies. Keep in mind this will delete environment files like.env.local
as well though, so back them up if needed.
Below is an excerpt from the WDB Next.js template README that explains the structure of the rest of project and some the technologies we're using.
Next.js is used as the frontend framework since it's currently the de facto standard for writing React and has a ton of great features for making development easier. Here's the structure for Next.js-related files (most frontend development will be done here):
src/pages
- contains all of the pages for the sitesrc/components
- contains all of the components for the site; should be organized by page and/or use case (e.g.src/components/utils
)src/utils
- contains utility functions and types which aren't React-specificpublic
- contains static files which are served by the server (e.g. images, favicons, etc.)- images should be in
public/images
and ideally organized into folders
- images should be in
Yarn is used as the package manager since it's generally faster than NPM due to its caching mechanisms. It also works better with monorepos, and even though this isn't a monorepo it's useful to be consistent with the monorepo template. NPM commands that install packages should fail to avoid conflicting with Yarn (configured in .npmrc
). Here's the list of commands to use instead:
yarn
(replacesnpm install
) - install all dependenciesyarn add <package>
(replacesnpm install <package>
- install a packageyarn remove <package>
(replacesnpm uninstall <package>
) - remove a packageyarn <script>
(replacesnpm run <script>
) - run a script defined inpackage.json
(the NPM script still works in this case)
TypeScript is used over JavaScript as it makes catching type-related bugs much easier. Although it can occasionally get in the way via cryptic errors, TypeScript ends up saving a ton of time in the long run and should almost always be used for any web development project. You shouldn't need to write manual type annotations too often due to type inference, but they should always be included when components have props (see the SkeletonAvatarProps
interface in src/components/SkeletonAvatar.tsx
for an example). The project's TypeScript settings are defined in tsconfig.json
.
Chakra UI is WDB's UI library of choice. It's a great library that makes styling and implementing design systems really easy. Chakra is pretty customizable and even directly writing CSS is possible via an escape hatch, so ideally all styling should be done through Chakra (i.e. no need to create CSS files). The project theme is defined in src/utils/theme.ts
and should be edited to fit the project. Chakra also includes a ton of icons through the @chakra-ui/icons
package, so it's a good idea to use icons from there where possible since their designs are consistent with Chakra's components.
This is a drop-in progress bar component from the nextjs-progressbar
package that's used to show the user that the page is loading when they click on links. It's completely optional and more of a stylistic/UX choice, so feel free to remove it. The progress bar is used in src/pages/_app.tsx
via the NextNProgress
component.
The error boundary component from the react-error-boundary
package is used to catch errors in the React component tree and display a modal with the error message. Including this avoids the entire page from going blank when there's an error in the website. The error boundary is used in src/pages/_app.tsx
via the ErrorBoundary
component. The contents of the modal can be edited to fit the project if needed.
The template also includes various utility React components in src/components/utils
which should be useful for most projects. Feel free to remove any that aren't needed. Here's the list:
- Link components - these should almost always be used over the
Link
components from Next.js or Chakra UI:NextLink
combines Chakra Link and Next Link into a single component which allows styling links with Chakra while also using the Next routerPlainLink
does the same except it has no styling/underline on hover, which is useful for navbars and other links that don't need to look like linksButtonLink
combines Chakra Button and Next Link into a single component and is useful for any place where buttons are used as links
Responsive
,DesktopOnly
, andMobileOnly
are all useful for responsive designSkeletonAvatar
is a useful component for displaying a placeholder skeleton while e.g. profile pictures are loading
Prettier is used to format the code. It's configured in .prettierrc
(everything is set to default).
https://eslint.org/ is used to lint the code, meaning it automatically checks for logic and stylistic errors. It's configured in .eslintrc.js
. The settings are highly opinionated so feel free to change them, but I've included most rules in there for a reason - in the long run, linting avoids bugs and makes sure code is consistent even when it's written by a bunch of people. Linting errors can sometimes be pretty annoying to fix though, so I've tried to make it as painless as possible by setting up ESLint to automatically fix issues whenever you save a file in VS Code and right before you commit. Some errors can also be fixed in VS Code by hovering over the error and selecting "Quick Fix". Finally, you can also manually run yarn lint
to check for and fix ESLint issues. With that said, here's some highlights from the list of enabled rules:
- All recommended rules from ESLint itself, the ESLint Import Plugin, TypeScript ESLint, Prettier, and Next.js
- No unreachable code
- Miscellaneous
@typescript-eslint
rules to ensure that code is type-safe - Naming conventions:
camelCase
for variables andPascalCase
for types and components - No commented out code since it should usually only be used during debugging - there are still some cases where it's useful though, so see below for how to disable the rule for specific lines
- Prefer interfaces to
type
for TypeScript type declarations wherever possible, mostly just for consistency - Warnings for
TODO
comments so they're easy to identify in the future - Warnings for
console.log
statements since they usually shouldn't be used other than for debugging
Most of the other rules can just be searched by name and documentation should be available. Only ESLint errors (not warnings) will cause GitHub Actions to fail. As long as you have the ESLint VS Code extension installed, errors should be underlined in red and warnings should be underlined in yellow; the corresponding ESLint rule will show up if you hover over the underlined code.
Rules can be disabled via eslint-disable-next-line
comments, with the added caveat that the specific rule being disabled needs to be included (e.g. // eslint-disable-next-line etc/no-commented-out-code
). This should just be used as an escape hatch though, and it will be highlighted as a warning so that it's easy to identify later.
Husky is used to run scripts before and after Git commands. Here it's just used to fix files with ESLint with yarn lint
before every commit (see .husky/pre-commit
). The commit will still succeed even if there's errors, but those errors still should show up in GitHub Actions.
GitHub Actions is used for CI (continuous integration). Any time code is pushed or a pull request to the main
branch is opened, GitHub Actions will check the project for unused dependencies and errors from ESLint or Prettier. It will also check if the TypeScript types are valid and try to create a production build. If any of these checks fail, the commit/pull request will be marked as failing. The GitHub Actions workflow is defined in .github/workflows/main.yml
. It's recommended to only merge PRs which pass the checks.
Configuration files for for VS Code are inside .vscode
. The settings.json
file sets the default formatter to Prettier and enables automatically linting via ESLint whenever you save files. The extensions.json
file lists the recommended extensions for the project.
.editorconfig
is used by the EditorConfig extension and contains settings which ensure consistent formatting for files, including indentation and newlines..gitattributes
also contains settings for consistent formatting, but is used by Git instead..env
should contain any environment variables used by the project. Since this is included in GitHub, do not put any sensitive information in here (e.g. API keys, etc.) and instead include them in an.env.local
file.