# Quickstart

### Setup CRA Template

```
yarn create react-app --template cra-template-rb my-example-app
cd my-example-app
```

### Install trixta-js packages

```
yarn add @trixtateam/trixta-js-core @trixtateam/trixta-js-rjsf @trixtateam/phoenix-to-redux @rjsf/core @rjsf/utils @rjsf/validator-ajv6
```

<details>

<summary>Generate Login Page Example</summary>

```
yarn generate
```

Follow the prompt instructions and create component under Pages directory

Replace file contents with below code. `src\app\pages\LoginPage`

```tsx
/**
 *
 * LoginPage
 *
 */
import {
  ReservedTrixtaRoles
} from '@trixtateam/trixta-js-core';
import {
  TrixtaActionComponent,
  TrixtaLoginWidget,
  TrixtaReactionComponent,
} from '@trixtateam/trixta-js-rjsf';
import { PageWrapper } from '../../components/PageWrapper';

interface Props {}

export function LoginPage(props: Props) {
  return (
    <PageWrapper>
    <div
        style={{
          margin: '10px',
          padding: '10px',
          backgroundColor: '#dce6ea',
        }}
      >
        <TrixtaLoginWidget />
      </div>
      <div
        style={{
          margin: '10px',
          padding: '10px',
        }}
      >
        <TrixtaActionComponent
          actionName="example"
          roleName={ReservedTrixtaRoles.EVERYONE_AUTHED}
        />
      </div>
      <div
        style={{
          margin: '10px',
          padding: '10px',
        }}
      >
        <TrixtaReactionComponent
          reactionName="welcome"
          requestForEffect
          roleName={ReservedTrixtaRoles.EVERYONE_AUTHED}
        />
      </div>
    </PageWrapper>
  );
}
```

</details>

<details>

<summary>Setup Reducer</summary>

Replace file contents with below code.

`src\store\reducers.ts`

```typescript
/**
 * Combine all reducers in this file and export the combined reducers.
 */

import { combineReducers } from '@reduxjs/toolkit';
import { phoenixReducer } from '@trixtateam/phoenix-to-redux';
import { trixtaReducer } from '@trixtateam/trixta-js-core';
import { InjectedReducersType } from 'utils/types/injector-typings';

/**
 * Merges the main reducer with the router state and dynamically injected reducers
 */
export function createReducer(injectedReducers: InjectedReducersType = {}) {
  // Initially we don't have any injectedReducers, so returning identity function to avoid the error
  if (Object.keys(injectedReducers).length === 0) {
    return state => state;
  } else {
    return combineReducers({
      trixta: trixtaReducer,
      phoenix: phoenixReducer,
      ...injectedReducers,
    });
  }
}
```

</details>

<details>

<summary>Setup Trixta Saga</summary>

Create and copy saga file `src\app\sagas\app.ts`

```typescript
import { setupTrixtaSaga } from '@trixtateam/trixta-js-core';
import { fork } from 'redux-saga/effects';

export default function* rootSaga() {
  yield fork(setupTrixtaSaga);
}
```

</details>

<details>

<summary>Configure Store</summary>

Replace file contents with below code.

`src\store\configureStore.ts`

```typescript
import {
  configureStore,
  getDefaultMiddleware,
  StoreEnhancer,
} from '@reduxjs/toolkit';
import { createInjectorsEnhancer } from 'redux-injectors';

import { createPhoenixChannelMiddleware } from '@trixtateam/phoenix-to-redux';
import createSagaMiddleware from 'redux-saga';
import { createReducer } from './reducers';

export function configureAppStore() {
  const reduxSagaMonitorOptions = {};
  // Makes redux connected to phoenix channels
  const phoenixChannelMiddleWare = createPhoenixChannelMiddleware();
  const sagaMiddleware = createSagaMiddleware(reduxSagaMonitorOptions);
  const { run: runSaga } = sagaMiddleware;

  // Create the store with saga middleware
  const middlewares = [sagaMiddleware, phoenixChannelMiddleWare];

  const enhancers = [
    createInjectorsEnhancer({
      createReducer,
      runSaga,
    }),
  ] as StoreEnhancer[];

  const store = configureStore({
    reducer: createReducer(),
    middleware: [
      ...getDefaultMiddleware({
        thunk: false,
        immutableCheck: {
          ignore: ['socket', 'channel', 'trixta', 'phoenix', 'router'],
        },
        serializableCheck: false,
      }),
      ...middlewares,
    ],
    devTools:
      /* istanbul ignore next line */
      process.env.NODE_ENV !== 'production' ||
      process.env.PUBLIC_URL.length > 0,
    enhancers,
  });

  return store;
}
```

</details>

<details>

<summary>Connect Trixta</summary>

Replace file contents with below code.

`src\app\index.tsx`

```tsx
/**
 *
 * App
 *
 * This component is the skeleton around the actual pages, and should only
 * contain code that should be seen on all pages. (e.g. navigation bar)
 */

import { Helmet } from 'react-helmet-async';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import { GlobalStyle } from '../styles/global-styles';
import { useTrixtaSpace } from '@trixtateam/trixta-js-core';
import { useTranslation } from 'react-i18next';
import { SagaInjectionModes, useInjectSaga } from 'redux-injectors';
import { HomePage } from './pages/HomePage/Loadable';
import { LoginPage } from './pages/LoginPage';
import { NotFoundPage } from './pages/NotFoundPage/Loadable';
import saga from './sagas/app';
export function App() {
  useInjectSaga({ key: 'App', saga, mode: SagaInjectionModes.DAEMON });
  useTrixtaSpace({ space: 'trixta-demo.space.trixta.io', params: {} });
  const { i18n } = useTranslation();
  return (
    <BrowserRouter>
      <Helmet
        titleTemplate="%s - React Boilerplate"
        defaultTitle="React Boilerplate"
        htmlAttributes={{ lang: i18n.language }}
      >
        <meta name="description" content="A React Boilerplate application" />
      </Helmet>

      <Routes>
        <Route path={process.env.PUBLIC_URL + '/'} element={<HomePage />} />
        <Route
          path={process.env.PUBLIC_URL + '/login'}
          element={<LoginPage />}
        />
        <Route element={<NotFoundPage />} />
      </Routes>
      <GlobalStyle />
    </BrowserRouter>
  );
}
```

</details>

### Run Example

```
yarn start
```

* Select the light theme
* Navigate to <http://localhost:3000/login>
* Follow the prompts and see what happens.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://trixtateam.gitbook.io/trixta-js-rjsf/quickstart.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
