The project is based on

- [Kirby CMS](https://getkirby.com) as the content management system
- [Vite](https://vitejs.dev/) as the build tool
- [Vue](https://fr.vuejs.org/) as the JavaScript framework
- [Vue Router](https://router.vuejs.org) for handling routing
  [Pinia](https://pinia.vuejs.org/) as a state management library.

Vue is used with the composition API approach.

The project also includes some helper libraries that are available throughout the /src directory. These libraries include:

- [dayjs](https://day.js.org/): a lightweight JavaScript date library for parsing, manipulating, and formatting dates. To use dayjs in your code, you can import it like this:

```javascript
import dayjs from "dayjs";
```

- [slugify](https://www.npmjs.com/package/slugify): a library for converting strings into URL-friendly slugs. To use slugify in your code, you can import it like this:

```javascript
import slugify from "slugify";
```

# Development

## Development environment

### First setup :

- **From the `/public` directory**, install the Kirby dependencies : `composer install`
- **From the root directory**, install the Node dependencies : `npm install`
- Replace the `public/site/plugins/kql`plugins by its last version, downloaded from the [official GitHub repo](https://github.com/getkirby/kql/releases).
- Launch the servers (see below).
- Create the first user to the Kirby panel through http://localhost:8888/panel.
- In the root directory, create an .env file containing your user's connexion informations :

```bash
VITE_USERNAME=mail@example.com
VITE_PASSWORD=your-private-password
```

### Servers

- **From the `/public` directory**, launch the PHP server : `php -S localhost:8888 kirby/router.php`.
- In another terminal tab, **from the root directory**, launch the Vite server : `vite`.

## Code

### Rules and conventions

- All `.vue` files' names are written in PascalCase :
  - ⛔ `sidenav.vue`
  - ⛔ `sideNav.vue`
  - ✅ `SideNav.vue`
  - ✅ `Home.vue`
- Stores files' names, located in `/src/stores/`, are written in camelCase and doesn't include the word "Store" :
  - ⛔ `Api.js`
  - ⛔ `ApiStore.js`
  - ⛔ `apiStore.js`
  - ✅ `api.js`
  - ✅ `pageData.js`

### Creating a page

Templates are managed through Vue (`/src/views`). Thus, the process for creating new pages differs from the Kirby usual one. In addition to the **blueprint** (`/public/site/blueprints/pages/example.yml`) and **template** (`/public/site/templates/example.php`) files and the corresponding content directory (`/public/content/<page-uri>/<template>.txt`), it needs at least a **content representation** (`/public/site/templates/example.json.php`) and a **view component** (`/src/views/Example.vue`) ones.

1. **Create the blueprint** as usual.
2. **Create the corresponding template**. Distincts templates are needed, but all of them should contain this same single line of code (that you can also find in `/public/site/templates/example.php`) : `<?php snippet('generic-template') ?>`.
3. **Create the corresponding content directory**. Put the `<template-name>.txt` within.
4. **Create the corresponding [content representation](https://getkirby.com/docs/guide/templates/content-representations)** following this code (also in `/public/site/templates/example.json.php`) :

```php
<?php

$specificData = [
  "exampleField" => $page->exampleField(),
  "exampleHardData" => 'Example hard value'
];

$pageData = array_merge($genericData, $specificData);

echo json_encode([
  "page" => $pageData,
  "user" => $userData
]);
```

`$genericData` are defined in the `/public/site/controllers/site.php` controllers. By default, it contains a simple representation of the page object.

4. **Create the corresponding views** in `/src/views/`. It's just a simple vue component that heritates the page data through the page object (also in `/src/views/Example.vue`) :

```vue
<template>
  <h1>{{ page.content.title }}</h1>
</template>

<script setup>
import { usePageStore } from "../stores/page";
import { storeToRefs } from "pinia";

const { page } = storeToRefs(usePageStore());
</script>
```

5. **Create the route** in the `/src/router/routes.js`. A route is a combination of a path and a corresponding component. The path can include variable parameters, which can be captured and passed to the component. To create a route, you need to import the component and add an object to the routes array. See the [Vue Router documentation](https://router.vuejs.org/guide/) for more information.

```vue
<script setup>
import ExampleView from "../views/ExampleView.vue";

const routes = [
  // Existing routes go here...
  {
    // This is a static route without any variable parameters
    path: "/page-uri",
    component: ExampleView,
  },
  {
    // This is a dynamic route with a variable parameter :title
    path: "/page-uri/:title",
    component: ExampleView,
    // OPTIONAL. The props: true option allows the route parameters to be passed as props to the component.
    props: true,
  },
];

export default routes;
</script>
```

**The name of the component should be exactly the same as the name of the template, including its case**. This project follows the Vue convention to use pascal case

### Files data

Files data must be prepared using the `getFileData()` function, which takes a `Kirby\Cms\File` class as a parameter. It is located in `public/site/plugins/helpers/index.php`.

### Steps

Each project is composed of different steps, which are ordered regarding project process and may be required (\*) or optional :

- Client brief\* :

```json
{
  "id": "clientBrief",
  "label": "Brief client",
  "slug": "client-brief"
}
```

- Proposal\* :

```json
{
  "id": "proposal",
  "label": "Offre commerciale",
  "slug": "proposal"
}
```

- Extended Brief\*

```json
{
  "id": "extendedBrief",
  "label": "Brief enrichi",
  "slug": "extended-brief"
}
```

- Industrial ideation

```json
{
  "id": "industrialIdeation",
  "label": "Idéation industrielle",
  "slug": "industrial-ideation"
}
```

- Virtual sample\*

```json
{
  "id": "virtualSample",
  "label": "Échantillon industriel",
  "slug": "virtual-sample"
}
```

- Physical sample

```json
{
  "id": "physicalSample",
  "label": "Échantillon physique",
  "slug": "physical-sample"
}
```
