Compare commits

..

1 Commits

Author SHA1 Message Date
1dca0951e8 🚧 Commence la personnalisation de l'affichage des pages
Pour #12
2022-04-19 16:55:18 +02:00
22 changed files with 746 additions and 44 deletions

View File

@ -1,39 +1,66 @@
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400"></a></p>
# Diareact
<p align="center">
<a href="https://travis-ci.org/laravel/framework"><img src="https://travis-ci.org/laravel/framework.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
</p>
A personnal and encrypted diary with Laravel and React.
## About Laravel
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
- [Simple, fast routing engine](https://laravel.com/docs/routing).
- [Powerful dependency injection container](https://laravel.com/docs/container).
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
- [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
## Badges
Laravel is accessible, powerful, and provides tools required for large, robust applications.
[![Build Status](https://ci.canhelpme.com/api/badges/Shikiryu/diaREact/status.svg?ref=refs/heads/main)](https://ci.canhelpme.com/Shikiryu/maison-montsoult)
## Learning Laravel
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
## Installation
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 1500 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
Install diareact
## Laravel Sponsors
```bash
git clone ssh://gogs@git.shikiryu.com:2200/Shikiryu/diaREact.git
cd diaREact
composer install
npm install
```
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
## Authors
### Premium Partners
[@shikiryu](https://git.shikiryu.com/Shikiryu)
- **[Vehikl](https://vehikl.com/)**
- **[Tighten Co.](https://tighten.co)**
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
- **[64 Robots](https://64robots.com)**
- **[Cubet Techno Labs](https://cubettech.com)**
- **[Cyber-Duck](https://cyber-duck.co.uk)**
- **[Many](https://www.many.co.uk)**
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
- **[DevSquad](https://devsquad.com)**
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
- **[OP.GG](https://op.gg)**
- **[CMS Max](https://www.cmsmax.com/)**
- **[WebReinvent](https://webreinvent.com/?utm_source=laravel&utm_medium=github&utm_campaign=patreon-sponsors)**
- **[Lendio](https://lendio.com)**
- **[Romega Software](https://romegasoftware.com)**
## Contributing
## Acknowledgements
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
- [React](https://github.com/facebook/react/)
- [React MD Editor](https://github.com/uiwjs/react-md-editor)
## Code of Conduct
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
## Security Vulnerabilities
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
## License
[MIT](https://choosealicense.com/licenses/mit/)
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).

View File

@ -45,12 +45,14 @@ class PageController extends Controller
}
}, Storage::disk('pages')->files(Auth::user()->getAuthIdentifier())));
/** @var \App\Models\User $user */
$user = Auth::user();
return view('pages.index', [
'start_date'=> min((new DateTime())->sub(new DateInterval('P1Y')), $user->created_at),
'checkword' => $user->checkword,
'pages' => $pages,
'start_date' => min((new DateTime())->sub(new DateInterval('P1Y')), $user->created_at),
'checkword' => $user->checkword,
'settings' => json_encode($user->getSettings()),
'pages' => $pages,
]);
}
@ -124,7 +126,7 @@ class PageController extends Controller
*/
public function edit($id)
{
throw new MethodNotAllowedHttpException('You can\'t edit a page.');
throw new MethodNotAllowedHttpException(['GET'], 'You can\'t edit a page.');
}
/**
@ -137,7 +139,7 @@ class PageController extends Controller
*/
public function update(Request $request, $id)
{
throw new MethodNotAllowedHttpException('You can\'t edit a page.');
throw new MethodNotAllowedHttpException(['GET'], 'You can\'t edit a page.');
}
/**

View File

@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Http\Requests\User\SettingsRequest;
use App\Http\Requests\User\WordCheckRequest;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
@ -23,4 +24,26 @@ class UserController extends Controller
return response()->json(['success' => true]);
}
public function settings()
{
return view('user.settings', [
'settings' => Auth::user()->getSettings(),
]);
}
public function storeSettings(SettingsRequest $request)
{
$validated = $request->validated();
$user = User::where('id', Auth::user()->getAuthIdentifier())->firstOrFail();
foreach ($validated as $name => $value) {
$user->{$name} = $value;
}
$user->save();
Auth::setUser($user);
$request->session()->flash('status', __('Settings saved!'));
return redirect()->route('user.settings');
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Http\Requests\User;
use Illuminate\Foundation\Http\FormRequest;
class SettingsRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'text_color' => ['required', 'string', 'max:7'],
'background_color' => ['required', 'string', 'max:7'],
'font' => ['required', 'string', 'max:255'],
'font_size' => ['required', 'numeric'],
'line_spacing' => ['required', 'numeric'],
];
}
}

View File

@ -33,6 +33,14 @@ class User extends Authenticatable
'remember_token',
];
protected $settings = [
'text_color',
'background_color',
'font',
'font_size',
'line_spacing',
];
/**
* The attributes that should be cast.
*
@ -41,4 +49,17 @@ class User extends Authenticatable
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* @return array
*/
public function getSettings()
{
$settings = [];
foreach ($this->settings as $setting) {
$settings[$setting] = $this->{$setting};
}
return $settings;
}
}

View File

@ -6,13 +6,15 @@
"license": "MIT",
"require": {
"php": "^7.3|^8.0",
"doctrine/dbal": "^3.3",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"kzykhys/yaml-front-matter": "^1.0",
"laravel/framework": "^9.0",
"laravel/sanctum": "^2.11",
"laravel/tinker": "^2.5",
"laravel/ui": "^3.4"
"laravel/ui": "^3.4",
"ext-json": "*"
},
"require-dev": {
"spatie/laravel-ignition": "^1.0",

398
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "af7035cb5f906bc34893e53d97e6656f",
"content-hash": "4b6bb4a29b9cbd7a05ba0cc319b1aa4c",
"packages": [
{
"name": "asm89/stack-cors",
@ -197,6 +197,353 @@
},
"time": "2021-08-13T13:06:58+00:00"
},
{
"name": "doctrine/cache",
"version": "2.1.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "331b4d5dbaeab3827976273e9356b3b453c300ce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/331b4d5dbaeab3827976273e9356b3b453c300ce",
"reference": "331b4d5dbaeab3827976273e9356b3b453c300ce",
"shasum": ""
},
"require": {
"php": "~7.1 || ^8.0"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
"alcaeus/mongo-php-adapter": "^1.1",
"cache/integration-tests": "dev-master",
"doctrine/coding-standard": "^8.0",
"mongodb/mongodb": "^1.1",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"predis/predis": "~1.0",
"psr/cache": "^1.0 || ^2.0 || ^3.0",
"symfony/cache": "^4.4 || ^5.2 || ^6.0@dev",
"symfony/var-exporter": "^4.4 || ^5.2 || ^6.0@dev"
},
"suggest": {
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
},
"type": "library",
"autoload": {
"psr-4": {
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
"homepage": "https://www.doctrine-project.org/projects/cache.html",
"keywords": [
"abstraction",
"apcu",
"cache",
"caching",
"couchdb",
"memcached",
"php",
"redis",
"xcache"
],
"support": {
"issues": "https://github.com/doctrine/cache/issues",
"source": "https://github.com/doctrine/cache/tree/2.1.1"
},
"funding": [
{
"url": "https://www.doctrine-project.org/sponsorship.html",
"type": "custom"
},
{
"url": "https://www.patreon.com/phpdoctrine",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache",
"type": "tidelift"
}
],
"time": "2021-07-17T14:49:29+00:00"
},
{
"name": "doctrine/dbal",
"version": "3.3.5",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "719663b15983278227669c8595151586a2ff3327"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/719663b15983278227669c8595151586a2ff3327",
"reference": "719663b15983278227669c8595151586a2ff3327",
"shasum": ""
},
"require": {
"composer-runtime-api": "^2",
"doctrine/cache": "^1.11|^2.0",
"doctrine/deprecations": "^0.5.3",
"doctrine/event-manager": "^1.0",
"php": "^7.3 || ^8.0",
"psr/cache": "^1|^2|^3",
"psr/log": "^1|^2|^3"
},
"require-dev": {
"doctrine/coding-standard": "9.0.0",
"jetbrains/phpstorm-stubs": "2021.1",
"phpstan/phpstan": "1.5.3",
"phpstan/phpstan-strict-rules": "^1.1",
"phpunit/phpunit": "9.5.16",
"psalm/plugin-phpunit": "0.16.1",
"squizlabs/php_codesniffer": "3.6.2",
"symfony/cache": "^5.2|^6.0",
"symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0",
"vimeo/psalm": "4.22.0"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
},
"bin": [
"bin/doctrine-dbal"
],
"type": "library",
"autoload": {
"psr-4": {
"Doctrine\\DBAL\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
}
],
"description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.",
"homepage": "https://www.doctrine-project.org/projects/dbal.html",
"keywords": [
"abstraction",
"database",
"db2",
"dbal",
"mariadb",
"mssql",
"mysql",
"oci8",
"oracle",
"pdo",
"pgsql",
"postgresql",
"queryobject",
"sasql",
"sql",
"sqlite",
"sqlserver",
"sqlsrv"
],
"support": {
"issues": "https://github.com/doctrine/dbal/issues",
"source": "https://github.com/doctrine/dbal/tree/3.3.5"
},
"funding": [
{
"url": "https://www.doctrine-project.org/sponsorship.html",
"type": "custom"
},
{
"url": "https://www.patreon.com/phpdoctrine",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal",
"type": "tidelift"
}
],
"time": "2022-04-05T09:50:18+00:00"
},
{
"name": "doctrine/deprecations",
"version": "v0.5.3",
"source": {
"type": "git",
"url": "https://github.com/doctrine/deprecations.git",
"reference": "9504165960a1f83cc1480e2be1dd0a0478561314"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/deprecations/zipball/9504165960a1f83cc1480e2be1dd0a0478561314",
"reference": "9504165960a1f83cc1480e2be1dd0a0478561314",
"shasum": ""
},
"require": {
"php": "^7.1|^8.0"
},
"require-dev": {
"doctrine/coding-standard": "^6.0|^7.0|^8.0",
"phpunit/phpunit": "^7.0|^8.0|^9.0",
"psr/log": "^1.0"
},
"suggest": {
"psr/log": "Allows logging deprecations via PSR-3 logger implementation"
},
"type": "library",
"autoload": {
"psr-4": {
"Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
"homepage": "https://www.doctrine-project.org/",
"support": {
"issues": "https://github.com/doctrine/deprecations/issues",
"source": "https://github.com/doctrine/deprecations/tree/v0.5.3"
},
"time": "2021-03-21T12:59:47+00:00"
},
{
"name": "doctrine/event-manager",
"version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/event-manager.git",
"reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/event-manager/zipball/41370af6a30faa9dc0368c4a6814d596e81aba7f",
"reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"conflict": {
"doctrine/common": "<2.9@dev"
},
"require-dev": {
"doctrine/coding-standard": "^6.0",
"phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\": "lib/Doctrine/Common"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
},
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com"
}
],
"description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.",
"homepage": "https://www.doctrine-project.org/projects/event-manager.html",
"keywords": [
"event",
"event dispatcher",
"event manager",
"event system",
"events"
],
"support": {
"issues": "https://github.com/doctrine/event-manager/issues",
"source": "https://github.com/doctrine/event-manager/tree/1.1.x"
},
"funding": [
{
"url": "https://www.doctrine-project.org/sponsorship.html",
"type": "custom"
},
{
"url": "https://www.patreon.com/phpdoctrine",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager",
"type": "tidelift"
}
],
"time": "2020-05-29T18:28:51+00:00"
},
{
"name": "doctrine/inflector",
"version": "2.0.4",
@ -2305,6 +2652,55 @@
],
"time": "2021-12-04T23:24:31+00:00"
},
{
"name": "psr/cache",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/cache.git",
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
"shasum": ""
},
"require": {
"php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Cache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for caching libraries",
"keywords": [
"cache",
"psr",
"psr-6"
],
"support": {
"source": "https://github.com/php-fig/cache/tree/3.0.0"
},
"time": "2021-02-03T23:26:27+00:00"
},
{
"name": "psr/container",
"version": "2.0.2",

View File

@ -0,0 +1,48 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('text_color')->default('#000000');
$table->string('background_color')->default('#FFFFFF');
$table->string('font')->default('Arial');
$table->float('font_size', 3, 1)->default(16);
$table->float('line_spacing', 2, 3)->default(1.5);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('text_color');
});
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('background_color');
});
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('font');
});
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('font_size');
});
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('line_spacing');
});
}
};

View File

@ -24,6 +24,7 @@ const sessionPassphrase = sessionStorage.getItem("key") as string;
let pages: IList[] = [];
let getPageContentUrl,
postUrl,
settings,
removeUrl,
checkword,
startDate,
@ -33,7 +34,8 @@ if (app) {
getPageContentUrl = "" + app.getAttribute('data-url');
pages = JSON.parse("" + app.getAttribute('data-list')) as IList[];
postUrl = "" + app.getAttribute('data-post');
startDate = "" + app.getAttribute('data-start');
startDate = "" + app.getAttribute('data-start');
settings = JSON.parse("" + app.getAttribute('data-settings'));
removeUrl = "" + app.getAttribute('data-remove');
csrf = "" + app.getAttribute('data-csrf');
checkword = "" + app.getAttribute('data-checkword');
@ -195,6 +197,7 @@ function App() {
csrf={csrf}
removeUrl={removeUrl}
loadPages={loadPages}
settings={settings}
setAllLoaded={setAllLoaded}
/>
<Divider/>

View File

@ -5,7 +5,7 @@ import {IPages} from "../../interfaces/IPages";
import {IList} from "../../interfaces/IList";
import {isAllLoadedLocally} from "../../utils";
export default function Pages({pages, url, removeUrl, csrf, passphrase, loadPages, setAllLoaded}: IPages) {
export default function Pages({pages, url, removeUrl, csrf, passphrase, loadPages, settings, setAllLoaded}: IPages) {
const isPassphraseSet = passphrase !== null;
const perPage = 1;
const total = pages.length;
@ -24,26 +24,22 @@ export default function Pages({pages, url, removeUrl, csrf, passphrase, loadPage
const json = await response.json();
if (json.success) {
console.log(listPages.length);
const newListPages = listPages.filter(function (value) {
console.log(value.id);
return value.id !== id;
});
setListPages(newListPages);
console.log(newListPages.length);
console.log(listPages.length);
updateListPages(newListPages.slice((currentPage - 1) * perPage, ((currentPage - 1) * perPage) + perPage).map(page =>
<Page page={page} url={url} remove={removePage} passphrase={passphrase} key={page.id}/>));
<Page page={page} url={url} remove={removePage} settings={settings} passphrase={passphrase} key={page.id}/>));
}
}
const [listPagesDisplayed, updateListPages] = React.useState(listPages.slice((currentPage-1) * perPage, ((currentPage-1) * perPage) + perPage ).map(page =>
<Page page={page} url={url} remove={removePage} passphrase={passphrase} key={page.id} />));
<Page page={page} url={url} remove={removePage} settings={settings} passphrase={passphrase} key={page.id} />));
const handlePageChange = (event: React.ChangeEvent<unknown>, value: number) => {
setPage(value);
updateListPages(listPages.slice((value-1) * perPage, ((value-1) * perPage) + perPage).map(page =>
<Page page={page} url={url} remove={removePage} passphrase={passphrase} key={page.id}/>));
<Page page={page} url={url} settings={settings} remove={removePage} passphrase={passphrase} key={page.id}/>));
};
const loadAllPages = function() {
@ -61,7 +57,7 @@ export default function Pages({pages, url, removeUrl, csrf, passphrase, loadPage
localStorage.setItem(page.id + "text", json.content);
updateListPages([]);
updateListPages(listPages.slice((currentPage-1) * perPage, ((currentPage-1) * perPage) + perPage).map(page =>
<Page page={page} url={url} remove={removePage} passphrase={passphrase} key={page.id}/>));
<Page page={page} url={url} remove={removePage} settings={settings} passphrase={passphrase} key={page.id}/>));
}
}

View File

@ -3,7 +3,7 @@ import {
AlertTitle,
Card, CardContent,
CardHeader, Collapse,
Grid, IconButton
Grid, IconButton,
} from '@mui/material';
import MoreVertIcon from '@mui/icons-material/MoreVert';
import * as React from 'react';
@ -12,7 +12,7 @@ import {Delete, Download} from "@mui/icons-material";
import MDEditor from "@uiw/react-md-editor";
import {PropPage} from "../../interfaces/PropPage";
const Page = function({page, url, passphrase, remove}: PropPage) {
const Page = function({page, url, passphrase, settings, remove}: PropPage) {
const [more, setMore] = React.useState<boolean>(false);
const handleMoreClick = () => { setMore(!more); };
@ -49,10 +49,22 @@ const Page = function({page, url, passphrase, remove}: PropPage) {
);
}
return (
<Grid item xs={12} sm={12} md={12} id={page.id}>
<Grid item xs={12} sm={12} md={12} id={page.id}
sx={{
bgcolor: settings.background_color,
color: settings.text_color,
fontSize: settings.font_size + "px",
fontFamily: settings.font,
lineHeight: settings.line_spacing
}}>
<Card>
<CardHeader
sx={{
bgcolor: settings.background_color,
color: settings.text_color
}}
action={
icons
}
@ -65,7 +77,13 @@ const Page = function({page, url, passphrase, remove}: PropPage) {
</IconButton>
</Collapse>
</CardHeader>
<CardContent>
<CardContent sx={{
backgroundColor: settings.background_color,
color: settings.text_color,
fontSize: settings.font_size + "px",
fontFamily: settings.font,
lineHeight: settings.line_spacing
}}>
<MDEditor.Markdown source={content} />
</CardContent>
</Card>

View File

@ -13,6 +13,12 @@ export default function BasicMenu({nickname}) {
setAnchorEl(null);
};
function gotoSettings() {
const currentHref = location.href.split('/');
currentHref.pop();
location.href = currentHref.join('/') + '/settings';
}
function logout() {
const logoutForm: HTMLFormElement = document.getElementById("logout-form") as HTMLFormElement;
logoutForm.submit();
@ -39,7 +45,7 @@ export default function BasicMenu({nickname}) {
'aria-labelledby': 'basic-button',
}}
>
{/*<MenuItem onClick={handleClose}>My account</MenuItem>*/}
<MenuItem onClick={gotoSettings}>Settings</MenuItem>
<MenuItem onClick={logout}>Logout</MenuItem>
</Menu>
</div>

View File

@ -28,6 +28,12 @@ export default function MobileMenu({nickname}) {
setState( open );
};
function gotoSettings() {
const currentHref = location.href.split('/');
currentHref.pop();
location.href = currentHref.join('/') + '/settings';
}
function logout() {
const logoutForm: HTMLFormElement = document.getElementById("logout-form") as HTMLFormElement;
logoutForm.submit();
@ -53,7 +59,7 @@ export default function MobileMenu({nickname}) {
onKeyDown={toggleDrawer(false)}
>
<List>
<ListItem button key={"user"}>
<ListItem key={"user"}>
<ListItemIcon>
<MailIcon />
</ListItemIcon>
@ -62,7 +68,13 @@ export default function MobileMenu({nickname}) {
</List>
<Divider />
<List>
<ListItem button key={"user.logout"} onClick={logout}>
<ListItem key={"user.settings"} onClick={gotoSettings}>
<ListItemIcon>
<MailIcon />
</ListItemIcon>
<ListItemText primary={"Settings"} />
</ListItem>
<ListItem key={"user.logout"} onClick={logout}>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>

View File

@ -1,5 +1,6 @@
import {IList} from "./IList";
import * as React from "react";
import {ISettings} from "./ISettings";
export interface IPages {
pages: IList[];
@ -7,6 +8,7 @@ export interface IPages {
removeUrl: string;
csrf: string;
passphrase: string;
settings: ISettings;
loadPages: React.MutableRefObject<() => void>;
setAllLoaded: React.Dispatch<React.SetStateAction<boolean>>;
}

View File

@ -0,0 +1,7 @@
export interface ISettings {
background_color: string;
text_color: string;
font_size: number;
font: string;
line_spacing: number;
}

View File

@ -1,9 +1,11 @@
import { Ref } from "react";
import {IList} from "./IList";
import {ISettings} from "./ISettings";
export interface PropPage {
page: IList;
url: string;
settings: ISettings;
passphrase: string;
remove: (id) => void;
ref: Ref<IList>;

View File

@ -7,6 +7,9 @@
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Fonts -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">
<!-- Styles -->
<link rel="stylesheet" href="{{ asset('css/app.css') }}">

View File

@ -7,6 +7,7 @@
<title>{{ config('app.name', 'Laravel') }}</title>
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
<style>
body { font-family: 'Nunito', sans-serif; }
.gradient {
background: rgb(108,99,255);
background: linear-gradient(90deg, rgba(108,99,255,1) 0%, rgba(0,212,255,1) 100%);

View File

@ -17,6 +17,7 @@
data-remove="{{ route('pages.destroy', ['page' => 'replace_me']) }}"
data-csrf="{{ csrf_token() }}"
data-checkword="{{ $checkword }}"
data-settings="{{ $settings }}"
>
</div>
</div>

View File

@ -1,7 +1,7 @@
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('First connection') }}
{{ __('Première connexion') }}
</h2>
</x-slot>

View File

@ -0,0 +1,96 @@
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Settings') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<!-- Session Status -->
<x-auth-session-status class="mb-4" :status="session('status')" />
<!-- Validation Errors -->
<x-auth-validation-errors class="mb-4" :errors="$errors" />
<div class="p-6 bg-white border-b border-gray-200">
<form action="{{ route('user.storeSettings') }}" method="post">
@csrf
<div class="md:flex mb-6">
<div class="md:w-1/3">
<label class="block text-gray-600 font-bold md:text-left mb-3 md:mb-0 pr-4" for="text_color">
{{ __('Text color:') }}
</label>
</div>
<div class="md:w-2/3">
<input class="form-input block w-full focus:bg-white" id="text_color" name="text_color" type="color" value="{{ $settings['text_color'] }}">
</div>
</div>
<div class="md:flex mb-6">
<div class="md:w-1/3">
<label class="block text-gray-600 font-bold md:text-left mb-3 md:mb-0 pr-4" for="background_color">
{{ __('Background color:') }}
</label>
</div>
<div class="md:w-2/3">
<input class="form-input block w-full focus:bg-white" id="background_color" name="background_color" type="color" value="{{ $settings['background_color'] }}">
</div>
</div>
<div class="md:flex mb-6">
<div class="md:w-1/3">
<label class="block text-gray-600 font-bold md:text-left mb-3 md:mb-0 pr-4" for="font">
{{ __('Font:') }}
</label>
</div>
<div class="md:w-2/3">
<select class="form-select block w-full focus:bg-white" id="font" name="font">
<option value="Arial" {{ $settings['font'] === 'Arial' ? 'selected' : '' }}>Arial</option>
<option value="Pacifico" {{ $settings['font'] === 'Pacifico' ? 'selected' : '' }}>Pacifico</option>
</select>
</div>
</div>
<div class="md:flex mb-6">
<div class="md:w-1/3">
<label class="block text-gray-600 font-bold md:text-left mb-3 md:mb-0 pr-4" for="font_size">
{{ __('Font size:') }}
</label>
</div>
<div class="md:w-2/3">
<input class="form-input block w-full focus:bg-white" id="font_size" name="font_size" type="range" min="12" max="18" step="1" value="{{ $settings['font_size'] }}" oninput="this.nextElementSibling.value = this.value">
<output>{{ $settings['font_size'] }}</output>
</div>
</div>
<div class="md:flex mb-6">
<div class="md:w-1/3">
<label class="block text-gray-600 font-bold md:text-left mb-3 md:mb-0 pr-4" for="line_spacing">
{{ __('Line spacing:') }}
</label>
</div>
<div class="md:w-2/3">
<input class="form-input block w-full focus:bg-white" id="line_spacing" name="line_spacing" type="range" min="1" max="3" step="0.1" value="{{ $settings['line_spacing'] }}" oninput="this.nextElementSibling.value = this.value">
<output>{{ $settings['line_spacing'] }}</output>
</div>
</div>
<div class="md:flex md:items-center">
<div class="md:w-1/3"></div>
<div class="md:w-2/3">
<button class="shadow bg-yellow-700 hover:bg-yellow-500 focus:shadow-outline focus:outline-none text-white font-bold py-2 px-4 rounded" type="submit">
{{ __('Save preference') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</x-app-layout>

View File

@ -27,6 +27,8 @@ Route::resource('pages', PageController::class)
Route::get('/first', [UserController::class, 'first'])->middleware(['auth', 'auth.passphrase'])->name('user.first');
Route::post('/first', [UserController::class, 'storeFirst'])->middleware(['auth', 'auth.passphrase'])->name('user.storeFirst');
Route::get('/settings', [UserController::class, 'settings'])->middleware(['auth'])->name('user.settings');
Route::post('/settings', [UserController::class, 'storeSettings'])->middleware(['auth'])->name('user.storeSettings');
Route::get('/dashboard', function () {
return redirect(\route('pages.index'));