# Client App Code Structure and Important Architecture Highlights ## File/Folder Structure: Domain-Driven Design From the point of the file/folder structure, the repo is in the process of switching to the Domain-Driven Design. New code should go to `/src/domain/**`. Directories under `/src/domain` contain files that are related with a certain part of the business domain / model entity. Examples: ``` src/domain/aspect/utils/aspectsCount.ts - a React hook that counts aspects that belong to some parent entity src/domain/session/SignInSegment.tsx - a React component that is shown when no user session is detected ``` There may be a need to create a deeper structure if a “domain” has many related files. Further structuring can be either domain-based or functional. E.g. there are `domain/admin/challenge` and `domain/admin/opportunity` but at the same time `challenge` has `challenge/providers` and `challenge/views`. While the former allows to organize code better by extracting “sub-domains”, the latter is just for the directories not to be too overcrowded. Having too many hooks? Give them their own folder. Most of the project files are currently structured in the old, functional-wise way. E.g. React hooks sit in a toplevel dir named `hooks`. The main rationale behind going away from this approach is you never search for a piece of code by its type. You never look for “any hook”, you need some specific hook instead, e.g. a hook that fetches Aspects. Going to `hooks` may be a mistake because that code may have never existed as a hook but rather be a container component. That works for you too, but there’s a chance you don’t find it in functional/type-oriented folder structure. Another benefit of the Domain-Driven structure is that it's easier to track connection/usage between files when they aren't `import`ed but are integrated by different means. One example could be connecting graphql files with the hooks that use them. On the contrary, when graphql files sit in a separate toplevel `graphql` folder it's even hard to track which quieries are used and which are not. ## Component roles React is extremely flexible when it comes to defining what types of components you have based on holding state, data fetching, etc., so it’s up to the team to come up with a convention. In our client-side app we agreed to have certain roles of components: ### Presentational Component / View The simplest type of a component. it’s the one that holds styles and does the translation. It should not be aware of the context it’s used in, hence no `useUpdateNavigation()` or `useQuery()`. It’s better to avoid direct history access or manipulation from within a presentational component. Think of it as data in -> formatted data out. ### Container / Provider Represents the data layer. Its purpose is to fetch the data for a caller as well as provide callbacks for data manipulation. Previously organized as container components within `src/containers`, new ones should be created as React hooks and be put under `src/domain/**` (`src/domain/**/providers` in case you have many provider hooks for a domain). ### Page Component The closest thing to what we call a Page component is the Controller in abstract MVC. To connect a view to a data provider, you compose them into a third component, a Page. Pages are singleton components - their instances describe the global state of UI and they access the global layout by leveraging hooks (useUpdateNavigation) in a way that is prone to race conditions. A Page is the one that accesses global things like `history`, reads query params etc. One of the ongoing changes in how the code is organized is also putting Layout into pages, so that they become the combination of Provider+Layout+View. ### Layout Layout isn’t a separate kind of a component, but an important subtype of the presentational one. It’s worth some special attention, because we’re currently moving from imperatively controlling layout from a Page (or worse, a View) to declaratively setting the current state of the global UI by returning Layout from the Page. A good example could be: instead of assuming the Page is rendered within something that has breadcrumbs and altering the parent state by calling `useUpdateNavigation()`, a Page can `return <Layout breadcrumbs={[…]} />`, thus explicitly telling which layout it wants and which props the Layout should receive. While this is not yet the case with breadcrumbs at the moment, the similar change is happening now with Page Tabs (migrated to Layout for Admin UI, but not yet for the general one).