This is the frontend for the Skole app.
Also check out the README from skole
repo.
See detailed description for all top-level dependencies in dependencies.md
file.
Other useful documentation:
A quick look at the top-level files and directories excluding Git ignored locations.
__generated__/
: Generated code by graphql-let..github/
: Configuration for Github Actions..idea/
: Jetbrains editor configuration..vscode/
: VSCode configuration.cypress/
: Cypress tests.locales/
: Contains JSON files with all of the translated UI strings.markdown/
: Markdown content used in static pages.public/
: Static assets exposed in the browser.src/
: Source code..babelrc
: Babel configuration..dockerignore
: List of files ignored by Docker..eslintignore
: List of files ignored by ESLint..eslintrc.json
: ESLint configuration..gitattributes
: Additional Git repo metadata..gitignore
: List of files ignored by Git..graphql-let.yml
: Configuration for graphql-let..graphqlconfig
: GraphQL configuration file, used by e.g. Jetbrains editors..prettierignore
: List of files ignored by Prettier..prettierrc.json
: Prettier configuration.cypress.json
: Cypress configuration.dependencies.md
: Documentation for top-level dependencies.Dockerfile
: Formal instructions for Docker how to build the image for the app.i18n.js
: Configuration for next-translate.next-env.d.ts
: Next.js typings for TypeScript compiler.next.config.js
: Next.js configuration.package.json
: Manifest file for Node.js.README.md
: The file you're reading.schema.graphql
: Dumped GraphQL schema (used by IDEA).tsconfig.json
: TypeScript configuration.types.d.ts
: Module deNext.js typings for TypeScript compiler.larations for dependencies that do not have TypeScript typings.yarn.lock
: Auto-generated file for locking version numbers of all dependencies listed inpackage.json
.
- No pull requests can be merged without CI first building and running
Dockerfile
against it. See the bottommostCMD
in theDockerfile
for the full list of stuff it runs and validates. CI also verifies the code style, so there is no need to argue about formatting. - The code style is based on Airbnb JavaScript Style Guide with a few exceptions.
- Use functional components for everything.
- ESLint will show a warning for all
any
-typings. Useunknown
-type instead or ignore the line if you absolutely have to. - Comment all type ignores with a statement describing the reason for the ignore.
- Try to keep the JSX readable. In this project, we have tried to split up the JSX so that it almost never exceeds 4 levels of depth.
- Place all global constants in
constants.ts
file. If the constant is related to theming/styles, you can place it intheme.ts
. - Place all global helper functions in
helpers.ts
file. - Place all global hooks in the
hooks
folder in a file with the same name as the hook. - Use named imports/exports for everything except most Material UI components. Always re-export functions that are inside a folder from an
index.ts
file. - Whenever you add a new folder in the
src
directory, add it as an absolute path in thetsconfig.json
file. - Whenever you add a new file/folder in the root directory, please document it in the "What's inside?" section.
- Make sure your backend branch is up-to-date when running the GraphQL code gen as it validates the queries and mutations against the backend schemas.
- Use Material UI components instead of native HTML elements for consistency, e.g. Box vs
div
and Typography vs.p
-tags. - Use React Context API for all app-level state management. Use the
context
-folder as a reference. In short, we avoid using reducers for less boilerplate. Place the context provider as low as possible in the component tree. - If an interface/type is used in more than one place, put it in the
types
folder in a suitable file. If the interface/type is only used in one place, you may define it in that file. - If you have only one component per file, name the component prop interface/type as
Props
. Otherwise, if you have two components in a file, e.g.Foo
andBar
, name the prop interfaces/types asFooProps
andBarProps
. - Avoid using inline styles. In this project, we have used CSS in JS nearly everywhere with a few exceptions.
- Document everything that is hard to understand from the code. Use single line comment syntax for everything, even for multi-line comments.
- Avoid writing event handlers/functions directly in JSX to keep it more readable.
- Use
React.FC
syntax for all components. - Use Material Icons for all icons. Make sure to use the outlined variants of the icons.
- Use
<></>
instead ofReact.Fragment
for fragments. - If you split up JSX to multiple variables, name them so that they start with the word "render", e.g
const renderFoo = ...
. - TS doesn't play nice with React refs. Use non-null-assertions for refs, e.g.
const myRef = useRef(null!)
. - Use ES6 syntax everywhere:
- Avoid using the
function
keyword. - Use
async
/await
syntax. - Destructure objects and imports whenever possible.
- Avoid using the
- Whenever you add a new page that Google should index, make sure to add that entry to the
sitemap.xml.ts
filesstaticPaths
array. - Whenever you add a new page that Google should not index, make sure to add that entry to the
robots.txt.ts
filespaths
array. - Make sure not to update
@date-io/dayjs
beyond major version 1, later versions are currently not supported by MUI date pickers. - For forms that use dynamic initial values, use the
enableReinitialize
prop together with theuseMemo
hook for the initial values. - When settings
z-index
CSS values, document the use case so it's clear on which elements that value affects. - Do not use
next/link
, use our customLink
-component instead to make sure anchor tags are always rendered properly. - Generate Cypress fixtures easily by copying the request from
common.graphql
and using e.g. Insomnia to get the backend response as JSON. - Use
useMemo/useCallback
for all conditional rendering to optimize performance. - Use MUI media queries through the
useMediaQueryContext
-hook and not directly.