# Nextjs Convention

## Table of Contents
- Use PascalCase for type names.
- Do not use I as a prefix for interface names.
- Use PascalCase for enum values.
- Use camelCase for function names.
- Use camelCase for property names and local variables.
- Do not use _ as a prefix for private properties.
- Use whole words in names when possible.
- Prefer function declaration over function expression
- Do name React component using UpperCamelCase
- Prefer named export over default export
- Always using Function Declaration over Function Expression
- Order of properties in a React component
- Always use React Fragment to render multiple React components over array and wrapper div:
- Always use <></> over <React.Fragment></React.Fragment> unless you want to pass a key to it
- Always create a function for each reducer actions
- Always use handle prefix for event handler
- Always use on prefix for event handler
- Always use React namespace when accessing React APIs
- Put images to the src/shared/assets/images folder
- Use absolute import to when importing from another module or from the shared module

### Use PascalCase for type names
```typescript
// bad
export type serviceLaneConfigurationPort = {
  id: string;
  serviceLaneConfigurationId: string;
  port: string;
  bound?: string;
  order: number;
  portType: string;
  aggregatedPort?: string;
};

// good
export type ServiceLaneConfigurationPort = {
  id: string;
  serviceLaneConfigurationId: string;
  port: string;
  bound?: string;
  order: number;
  portType: string;
  aggregatedPort?: string;
};

Do not use I as a prefix for interface names.

// bad
export interface IServiceLaneConfigurationPort {
  id: string;
  serviceLaneConfigurationId: string;
  port: string;
  bound?: string;
  order: number;
  portType: string;
  aggregatedPort?: string;
};

// good
export interface ServiceLaneConfigurationPort {
  id: string;
  serviceLaneConfigurationId: string;
  port: string;
  bound?: string;
  order: number;
  portType: string;
  aggregatedPort?: string;
};

Use PascalCase for enum values.

// bad
export enum ServiceLaneConfigurationPortType {
  INBOUND = 'inbound',
  OUTBOUND = 'outbound',
};

// good
export enum ServiceLaneConfigurationPortType {
  Inbound = 'inbound',
  Outbound = 'outbound',
};

Use camelCase for function names.

// bad
export function GetListDischargePort(request: GetListDischargePortRequest): GetListDischargePortResponse {
  // ...
}

// good
export function getListDischargePort(request: GetListDischargePortRequest): GetListDischargePortResponse {
  // ...
}

Use camelCase for property names and local variables.

// bad
export function getListDischargePort(request: GetListDischargePortRequest): GetListDischargePortResponse {
  const ServiceLaneConfigurationPort = request.ServiceLaneConfigurationPort;
  // ...
}

// good
export function getListDischargePort(request: GetListDischargePortRequest): GetListDischargePortResponse {
  const serviceLaneConfigurationPort = request.serviceLaneConfigurationPort;
  // ...
}

Do not use _ as a prefix for private properties.

// bad
export class ServiceLaneConfigurationPort {
  private _id: string;
  private _serviceLaneConfigurationId: string;
  private _port: string;
  private _bound?: string;
  private _order: number;
  private _portType: string;
  private _aggregatedPort?: string;
};

// good
export class ServiceLaneConfigurationPort {
  private id: string;
  private serviceLaneConfigurationId: string;
  private port: string;
  private bound?: string;
  private order: number;
  private portType: string;
  private aggregatedPort?: string;
};

Use whole words in names when possible.

// bad
export type ServiceLaneConfigurationPort {
  id: string;
  slcId: string;
  port: string;
  bound?: string;
  order: number;
  portType: string;
  aggregatedPort?: string;
};

// good
export type ServiceLaneConfigurationPort {
  id: string;
  serviceLaneConfigurationId: string;
  port: string;
  bound?: string;
  order: number;
  portType: string;
  aggregatedPort?: string;
};

Prefer function declaration over function expression

Prefer this:

function test() {}
Over this:

const test = () => {}
Because function expression does not have a name and will appear annonymous when debugging with Chrome devtools.

Do name React component using UpperCamelCase

// bad
export function serviceLaneConfigurationPort() {
  // ...
}

// good
export function ServiceLaneConfigurationPort() {
  // ...
}

Prefer named export over default export

Reason: https://basarat.gitbook.io/typescript/main-1/defaultisbad Maintainability concerns here:

// bad
export default function ServiceLaneConfigurationPort() {
  // ...
}

// good
export function ServiceLaneConfigurationPort() {
  // ...
}

Always using Function Declaration over Function Expression

// bad
const test = function() {
  // ...
}

// good
function test() {
  // ...
}

Order of properties in a React component

import * as React from 'react';
type Props = {/* */}
export function Component(props: Props): React.ReactElement {/* */}

Always use React Fragment to render multiple React components over array and wrapper div:

// bad
function Component() {
  return [
    <div key="1">Item 1</div>,
    <div key="2">Item 2</div>,
  ];
}

// good
function Component() {
  return (
    <>
      <div>Item 1</div>
      <div>Item 2</div>
    </>
  );
}

Always use <></> over <React.Fragment></React.Fragment> unless you want to pass a key to it


// bad
function Component() {
  return (
    <React.Fragment>
      <div>Item 1</div>
      <div>Item 2</div>
    </React.Fragment>
  );
}

// good
function Component() {
  return (
    <>
      <div>Item 1</div>
      <div>Item 2</div>
    </>
  );
}

Always create a function for each reducer actions

export function showTooltipAction(dispatch: React.Dispatch<Action>):
void {
dispatch({ type: 'SHOW_TOOLTIP' });
}
export function hideTooltipAction(dispatch: React.Dispatch<Action>):
void {
dispatch({ type: 'HIDE_TOOLTIP' });
}

Always use handle prefix for event handler

function Button(): React.ReactElement {
function handleClick() {/* */}
return <button onClick={handleClick} />;
}

Always use on prefix for event handler

type Props = {
onClick: () => void;
}

getStaticProps usecases:

The data required to render the page is available at build time ahead of a user’s request.

The data comes from a headless CMS.

The data can be publicly cached (not user-specific).

The page must be pre-rendered (for SEO) and be very fast — getStaticProps generates HTML and JSON files, both of which can be cached by a CDN for performance.

getServerSideProps usecases:

The data needs to be updated on every request and is important for SEO

A Slower TTFB compared to SSG is acceptable

The amount of data that needs to be fetch initially is huge

Packages:

Form validation: Use react-hook-form and yup.

Animation/Transition: Use framer-motion

Data fetching: axios

Server state management: react-query

Date-timer formatter: luxon