diff --git a/app/Clients/ZonneplanPriceClient.php b/app/Clients/ZonneplanPriceClient.php index 11a959b..9e9d888 100644 --- a/app/Clients/ZonneplanPriceClient.php +++ b/app/Clients/ZonneplanPriceClient.php @@ -3,10 +3,12 @@ namespace App\Clients; use App\Contracts\PriceClient; +use Carbon\Carbon; use Exception; use Illuminate\Http\Client\Factory; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log; +use Override; use Throwable; class ZonneplanPriceClient implements PriceClient @@ -25,14 +27,31 @@ class ZonneplanPriceClient implements PriceClient return collect($this->get('/energy-prices/gas/upcoming')); } - /** @return array> */ - private function get(string $path): array + #[Override] + public function getElectricityPricesForDate(Carbon $date): Collection + { + return collect($this->get('/energy-prices/electricity/upcoming', ['date' => $date->format('Y-m-d')])); + } + + #[Override] + public function getGasPricesForDate(Carbon $date): Collection + { + return collect($this->get('/energy-prices/gas/upcoming', ['date' => $date->format('Y-m-d')])); + } + + /** + * @property array $params + * + * @return array> + */ + private function get(string $path, array $params = []): array { try { $response = $this->http ->baseUrl(config('api.baseurl')) ->withQueryParameters([ 'secret' => config('api.key'), + ...$params, ]) ->timeout(10) ->retry(2, 100) diff --git a/app/Contracts/PriceClient.php b/app/Contracts/PriceClient.php index 12f4fd2..391d70c 100644 --- a/app/Contracts/PriceClient.php +++ b/app/Contracts/PriceClient.php @@ -2,6 +2,7 @@ namespace App\Contracts; +use Carbon\Carbon; use Illuminate\Support\Collection; interface PriceClient @@ -9,4 +10,8 @@ interface PriceClient public function getElectricityPrices(): Collection; public function getGasPrices(): Collection; + + public function getElectricityPricesForDate(Carbon $date): Collection; + + public function getGasPricesForDate(Carbon $date): Collection; } diff --git a/app/Contracts/PriceRepository.php b/app/Contracts/PriceRepository.php index 287673a..27b7eba 100644 --- a/app/Contracts/PriceRepository.php +++ b/app/Contracts/PriceRepository.php @@ -2,6 +2,7 @@ namespace App\Contracts; +use Carbon\Carbon; use Illuminate\Support\Collection; interface PriceRepository @@ -9,4 +10,8 @@ interface PriceRepository public function retrieveElectricity(): Collection; public function retrieveGas(): Collection; + + public function retrieveElectricityForDate(Carbon $date): Collection; + + public function retrieveGasForDate(Carbon $date): Collection; } diff --git a/app/Features/Dashboard/Data/ElectricityData.php b/app/Data/ElectricityData.php similarity index 94% rename from app/Features/Dashboard/Data/ElectricityData.php rename to app/Data/ElectricityData.php index e81dc75..3386715 100644 --- a/app/Features/Dashboard/Data/ElectricityData.php +++ b/app/Data/ElectricityData.php @@ -1,6 +1,6 @@ getDashboardData(); } diff --git a/app/Features/Dashboard/Data/DashboardData.php b/app/Features/Dashboard/Data/DashboardData.php index 603594e..e49f53b 100644 --- a/app/Features/Dashboard/Data/DashboardData.php +++ b/app/Features/Dashboard/Data/DashboardData.php @@ -2,6 +2,8 @@ namespace App\Features\Dashboard\Data; +use App\Data\ElectricityData; +use App\Data\GasData; use Spatie\LaravelData\Data; class DashboardData extends Data diff --git a/app/Features/History/Controllers/HistoryController.php b/app/Features/History/Controllers/HistoryController.php new file mode 100644 index 0000000..598d1bb --- /dev/null +++ b/app/Features/History/Controllers/HistoryController.php @@ -0,0 +1,23 @@ +date) { + $date = $request->date; + } + + return $historyService->getHistoryData($date); + } +} diff --git a/app/Features/History/Data/HistoryData.php b/app/Features/History/Data/HistoryData.php new file mode 100644 index 0000000..9cd7c04 --- /dev/null +++ b/app/Features/History/Data/HistoryData.php @@ -0,0 +1,20 @@ + $electricity + * @property Collection $gas + */ + public function __construct( + public Collection $electricity, + public Collection $gas, + ) {} +} diff --git a/app/Features/History/Requests/HistoryRequest.php b/app/Features/History/Requests/HistoryRequest.php new file mode 100644 index 0000000..a269f11 --- /dev/null +++ b/app/Features/History/Requests/HistoryRequest.php @@ -0,0 +1,13 @@ +repository->retrieveElectricityForDate($date)); + $gas = GasData::collect($this->repository->retrieveGasForDate($date)); + + return new HistoryData($electricity, $gas); + } +} diff --git a/app/Providers/TypeScriptTransformerServiceProvider.php b/app/Providers/TypeScriptTransformerServiceProvider.php index ed2fd52..829cd90 100644 --- a/app/Providers/TypeScriptTransformerServiceProvider.php +++ b/app/Providers/TypeScriptTransformerServiceProvider.php @@ -3,6 +3,7 @@ namespace App\Providers; use Carbon\Carbon; +use Illuminate\Support\Collection; use Spatie\LaravelTypeScriptTransformer\LaravelData\Transformers\DataClassTransformer; use Spatie\LaravelTypeScriptTransformer\TypeScriptTransformerApplicationServiceProvider as BaseTypeScriptTransformerServiceProvider; use Spatie\TypeScriptTransformer\Formatters\PrettierFormatter; @@ -22,6 +23,7 @@ class TypeScriptTransformerServiceProvider extends BaseTypeScriptTransformerServ ->transformDirectories(app_path()) ->writer(new GlobalNamespaceWriter('generated.d.ts')) ->replaceType(Carbon::class, 'string') + ->replaceType(Collection::class, 'array') ->formatter(PrettierFormatter::class); } } diff --git a/app/Repositories/ZonneplanPriceRepository.php b/app/Repositories/ZonneplanPriceRepository.php index ce33adb..98aff5f 100644 --- a/app/Repositories/ZonneplanPriceRepository.php +++ b/app/Repositories/ZonneplanPriceRepository.php @@ -4,8 +4,9 @@ namespace App\Repositories; use App\Contracts\PriceClient; use App\Contracts\PriceRepository as ContractsPriceRepository; -use App\Features\Dashboard\Data\ElectricityData; -use App\Features\Dashboard\Data\GasData; +use App\Data\ElectricityData; +use App\Data\GasData; +use Carbon\Carbon; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Cache; use Override; @@ -19,16 +20,32 @@ class ZonneplanPriceRepository implements ContractsPriceRepository #[Override] public function retrieveElectricity(): Collection { - $data = Cache::remember('electricity', 3600, fn () => $this->client->getElectricityPrices()->toArray()); + $data = Cache::remember('electricity:upcomming', 3600, fn () => $this->client->getElectricityPrices()->toArray()); - return collect(ElectricityData::collect($data)); + return ElectricityData::collect($data, Collection::class); } #[Override] public function retrieveGas(): Collection { - $data = Cache::remember('gas', 3600, fn () => $this->client->getGasPrices()->toArray()); + $data = Cache::remember('gas:upcomming', 3600, fn () => $this->client->getGasPrices()->toArray()); - return collect(GasData::collect($data)); + return GasData::collect($data, Collection::class); + } + + #[Override] + public function retrieveElectricityForDate(Carbon $date): Collection + { + $data = Cache::remember('electricity:'.$date->format('Y-m-d'), 3600, fn () => $this->client->getElectricityPricesForDate($date)->toArray()); + + return GasData::collect($data, Collection::class); + } + + #[Override] + public function retrieveGasForDate(Carbon $date): Collection + { + $data = Cache::remember('gas:'.$date->format('Y-m-d'), 3600, fn () => $this->client->getGasPricesForDate($date)->toArray()); + + return GasData::collect($data, Collection::class); } } diff --git a/config/data.php b/config/data.php index ef02e43..c081810 100644 --- a/config/data.php +++ b/config/data.php @@ -25,7 +25,7 @@ return [ * and will serialize dates using the first format from the array. */ 'date_format' => [ - 'Y-m-d\TH:i:s.u\Z', 'Y-m-d\TH:i:s.uP', 'Y-m-d H:i:s', 'U', + 'Y-m-d\TH:i:s.u\Z', 'Y-m-d\TH:i:s.uP', 'Y-m-d H:i:s', 'U', 'Y-m-d', ], /* diff --git a/eslint.config.js b/eslint.config.js index 3aa406d..a0a7b91 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,5 +1,8 @@ import stylistic from '@stylistic/eslint-plugin'; -import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'; +import { + defineConfigWithVueTs, + vueTsConfigs, +} from '@vue/eslint-config-typescript'; import prettier from 'eslint-config-prettier/flat'; import importPlugin from 'eslint-plugin-import'; import vue from 'eslint-plugin-vue'; @@ -48,9 +51,16 @@ export default defineConfigWithVueTs( }, ], 'import/order': [ - 'error', + 'off', { - groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'], + groups: [ + 'builtin', + 'external', + 'internal', + 'parent', + 'sibling', + 'index', + ], alphabetize: { order: 'asc', caseInsensitive: true, @@ -68,7 +78,11 @@ export default defineConfigWithVueTs( '@stylistic': stylistic, }, rules: { - '@stylistic/brace-style': ['error', '1tbs', { allowSingleLine: false }], + '@stylistic/brace-style': [ + 'error', + '1tbs', + { allowSingleLine: false }, + ], '@stylistic/padding-line-between-statements': [ 'error', ...paddingAroundControl, @@ -96,7 +110,11 @@ export default defineConfigWithVueTs( }, rules: { curly: ['error', 'all'], - '@stylistic/brace-style': ['error', '1tbs', { allowSingleLine: false }], + '@stylistic/brace-style': [ + 'error', + '1tbs', + { allowSingleLine: false }, + ], }, }, ); diff --git a/resources/js/features/history/pages/Index.vue b/resources/js/features/history/pages/Index.vue index ce1e62b..0e2270e 100644 --- a/resources/js/features/history/pages/Index.vue +++ b/resources/js/features/history/pages/Index.vue @@ -1,5 +1,23 @@ - + diff --git a/resources/js/features/history/viewmodels/HistoryViewModel.ts b/resources/js/features/history/viewmodels/HistoryViewModel.ts index e69de29..6c3ee75 100644 --- a/resources/js/features/history/viewmodels/HistoryViewModel.ts +++ b/resources/js/features/history/viewmodels/HistoryViewModel.ts @@ -0,0 +1,26 @@ +import { create } from 'axios'; +import { ref } from 'vue'; +import HistoryData = App.Features.History.Data.HistoryData; + +export default function useHistoryViewModel() { + const isLoading = ref(false); + const historyData = ref(); + + function getHistoryData(date: string) { + isLoading.value = true; + + const client = create(); + client + .get('/api/history', { + params: { + date, + }, + }) + .then((res) => { + historyData.value = res.data; + }) + .finally(() => (isLoading.value = false)); + } + + return { isLoading, historyData, getHistoryData }; +} diff --git a/resources/js/generated/generated.d.ts b/resources/js/generated/generated.d.ts index 423d0ed..bf19586 100644 --- a/resources/js/generated/generated.d.ts +++ b/resources/js/generated/generated.d.ts @@ -1,38 +1,53 @@ declare namespace App { + namespace Data { + export type ElectricityData = { + startDate: string; + endDate: string; + period: string; + marketPrice: number | null; + totalPriceTaxIncluded: number | null; + priceInclHandlingVat: number | null; + priceTaxWithVat: number | null; + pricingProfile: string | null; + carbonFootprintInGram: number | null; + sustainabilityScore: number | null; + startDateDatetime: string; + }; + export type GasData = { + startDate: string; + endDate: string; + period: string; + marketPrice: number; + totalPriceTaxIncluded: number; + priceInclHandlingVat: number; + priceTaxWithVat: number; + startDateDatetime: string; + }; + } namespace Features { namespace Dashboard { namespace Data { export type DashboardData = { - electricity: App.Features.Dashboard.Data.ElectricityData; - electricityCheapest: App.Features.Dashboard.Data.ElectricityData | null; - electricityDurable: App.Features.Dashboard.Data.ElectricityData | null; - electricityPriciest: App.Features.Dashboard.Data.ElectricityData | null; - gas: App.Features.Dashboard.Data.GasData; - gasCheapest: App.Features.Dashboard.Data.GasData | null; - gasPriciest: App.Features.Dashboard.Data.GasData | null; + electricity: App.Data.ElectricityData; + electricityCheapest: App.Data.ElectricityData | null; + electricityDurable: App.Data.ElectricityData | null; + electricityPriciest: App.Data.ElectricityData | null; + gas: App.Data.GasData; + gasCheapest: App.Data.GasData | null; + gasPriciest: App.Data.GasData | null; }; - export type ElectricityData = { - startDate: string; - endDate: string; - period: string; - marketPrice: number | null; - totalPriceTaxIncluded: number | null; - priceInclHandlingVat: number | null; - priceTaxWithVat: number | null; - pricingProfile: string | null; - carbonFootprintInGram: number | null; - sustainabilityScore: number | null; - startDateDatetime: string; + } + } + namespace History { + namespace Data { + export type HistoryData = { + electricity: Array; + gas: Array; }; - export type GasData = { - startDate: string; - endDate: string; - period: string; - marketPrice: number; - totalPriceTaxIncluded: number; - priceInclHandlingVat: number; - priceTaxWithVat: number; - startDateDatetime: string; + } + namespace Requests { + export type HistoryRequest = { + date: string | null; }; } } diff --git a/resources/js/generated/typescript-transformer-manifest.json b/resources/js/generated/typescript-transformer-manifest.json index 3bb79b1..d75a1cd 100644 --- a/resources/js/generated/typescript-transformer-manifest.json +++ b/resources/js/generated/typescript-transformer-manifest.json @@ -1,3 +1,3 @@ { - "generated.d.ts": "f593095f6f419a96a4c39c2b93719f9a" + "generated.d.ts": "7ca8a9c7f0ae5e5498bdee87bb2f005d" } \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index 8390db6..b4f8960 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,8 +1,10 @@ group(function () { Route::get('/energy-prices', [DashboardController::class, 'index'])->name('dashboard.index'); + Route::get('/history', [HistoryController::class, 'index'])->name('history.index'); });