Fixed dates

This commit is contained in:
Simon Pocrnjič 2026-04-14 17:41:05 +02:00
parent 821985469e
commit 7881508a7b
6 changed files with 52 additions and 23 deletions

View File

@ -80,14 +80,14 @@ public function __invoke(SmsService $sms): Response
->map(fn ($i) => now()->subDays(6 - $i)->format('Y-m-d'));
$fieldJobTrendRaw = FieldJob::whereBetween(DB::raw('COALESCE(assigned_at, created_at)'), [$start, $end])
->selectRaw('DATE(COALESCE(assigned_at, created_at)) as d, COUNT(*) as c')
->selectRaw("DATE(COALESCE(assigned_at, created_at) AT TIME ZONE 'Europe/Ljubljana') as d, COUNT(*) as c")
->groupBy('d')
->pluck('c', 'd');
// Completed field jobs last 7 days
$fieldJobCompletedRaw = FieldJob::whereNotNull('completed_at')
->whereBetween('completed_at', [$start, $end])
->selectRaw('DATE(completed_at) as d, COUNT(*) as c')
->selectRaw("DATE(completed_at AT TIME ZONE 'Europe/Ljubljana') as d, COUNT(*) as c")
->groupBy('d')
->pluck('c', 'd');

View File

@ -0,0 +1,21 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
public function up(): void
{
DB::statement('ALTER TABLE field_jobs ALTER COLUMN assigned_at TYPE timestamp USING assigned_at::timestamp');
DB::statement('ALTER TABLE field_jobs ALTER COLUMN completed_at TYPE timestamp USING completed_at::timestamp');
DB::statement('ALTER TABLE field_jobs ALTER COLUMN cancelled_at TYPE timestamp USING cancelled_at::timestamp');
}
public function down(): void
{
DB::statement('ALTER TABLE field_jobs ALTER COLUMN assigned_at TYPE date USING assigned_at::date');
DB::statement('ALTER TABLE field_jobs ALTER COLUMN completed_at TYPE date USING completed_at::date');
DB::statement('ALTER TABLE field_jobs ALTER COLUMN cancelled_at TYPE date USING cancelled_at::date');
}
};

View File

@ -32,7 +32,7 @@ const chartData = computed(() => {
}
return props.trends.labels.map((label, i) => ({
date: new Date(label),
date: new Date(label + "T00:00:00"),
dateLabel: label,
completed: props.trends.field_jobs_completed[i] || 0,
assigned: props.trends.field_jobs[i] || 0,
@ -140,7 +140,7 @@ const crosshairLabelFormatter = (value) => {
type="x"
:tick-line="false"
:grid-line="false"
:num-ticks="7"
:tick-values="chartData.map((d) => d.date)"
:tick-format="
(d) => {
const date = new Date(d);

View File

@ -263,10 +263,14 @@ function formatDate(value) {
if (isNaN(d)) {
return value;
}
const dd = String(d.getDate()).padStart(2, "0");
const mm = String(d.getMonth() + 1).padStart(2, "0");
const yyyy = d.getFullYear();
return `${dd}.${mm}.${yyyy}`;
const parts = new Intl.DateTimeFormat("en-GB", {
timeZone: "Europe/Ljubljana",
day: "2-digit",
month: "2-digit",
year: "numeric",
}).formatToParts(d);
const map = Object.fromEntries(parts.map((p) => [p.type, p.value]));
return `${map.day}.${map.month}.${map.year}`;
}
function formatCurrencyEUR(value) {

View File

@ -30,6 +30,7 @@ import {
Phone,
Wallet,
} from "lucide-vue-next";
import { fmtDateDMY } from "@/Utilities/functions";
const props = defineProps({
jobs: { type: Object, required: true },
@ -89,17 +90,16 @@ function clearSearch() {
function formatDateDMY(d) {
if (!d) return "-";
if (/^\d{4}-\d{2}-\d{2}/.test(d)) {
const [y, m, rest] = d.split("-");
const day = (rest || "").slice(0, 2) || "01";
return `${day}.${m}.${y}`;
}
const dt = new Date(d);
if (Number.isNaN(dt.getTime())) return String(d);
const dd = String(dt.getDate()).padStart(2, "0");
const mm = String(dt.getMonth() + 1).padStart(2, "0");
const yyyy = dt.getFullYear();
return `${dd}.${mm}.${yyyy}`;
const parts = new Intl.DateTimeFormat("en-GB", {
timeZone: "Europe/Ljubljana",
day: "2-digit",
month: "2-digit",
year: "numeric",
}).formatToParts(dt);
const map = Object.fromEntries(parts.map((p) => [p.type, p.value]));
return `${map.day}.${map.month}.${map.year}`;
}
function formatAmount(val) {
@ -412,7 +412,7 @@ function changePage(url) {
Dodeljeno
</p>
<p class="font-semibold text-gray-900 dark:text-gray-100">
{{ formatDateDMY(job.assigned_at) }}
{{ fmtDateDMY(job.assigned_at) }}
</p>
</div>
</div>
@ -430,7 +430,7 @@ function changePage(url) {
Zadnja aktivnost
</p>
<p class="font-semibold text-green-700 dark:text-green-400">
{{ formatDateDMY(job.last_activity) || "—" }}
{{ fmtDateDMY(job.last_activity) || "—" }}
</p>
</div>
</div>

View File

@ -33,8 +33,12 @@ export function fmtDateDMY(value) {
if (!value) return "-";
const d = new Date(value);
if (isNaN(d)) return "-";
const dd = String(d.getDate()).padStart(2, "0");
const mm = String(d.getMonth() + 1).padStart(2, "0");
const yyyy = d.getFullYear();
return `${dd}.${mm}.${yyyy}`;
const parts = new Intl.DateTimeFormat("en-GB", {
timeZone: "Europe/Ljubljana",
day: "2-digit",
month: "2-digit",
year: "numeric",
}).formatToParts(d);
const map = Object.fromEntries(parts.map((p) => [p.type, p.value]));
return `${map.day}.${map.month}.${map.year}`;
}