Skip to content

Commit

Permalink
feat: add documentation for web (#251)
Browse files Browse the repository at this point in the history
  • Loading branch information
fruneen committed Dec 12, 2023
1 parent 1a0f324 commit 53469e4
Show file tree
Hide file tree
Showing 12 changed files with 470 additions and 32 deletions.
10 changes: 9 additions & 1 deletion docs/mint.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,15 @@
"mailer",
{
"group": "Web",
"pages": ["web/overview"]
"pages": [
"web/overview",
"web/styling",
"web/routing",
"web/calling-api",
"web/forms",
"web/services",
"web/environment-variables"
]
},
{
"group": "Deployment",
Expand Down
51 changes: 51 additions & 0 deletions docs/web/calling-api.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
title: "Calling API"
---

## Overview

Ship uses [TanStack Query](https://tanstack.com/query/latest) with our own axios library wrapper.
All queries are located in the `/resources` folder, organized into sub-folders for each resource.

TanStack Query helps easily fetch, cache, and update data.
Each API endpoint has a related React hook using TanStack Query.

When getting data with **apiService** in `services/api.service.ts`, no need to add the full endpoint URL.
The axios instance already has the base URL set.

If you need to make a request to a new endpoint, for example, for a `project` resource,
you need to add a new hook to `/resources/project/project.api.ts`

## Examples

```typescript resources/account/account.api.ts
export function useUpdate<T>() {
const update = (data: T) => apiService.put("/account", data);

return useMutation<User, unknown, T>(update);
}
```

```typescript resources/user/user.api.ts
export function useList<T>(params: T) {
const list = () => apiService.get("/users", params);

interface UserListResponse {
count: number;
items: User[];
totalPages: number;
}

return useQuery<UserListResponse>(["users", params], list);
}
```

```typescript pages/profile/index.page.tsx
type UpdateParams = z.infer<typeof accountUpdateSchema>;

const { mutate: update, isLoading: isUpdateLoading } = accountApi.useUpdate<UpdateParams>();
```

```typescript pages/home/index.tsx
const { data: users, isLoading: isUsersLoading } = userApi.useList(params);
```
100 changes: 100 additions & 0 deletions docs/web/environment-variables.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
title: Environment Variables
---

## Overview

We use different environment variables for different stages like developing, testing, and when the app is live.

This is done by using special files that have environments in them.

### How the App Chooses the Right Environment Variables File
The app knows which file to use based on a special environment variable called `APP_ENV`.

If `APP_ENV` is set to **staging**, the app will use the variables from the staging file.

<Card title="Development Stage" icon="code" iconType="light" color="#F96F5D">
In this stage, we work on making the app and adding new things.

The app uses a file named `.env.development` which has special environment variables just for people who are building the app.
</Card>

<Card title="Testing Stage (Staging)" icon="bug" iconType="light" color="#ca8b04">
Here, we test the app to make sure it's ready to go live.

We use the `.env.staging` file which has variables that help us test everything properly.
</Card>

<Card title="Live Stage (Production)" icon="industry-windows" iconType="light" color="#02C39A">
In the Production, the app is all done and people can use it.

App uses a file named `.env.production` which has environment variables for the app when it's being used by everyone.
</Card>

### Environment Variables Schema Validation
We use [Zod](https://zod.dev/) to check that our config is correct and in the right format.
This is important to make sure the app works without any problems.

This setup is found in the `src/config/index.ts` file.

<Tip>
To prefix any variables intended for client-side exposure with `NEXT_PUBLIC_`.
</Tip>

When we add new environment variables to .env files, we need to make sure they match what we set up in the `Zod` schema.

## Adding a New Variable

Here's how to add a new environment variable to the application:

<Steps>
<Step title="Identify the Environment Stages">
Determine the environment stages where the new variable will be used.

Refer to the following table for file associations:

| APP_ENV | File |
|-------------|------------------|
| development | .env.development |
| staging | .env.staging |
| production | .env.production |
</Step>

<Step title="Update `.env` Files">
Add the new variable to the respective `.env` files. For client-side variables, prefix them with `NEXT_PUBLIC_`.

```bash
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_TYooMQauvdEDq54NiTphI7jx
```
</Step>

<Step title="Modify the Schema in `src/config/index.ts`">
Update the schema in the `config/index.ts` file to include the new variable.
This step is crucial for schema validation.

```typescript config/index.ts
const schema = z.object({
...
STRIPE_PUBLISHABLE_KEY: z.string(),
});
```
</Step>

<Step title="Update the Configuration Object">
Add the new variable to the configuration object within the same file (`config/index.ts`), ensuring it matches the schema.

```typescript config/index.ts
const processEnv = {
...
STRIPE_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY,
};
```
</Step>
</Steps>

<Warning>
All the environment variables we use in the front-end part of our app can be seen by everyone.
So, don't put any secret stuff like passwords or private keys there.

Keep those safe and only on the server side! 馃洝锔忊湪
</Warning>
119 changes: 119 additions & 0 deletions docs/web/forms.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
---
title: Forms
---

## Overview

We use the [react-hook-form](https://react-hook-form.com/) library along with [@hookform/resolvers](https://www.npmjs.com/package/@hookform/resolvers) to simplify the process of creating and managing forms.
This setup allows for the quick development of robust forms.

### Form Schema

With [@hookform/resolvers](https://www.npmjs.com/package/@hookform/resolvers), you can validate your forms using a Zod schema.
Just write the schema and use it as a resolver in the `useForm` hook.
This approach not only validates your forms but also helps in creating perfectly typed forms by inferring types from the schema.

Example of setting up a form with Zod schema:
```tsx
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

// Define your schema
const schema = z.object({
firstName: z.string().min(1, 'Please enter First name').max(100),
lastName: z.string().min(1, 'Please enter Last name').max(100),
email: z.string().regex(EMAIL_REGEX, 'Email format is incorrect.'),
});

// Infer type from schema
type FormParams = z.infer<typeof schema>;

const Page = () => {
const { register, handleSubmit } = useForm<FormParams>({
resolver: zodResolver(schema),
});

// Form handling code here
};
```

### Error Handling
For error handling in forms, we use the `handle-error.util.ts` utility function.
This function parses error messages, sets them to the form fields' error states, or displays a global notification for general errors.

Usage:
```tsx
import { useForm } from 'react-hook-form';
import { handleError } from 'utils';

const Page: NextPage = () => {
const { setError } = useForm();

// Submit function
const onSubmit = (data: SignUpParams) => signUp(data, {
onError: (e) => handleError(e, setError),
});
}
```

#### Form usage

Here is an example of how you can create a form:

```tsx
import { handleError } from 'utils';
import { accountApi } from 'resources/account';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

// Define your schema
const schema = z.object({
// Schema details here
});

// Infer type from schema
type SignUpParams = z.infer<typeof schema>;

const Page: NextPage = () => {
const { mutate: signUp, isLoading: isSignUpLoading } = accountApi.useSignUp();
const {
register,
handleSubmit,
setError,
formState: { errors },
} = useForm<SignUpParams>({
resolver: zodResolver(schema),
});

// Submit function
const onSubmit = (data: SignUpParams) => signUp(data, {
onSuccess: (data) => {
// Handle success response
queryClient.setQueryData(['account'], data);
},
onError: (e) => handleError(e, setError),
});

// Form rendering
return (
<form onSubmit={handleSubmit(onSubmit)}>
<TextInput
{...register('name')}
error={errors.name?.message}
/>

<Button
type="submit"
loading={isSignUpLoading}
>
Submit
</Button>
</form>
);
};
```

By following these guidelines, you can effectively build and manage forms in our application,
ensuring a smooth user experience and robust form handling.
40 changes: 20 additions & 20 deletions docs/web/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,30 @@
title: "Overview"
---

Web Starter is what we think an ideal starting point for the most React frontend applications. It is based on the following primary technologies:
Web Starter is our starting point for React front-end applications.
It's crafted using a selection of advanced technologies and tools, making it a robust and efficient foundation for development.

- Next.js
- React Query
- React Hook Form + Zod
- Mantine UI + Tabler
- Typescript
- Storybook + Chromatic
The core technologies include:

## Start application.
- [Next.js](https://nextjs.org/): A React framework that supports features like server-side rendering, static site generation and routing.
- [TanStack Query](https://tanstack.com/query): A library for managing data fetching, caching, and updating in React apps.
- [React Hook Form](https://react-hook-form.com/) + [Zod](https://zod.dev/): Efficient form management and schema validation tools.
- [Mantine UI](https://mantine.dev/) + [Tabler](https://tabler-icons.io/): UI components and icons for responsive and accessible web interfaces.
- [Typescript](https://www.typescriptlang.org/): JavaScript with syntax for types, enhancing scalability and maintainability.
- [Storybook](https://storybook.js.org/) + [Chromatic](https://www.chromatic.com/): UI development tools for building and testing components.

Run ```npm run dev``` that will start the application with ```.env.development``` config.
## Web Starter Documentation Sections

You also can start the app using Dockerfile.
Explore the following sections for detailed information on different aspects of the Web Starter:

### Important notes
- [Styling](/web/styling): Focuses on the styling approach used in the application, detailing how to work with Mantine UI to create visually appealing interfaces.
- [Routing](/web/routing): Covers the routing mechanism within the application, explaining how to organize navigation flow.
- [Calling API](/web/calling-api): Dedicated to API interactions, this section explains how to effectively make requests to back-end services, manage responses, and handle errors using the provided API service utilities.
- [Forms](/web/forms): Discusses form management, highlighting the integration of React Hook Form and Zod for efficient form creation, validation, and handling user inputs.
- [Services](/web/services): Describes the various service layers used in the application, such as the API, socket, and analytics services, providing examples of how to implement and utilize these services for different functionalities.
- [Environment Variables](/web/environment-variables): Guides on managing environment-specific configurations, explaining the use of different `.env` files for development, staging, and production environments, and the importance of securing sensitive data.

You need to set ```APP_ENV``` variable in build args in a place where you deploy application.
It is responsible for the config file from ```config``` folder that will be taken when building your application
## React TypeScript Cheatsheet

| APP_ENV | File |
| ------------- |-------------------|
| development | .env.development |
| staging | .env.staging |
| production | .env.production |

## [React Typescript Cheatsheet](https://react-typescript-cheatsheet.netlify.app/docs/basic/setup/)
For a detailed guide on using React with TypeScript,
visit the [React TypeScript Cheatsheet](https://react-typescript-cheatsheet.netlify.app/docs/basic/setup/).
Loading

0 comments on commit 53469e4

Please sign in to comment.