Skip to content

Commit

Permalink
Setup Frontend, add alert interface, config store & API
Browse files Browse the repository at this point in the history
  • Loading branch information
lcharette committed Aug 7, 2024
1 parent 4527705 commit dd5e8ce
Show file tree
Hide file tree
Showing 28 changed files with 8,082 additions and 1 deletion.
16 changes: 16 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')

module.exports = {
root: true,
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-typescript',
'@vue/eslint-config-prettier/skip-formatting'
],
parserOptions: {
ecmaVersion: 'latest'
},
ignorePatterns: ["dist/*"]
}
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ app/.env

# Ignore lock files
composer.lock
package-lock.json

# Ignore log, cache, sessions and storage directories content
app/cache/*
Expand Down
9 changes: 9 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://json.schemastore.org/prettierrc",
"semi": false,
"tabWidth": 4,
"singleQuote": true,
"printWidth": 100,
"trailingComma": "none",
"bracketSameLine": true
}
53 changes: 53 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,59 @@
"type": "shell",
"command": "vendor/bin/phpstan analyse",
"problemMatcher": []
},
{
"label": "npm update",
"type": "shell",
"options": {},
"command": "npm update",
"problemMatcher": []
},
{
"label": "npm build",
"type": "shell",
"options": {},
"command": "npm run build",
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "npm test",
"type": "shell",
"options": {},
"command": "npm run test",
"problemMatcher": [],
},
{
"label": "npm coverage",
"type": "shell",
"options": {},
"command": "npm run coverage",
"problemMatcher": []
},
{
"label": "npm lint",
"type": "shell",
"options": {},
"command": "npm run lint",
"problemMatcher": []
},
{
"label": "npm format",
"type": "shell",
"options": {},
"command": "npm run format",
"problemMatcher": []
},
{
"label": "npm type check",
"type": "shell",
"options": {},
"command": "npx vue-tsc",
"problemMatcher": []
}
]
}
14 changes: 14 additions & 0 deletions app/assets/interfaces/alerts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export interface AlertInterface {
title?: string
description?: string
style?: AlertStyle | keyof typeof AlertStyle
closeBtn?: boolean
hideIcon?: boolean
}

export enum AlertStyle {
Primary = 'Primary',
Success = 'Success',
Warning = 'Warning',
Danger = 'Danger'
}
3 changes: 3 additions & 0 deletions app/assets/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { type AlertInterface, AlertStyle } from './alerts'

export { type AlertInterface, AlertStyle }
8 changes: 8 additions & 0 deletions app/assets/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useConfigStore } from './stores/config'

export default {
install: () => {
const config = useConfigStore()
config.load()
}
}
18 changes: 18 additions & 0 deletions app/assets/stores/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { defineStore } from 'pinia'
import axios from 'axios'

export const useConfigStore = defineStore('config', {
persist: true,
state: () => {
return {
config: {}
}
},
actions: {
async load() {
axios.get('/api/config').then((response) => {
this.config = response.data
})
}
}
})
62 changes: 62 additions & 0 deletions app/src/Controller/ConfigController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

/*
* UserFrosting Core Sprinkle (http://www.userfrosting.com)
*
* @link https://github.com/userfrosting/sprinkle-core
* @copyright Copyright (c) 2013-2024 Alexander Weissman & Louis Charette
* @license https://github.com/userfrosting/sprinkle-core/blob/master/LICENSE.md (MIT License)
*/

namespace UserFrosting\Sprinkle\Core\Controller;

use Psr\Http\Message\ResponseInterface as Response;
use UserFrosting\Config\Config;
use UserFrosting\I18n\Translator;
use UserFrosting\Sprinkle\Core\I18n\SiteLocaleInterface;

/**
* Return the config variables to use in the frontend.
*/
class ConfigController
{
/**
* @param Config $config
* @param SiteLocaleInterface $locale
* @param Translator $translator
*/
public function __construct(
protected Config $config,
protected SiteLocaleInterface $locale,
protected Translator $translator
) {
}

/**
* @param Response $response
*/
public function __invoke(Response $response): Response
{
$payload = json_encode($this->getData(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT);
$response->getBody()->write($payload);

return $response
->withHeader('Content-Type', 'application/json');
}

/**
* @return mixed[]
*/
public function getData(): array
{
$data = [
'site' => $this->config->get('site'),
'locales' => [
'available' => $this->locale->getAvailableOptions(),
'current' => $this->translator->getLocale()->getIdentifier(),
],
];

return $data;
}
}
2 changes: 2 additions & 0 deletions app/src/Core.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
use UserFrosting\Sprinkle\Core\Middlewares\SessionMiddleware;
use UserFrosting\Sprinkle\Core\Middlewares\URIMiddleware;
use UserFrosting\Sprinkle\Core\Routes\AlertsRoutes;
use UserFrosting\Sprinkle\Core\Routes\ApiRoutes;
use UserFrosting\Sprinkle\Core\ServicesProvider\AlertStreamService;
use UserFrosting\Sprinkle\Core\ServicesProvider\CacheService;
use UserFrosting\Sprinkle\Core\ServicesProvider\ConfigService;
Expand Down Expand Up @@ -194,6 +195,7 @@ public function getRoutes(): array
{
return [
AlertsRoutes::class,
ApiRoutes::class,
];
}

Expand Down
25 changes: 25 additions & 0 deletions app/src/Routes/ApiRoutes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

/*
* UserFrosting Core Sprinkle (http://www.userfrosting.com)
*
* @link https://github.com/userfrosting/sprinkle-core
* @copyright Copyright (c) 2013-2024 Alexander Weissman & Louis Charette
* @license https://github.com/userfrosting/sprinkle-core/blob/master/LICENSE.md (MIT License)
*/

namespace UserFrosting\Sprinkle\Core\Routes;

use Slim\App;
use UserFrosting\Routes\RouteDefinitionInterface;
use UserFrosting\Sprinkle\Core\Controller\ConfigController;

class ApiRoutes implements RouteDefinitionInterface
{
public function register(App $app): void
{
$app->get('/api/config', ConfigController::class)->setName('api.config');
}
}
32 changes: 32 additions & 0 deletions app/tests/Integration/Controllers/ConfigControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

/*
* UserFrosting Core Sprinkle (http://www.userfrosting.com)
*
* @link https://github.com/userfrosting/sprinkle-core
* @copyright Copyright (c) 2013-2024 Alexander Weissman & Louis Charette
* @license https://github.com/userfrosting/sprinkle-core/blob/master/LICENSE.md (MIT License)
*/

namespace UserFrosting\Sprinkle\Core\Tests\Integration\Controller;

use UserFrosting\Sprinkle\Core\Tests\CoreTestCase as TestCase;

/**
* Tests ConfigController class.
*/
class ConfigControllerTest extends TestCase
{
public function testConfig(): void
{
// Create request with method and url and fetch response
$request = $this->createJsonRequest('GET', '/api/config');
$response = $this->handleRequest($request);

// Assert response status & body
$this->assertResponseStatus(200, $response);
$this->assertJsonStructure(['site', 'locales'], $response);
}
}
13 changes: 13 additions & 0 deletions dist/interfaces/alerts.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export interface AlertInterface {
title?: string;
description?: string;
style?: AlertStyle | keyof typeof AlertStyle;
closeBtn?: boolean;
hideIcon?: boolean;
}
export declare enum AlertStyle {
Primary = "Primary",
Success = "Success",
Warning = "Warning",
Danger = "Danger"
}
2 changes: 2 additions & 0 deletions dist/interfaces/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { AlertInterface, AlertStyle } from './alerts';
export { type AlertInterface, AlertStyle };
1 change: 1 addition & 0 deletions dist/plugin.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./stores.cjs"),o={install:()=>{e.useConfigStore().load()}};exports.default=o;
4 changes: 4 additions & 0 deletions dist/plugin.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare const _default: {
install: () => void;
};
export default _default;
9 changes: 9 additions & 0 deletions dist/plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useConfigStore as o } from "./stores.js";
const i = {
install: () => {
o().load();
}
};
export {
i as default
};
Loading

0 comments on commit dd5e8ce

Please sign in to comment.