Day hours are timezone-adjusted and taken from adjacent days as needed
This commit is contained in:
parent
aaf351d328
commit
b2e2770e91
@ -17,6 +17,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@date-fns/tz": "^1.2.0",
|
||||
"@date-fns/utc": "^2.1.0",
|
||||
"@lifetracker/db": "workspace:*",
|
||||
"@lifetracker/shared": "workspace:^",
|
||||
"@lifetracker/trpc": "workspace:^",
|
||||
|
||||
@ -10,6 +10,7 @@ import { Command } from "@commander-js/extra-typings";
|
||||
import { getBorderCharacters, table } from "table";
|
||||
import { format } from "date-fns";
|
||||
import { TZDate } from "@date-fns/tz";
|
||||
import { utc } from "@date-fns/utc";
|
||||
import { getHourFromTime, getTimeFromHour } from "@lifetracker/shared/utils/hours";
|
||||
|
||||
function moodToStars(mood: number) {
|
||||
@ -41,13 +42,14 @@ export const daysCmd = new Command()
|
||||
} else {
|
||||
|
||||
const moodStr = moodToStars(day.mood);
|
||||
const dateStr = format(day.date, "EEEE, MMMM do");
|
||||
const dateStr = format(day.date, "EEEE, MMMM do", { in: utc });
|
||||
const data: string[][] = [[dateStr, '', moodStr], [day.comment ?? "No comment", '', ''],
|
||||
["Time", "Category", "Comment"]
|
||||
];
|
||||
|
||||
day.hours.forEach((h) => {
|
||||
data.push([getHourFromTime(h.time), h.categoryName ?? "--", h.comment ?? ""]);
|
||||
day.hours.forEach((h, i) => {
|
||||
data.push([getHourFromTime(h.time),
|
||||
h.categoryName ?? "--", h.comment ?? ""]);
|
||||
})
|
||||
|
||||
console.log(table(data, {
|
||||
|
||||
@ -2,7 +2,6 @@ import { notFound } from "next/navigation";
|
||||
import { api } from "@/server/api/client";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import DayView from "@/components/dashboard/days/DayView";
|
||||
import LoadingSpinner from "@/components/ui/spinner";
|
||||
|
||||
export default async function DayPage({
|
||||
params,
|
||||
@ -10,9 +9,10 @@ export default async function DayPage({
|
||||
params: { dateQuery: string };
|
||||
}) {
|
||||
let day;
|
||||
|
||||
try {
|
||||
day = await api.days.get({ dateQuery: params.dateQuery });
|
||||
day = await api.days.get({
|
||||
dateQuery: params.dateQuery,
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof TRPCError) {
|
||||
if (e.code == "NOT_FOUND") {
|
||||
@ -23,11 +23,8 @@ export default async function DayPage({
|
||||
}
|
||||
|
||||
return (
|
||||
params.dateQuery === undefined ?
|
||||
<LoadingSpinner />
|
||||
:
|
||||
<DayView
|
||||
day={day}
|
||||
/>
|
||||
<DayView
|
||||
day={day}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -5,31 +5,55 @@ import { getServerAuthSession } from "@/server/auth";
|
||||
import { ZDay } from "@lifetracker/shared/types/days";
|
||||
import EditableDayComment from "./EditableDayComment";
|
||||
import { MoodStars } from "./MoodStars";
|
||||
import { format } from "date-fns";
|
||||
|
||||
import { format, addDays } from "date-fns";
|
||||
import { ButtonWithTooltip } from "@/components/ui/button";
|
||||
import { router } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ArrowLeftSquare, ArrowRightSquare } from "lucide-react";
|
||||
import { UTCDate, utc } from "@date-fns/utc";
|
||||
export default async function DayView({
|
||||
day,
|
||||
header,
|
||||
showDivider,
|
||||
showEditorCard = false,
|
||||
}: {
|
||||
day: ZDay;
|
||||
header?: React.ReactNode;
|
||||
showDivider?: boolean;
|
||||
showEditorCard?: boolean;
|
||||
}) {
|
||||
const session = await getServerAuthSession();
|
||||
if (!session) {
|
||||
redirect("/");
|
||||
}
|
||||
|
||||
const prevDay = format(addDays(day.date, -1), "yyyy-MM-dd");
|
||||
const nextDay = format(addDays(day.date, 1), "yyyy-MM-dd");
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
|
||||
<div className="flex justify-between">
|
||||
<span className="text-2xl">
|
||||
{format(day.date, "EEEE, MMMM do")}
|
||||
</span>
|
||||
<div className="flex">
|
||||
<Link
|
||||
href={`/dashboard/day/${prevDay}`}
|
||||
className={cn(
|
||||
"flex-0 items-center rounded-[inherit] px-3 py-2",
|
||||
)}
|
||||
>
|
||||
<div className="flex w-full justify-between">
|
||||
<ArrowLeftSquare size={18} />
|
||||
</div>
|
||||
</Link>
|
||||
<span className="text-2xl flex-1">
|
||||
{format(day.date, "EEEE, MMMM do", { in: utc })}
|
||||
</span>
|
||||
<Link
|
||||
href={`/dashboard/day/${nextDay}`}
|
||||
className={cn(
|
||||
"flex-0 items-center rounded-[inherit] px-3 py-2",
|
||||
)}
|
||||
>
|
||||
<div className="flex w-full justify-between">
|
||||
<ArrowRightSquare size={18} />
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div>
|
||||
<MoodStars
|
||||
day={day}
|
||||
@ -45,7 +69,13 @@ export default async function DayView({
|
||||
|
||||
<Separator />
|
||||
|
||||
|
||||
<ul>
|
||||
{day.hours.map((hour) => (
|
||||
<li key={hour.time}>
|
||||
{hour.time}: {hour.categoryName} {hour.comment}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -41,7 +41,6 @@ export default function EditableDayComment({
|
||||
},
|
||||
{
|
||||
onError: (e) => {
|
||||
console.log(e);
|
||||
toast({
|
||||
description: e.message,
|
||||
variant: "destructive",
|
||||
|
||||
@ -15,7 +15,7 @@ export default async function Header() {
|
||||
return (
|
||||
<header className="sticky left-0 right-0 top-0 z-50 flex h-16 items-center justify-between overflow-x-auto overflow-y-hidden bg-background p-4 shadow">
|
||||
<div className="hidden items-center sm:flex">
|
||||
<Link href={"/dashboard/bookmarks"} className="w-56">
|
||||
<Link href={"/dashboard/day/today"} className="w-56">
|
||||
<HoarderLogo height={20} gap="8px" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@ -35,7 +35,7 @@ export default async function Sidebar() {
|
||||
{
|
||||
name: "Home",
|
||||
icon: <Home size={18} />,
|
||||
path: "/dashboard/today",
|
||||
path: "/dashboard/day/today",
|
||||
},
|
||||
...searchItem,
|
||||
{
|
||||
|
||||
@ -16,7 +16,7 @@ export const settingsSidebarItems: {
|
||||
{
|
||||
name: "Back To App",
|
||||
icon: <ArrowLeft size={18} />,
|
||||
path: "/dashboard/today",
|
||||
path: "/dashboard/day/today",
|
||||
},
|
||||
{
|
||||
name: "User Info",
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
"dependencies": {
|
||||
"@auth/drizzle-adapter": "^1.4.2",
|
||||
"@date-fns/tz": "^1.2.0",
|
||||
"@date-fns/utc": "^2.1.0",
|
||||
"@emoji-mart/data": "^1.1.2",
|
||||
"@emoji-mart/react": "^1.1.1",
|
||||
"@hookform/resolvers": "^3.3.4",
|
||||
|
||||
@ -105,6 +105,5 @@ CREATE UNIQUE INDEX `apiKey_name_userId_unique` ON `apiKey` (`name`,`userId`);--
|
||||
CREATE UNIQUE INDEX `category_userId_code_unique` ON `category` (`userId`,`code`);--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `color_userId_name_unique` ON `color` (`userId`,`name`);--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `day_date_unique` ON `day` (`date`);--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `hour_time_unique` ON `hour` (`time`);--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `hour_dayId_time_unique` ON `hour` (`dayId`,`time`);--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `user_email_unique` ON `user` (`email`);
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "170be9e2-c822-4d3a-a0b1-18c8468f1c5d",
|
||||
"id": "ebffb4c7-5ecf-46d0-93c6-68f8e48a9fc4",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"tables": {
|
||||
"account": {
|
||||
@ -524,13 +524,6 @@
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"hour_time_unique": {
|
||||
"name": "hour_time_unique",
|
||||
"columns": [
|
||||
"time"
|
||||
],
|
||||
"isUnique": true
|
||||
},
|
||||
"hour_dayId_time_unique": {
|
||||
"name": "hour_dayId_time_unique",
|
||||
"columns": [
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "6",
|
||||
"when": 1732706352404,
|
||||
"tag": "0000_exotic_dakota_north",
|
||||
"when": 1732766704666,
|
||||
"tag": "0000_cold_golden_guardian",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
|
||||
@ -21,7 +21,6 @@ function createdAtField() {
|
||||
}
|
||||
|
||||
export function calcInverseColor(hexcode: string): string {
|
||||
console.log(hexcode);
|
||||
const hex = hexcode.replace("#", "");
|
||||
const r = parseInt(hex.substr(0, 2), 16);
|
||||
const g = parseInt(hex.substr(2, 2), 16);
|
||||
@ -148,7 +147,7 @@ export const hours = sqliteTable(
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
comment: text("comment"),
|
||||
time: integer("time").unique(),
|
||||
time: integer("time"),
|
||||
dayId: text("dayId").notNull().references(() => days.id, { onDelete: "cascade" }),
|
||||
categoryId: text("categoryId").references(() => categories.id),
|
||||
},
|
||||
|
||||
@ -3,7 +3,6 @@ import { api } from "../trpc";
|
||||
export function useUpdateUserTimezone(
|
||||
...opts: Parameters<typeof api.users.changeTimezone.useMutation>
|
||||
) {
|
||||
const apiUtils = api.useUtils();
|
||||
return api.users.changeTimezone.useMutation({
|
||||
...opts[0],
|
||||
onSuccess: (res, req, meta) => {
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@date-fns/tz": "^1.2.0",
|
||||
"@date-fns/utc": "^2.1.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"winston": "^3.17.0",
|
||||
"zod": "^3.23.8"
|
||||
|
||||
@ -6,10 +6,10 @@ export const zHourSchema = z.object({
|
||||
dayId: z.string(),
|
||||
date: z.string().optional(),
|
||||
time: z.number(),
|
||||
categoryCode: z.coerce.number().nullable(),
|
||||
categoryId: z.string().nullable(),
|
||||
categoryName: z.string().nullable(),
|
||||
comment: z.string().nullable(),
|
||||
categoryCode: z.coerce.number().nullish(),
|
||||
categoryId: z.string().nullish(),
|
||||
categoryName: z.string().nullish(),
|
||||
comment: z.string().nullish(),
|
||||
});
|
||||
export type ZHour = z.infer<typeof zHourSchema>;
|
||||
|
||||
|
||||
@ -1,13 +1,32 @@
|
||||
import { format } from "date-fns";
|
||||
import { format, addHours } from "date-fns";
|
||||
import { TZDate } from "@date-fns/tz";
|
||||
import { UTCDate, utc } from "@date-fns/utc";
|
||||
|
||||
export function dateFromInput(input: { dateQuery: string, timezone: string }) {
|
||||
let t: TZDate;
|
||||
let t: string;
|
||||
if (input.dateQuery == "today") {
|
||||
t = TZDate.tz(input.timezone);
|
||||
t = new Date();
|
||||
return format(t, "yyyy-MM-dd", { in: input.timezone });
|
||||
}
|
||||
else {
|
||||
t = new TZDate(input.dateQuery, input.timezone);
|
||||
t = new UTCDate(input.dateQuery);
|
||||
return format(t, "yyyy-MM-dd", { in: utc });
|
||||
}
|
||||
return format(t, "yyyy-MM-dd") + "T00:00:00";
|
||||
|
||||
}
|
||||
|
||||
function generateHour(d, t) {
|
||||
const dt: TZDate = addHours(d, t);
|
||||
return {
|
||||
date: format(dt, 'yyyy-MM-dd'),
|
||||
time: parseInt(format(dt, 'H')),
|
||||
};
|
||||
}
|
||||
|
||||
export function hoursListInTimezone(input: { dateQuery: string, timezone: string }) {
|
||||
const dateStr = dateFromInput(input);
|
||||
const d = new TZDate(dateStr, input.timezone);
|
||||
return Array.from({ length: 24 }, (_, t) =>
|
||||
generateHour(d, t)
|
||||
);
|
||||
}
|
||||
@ -27,7 +27,6 @@ async function createCategory(
|
||||
) {
|
||||
|
||||
return ctx.db.transaction(async (trx) => {
|
||||
console.log("Creating a category", input);
|
||||
try {
|
||||
const result = await trx
|
||||
.insert(categories)
|
||||
@ -54,7 +53,6 @@ async function createCategory(
|
||||
};
|
||||
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
if (e instanceof SqliteError) {
|
||||
if (e.code == "SQLITE_CONSTRAINT_UNIQUE") {
|
||||
throw new TRPCError({
|
||||
@ -196,8 +194,6 @@ export const categoriesAppRouter = router({
|
||||
category.parentId = categoryId;
|
||||
}
|
||||
|
||||
console.log(category);
|
||||
|
||||
return category;
|
||||
}),
|
||||
create: authedProcedure
|
||||
|
||||
@ -2,16 +2,17 @@ import { experimental_trpcMiddleware, TRPCError } from "@trpc/server";
|
||||
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
|
||||
import { z } from "zod";
|
||||
|
||||
import { SqliteError } from "@lifetracker/db";
|
||||
import { categories, days, hours, } from "@lifetracker/db/schema";
|
||||
import { db, SqliteError } from "@lifetracker/db";
|
||||
import { categories, days, hours, users } from "@lifetracker/db/schema";
|
||||
import {
|
||||
zDaySchema, ZDay
|
||||
} from "@lifetracker/shared/types/days";
|
||||
import type { Context } from "../index";
|
||||
import { authedProcedure, router } from "../index";
|
||||
import { dateFromInput } from "@lifetracker/shared/utils/days";
|
||||
import { format } from "date-fns";
|
||||
import { dateFromInput, hoursListInTimezone } from "@lifetracker/shared/utils/days";
|
||||
import { closestIndexTo, format } from "date-fns";
|
||||
import { TZDate } from "@date-fns/tz";
|
||||
import { hoursAppRouter } from "./hours";
|
||||
|
||||
async function createDay(date: string, ctx: Context) {
|
||||
return await ctx.db.transaction(async (trx) => {
|
||||
@ -30,21 +31,8 @@ async function createDay(date: string, ctx: Context) {
|
||||
comment: days.comment,
|
||||
});
|
||||
|
||||
const dayId = dayRes[0].id;
|
||||
|
||||
// Generate 24 "hour" objects
|
||||
const hoursData = Array.from({ length: 24 }, (_, hour) => ({
|
||||
userId: ctx.user!.id,
|
||||
dayId: dayId,
|
||||
time: hour
|
||||
}));
|
||||
|
||||
// Insert the "hour" objects
|
||||
await trx.insert(hours).values(hoursData);
|
||||
|
||||
return dayRes;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
if (e instanceof SqliteError) {
|
||||
if (e.code == "SQLITE_CONSTRAINT_UNIQUE") {
|
||||
throw new TRPCError({
|
||||
@ -61,6 +49,59 @@ async function createDay(date: string, ctx: Context) {
|
||||
});
|
||||
}
|
||||
|
||||
async function createHour(day, time, ctx,) {
|
||||
const newHour = (await ctx.db.insert(hours).values({
|
||||
dayId: day.id,
|
||||
time: time,
|
||||
userId: ctx.user!.id,
|
||||
}).returning());
|
||||
console.log(newHour);
|
||||
return newHour[0];
|
||||
}
|
||||
|
||||
async function getTimezone(ctx: Context) {
|
||||
const dbTimezone = await ctx.db.select({
|
||||
timezone: users.timezone
|
||||
}).from(users).where(eq(users.id, ctx.user!.id));
|
||||
|
||||
return dbTimezone[0].timezone as string;
|
||||
}
|
||||
|
||||
async function getDay(input: { dateQuery: string }, ctx: Context, date: string) {
|
||||
const dayRes = await ctx.db.select({
|
||||
id: days.id,
|
||||
date: days.date,
|
||||
mood: days.mood,
|
||||
comment: days.comment,
|
||||
})
|
||||
.from(days)
|
||||
.where(eq(days.date, date));
|
||||
|
||||
const day = dayRes.length == 0
|
||||
? (await createDay(date, ctx))[0]
|
||||
: (dayRes[0]);
|
||||
|
||||
const dayHours = await Promise.all(
|
||||
Array.from({ length: 24 }).map(async function (_, i) {
|
||||
const existing = await ctx.db.select({
|
||||
dayId: hours.dayId,
|
||||
time: hours.time,
|
||||
userId: hours.userId,
|
||||
}).from(hours)
|
||||
.where(and(
|
||||
eq(hours.userId, ctx.user!.id),
|
||||
eq(hours.dayId, day.id),
|
||||
eq(hours.time, i)
|
||||
))
|
||||
return existing.length == 0 ? createHour(day, i, ctx) : existing[0];
|
||||
}));
|
||||
|
||||
return {
|
||||
hours: dayHours,
|
||||
...day
|
||||
}
|
||||
}
|
||||
|
||||
export const daysAppRouter = router({
|
||||
get: authedProcedure
|
||||
.input(z.object({
|
||||
@ -68,47 +109,48 @@ export const daysAppRouter = router({
|
||||
}))
|
||||
.output(zDaySchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const date = dateFromInput({ timezone: ctx.user.timezone, ...input });
|
||||
console.log(ctx.user.timezone);
|
||||
// Fetch the day data
|
||||
let dayRes;
|
||||
dayRes = await ctx.db
|
||||
.select({
|
||||
id: days.id,
|
||||
date: days.date,
|
||||
mood: days.mood,
|
||||
comment: days.comment,
|
||||
})
|
||||
.from(days)
|
||||
.where(eq(days.date, date));
|
||||
|
||||
if (dayRes.length === 0) {
|
||||
dayRes = await createDay(date, ctx);
|
||||
}
|
||||
const timezone = await getTimezone(ctx);
|
||||
const date = dateFromInput({
|
||||
dateQuery: input.dateQuery,
|
||||
timezone: timezone
|
||||
});
|
||||
|
||||
const day = dayRes[0];
|
||||
const allHours = hoursListInTimezone({
|
||||
timezone,
|
||||
...input
|
||||
});
|
||||
|
||||
// Fetch the hours data for the corresponding dayId
|
||||
const hoursRes = await ctx.db
|
||||
.select({
|
||||
id: hours.id,
|
||||
dayId: hours.dayId,
|
||||
time: hours.time,
|
||||
categoryId: hours.categoryId,
|
||||
categoryCode: categories.code,
|
||||
categoryName: categories.name,
|
||||
comment: hours.comment,
|
||||
})
|
||||
.from(hours)
|
||||
.where(eq(hours.dayId, day.id))
|
||||
.leftJoin(categories, eq(categories.id, hours.categoryId))
|
||||
const dayRange = [...new Set(allHours.map(({ date: date, time: _time }) => date))];
|
||||
|
||||
// Combine the day and hours data
|
||||
const result = {
|
||||
...day,
|
||||
hours: hoursRes,
|
||||
const allDayIds = await Promise.all(dayRange.map(async function (date) {
|
||||
const dayObj = await getDay(input, ctx, date);
|
||||
return {
|
||||
id: dayObj.id,
|
||||
date: dayObj.date
|
||||
}
|
||||
}));
|
||||
|
||||
const dayHours = await Promise.all(allHours.map(async function ({ date, time }) {
|
||||
const dayId = allDayIds.find((_value: { id, date }) => date == date)!.id;
|
||||
|
||||
|
||||
const hourMatch = await ctx.db.select().from(hours)
|
||||
.where(and(
|
||||
eq(hours.time, time),
|
||||
eq(hours.dayId, dayId)));
|
||||
|
||||
// console.log("Search values:: ", `d: ${date}, t: ${time}, dayId: ${dayId}`)
|
||||
// console.log("hourMatch", hourMatch[0]);
|
||||
|
||||
return hourMatch;
|
||||
}));
|
||||
|
||||
return {
|
||||
...await getDay(input, ctx, date),
|
||||
hours: dayHours.flat(),
|
||||
};
|
||||
return result;
|
||||
|
||||
}),
|
||||
update: authedProcedure
|
||||
.input(
|
||||
|
||||
@ -22,7 +22,6 @@ export const hoursAppRouter = router({
|
||||
.output(zHourSchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const date = dateFromInput(input);
|
||||
console.log(input);
|
||||
const hourRes = await ctx.db
|
||||
.select({
|
||||
id: hours.id,
|
||||
@ -37,8 +36,6 @@ export const hoursAppRouter = router({
|
||||
.leftJoin(days, eq(days.id, hours.dayId)) // Ensure days table is joined first
|
||||
.leftJoin(categories, eq(categories.id, hours.categoryId))
|
||||
.where(and(eq(hours.time, input.time), eq(days.date, date))) // Use correct alias for days table
|
||||
|
||||
console.log(hourRes);
|
||||
return {
|
||||
date: format(date, "yyyy-MM-dd"),
|
||||
...hourRes[0]
|
||||
|
||||
@ -198,8 +198,6 @@ export const usersAppRouter = router({
|
||||
timezone: input.newTimezone,
|
||||
})
|
||||
.where(eq(users.id, ctx.user.id));
|
||||
|
||||
console.log("changeTimezone input", input.newTimezone);
|
||||
return input.newTimezone;
|
||||
}),
|
||||
});
|
||||
14
pnpm-lock.yaml
generated
14
pnpm-lock.yaml
generated
@ -23,6 +23,9 @@ importers:
|
||||
'@date-fns/tz':
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0
|
||||
'@date-fns/utc':
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
'@lifetracker/db':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/db
|
||||
@ -148,6 +151,9 @@ importers:
|
||||
'@date-fns/tz':
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0
|
||||
'@date-fns/utc':
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
'@emoji-mart/data':
|
||||
specifier: ^1.1.2
|
||||
version: 1.2.1
|
||||
@ -478,6 +484,9 @@ importers:
|
||||
'@date-fns/tz':
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0
|
||||
'@date-fns/utc':
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
date-fns:
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.0
|
||||
@ -1935,6 +1944,9 @@ packages:
|
||||
'@date-fns/tz@1.2.0':
|
||||
resolution: {integrity: sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg==}
|
||||
|
||||
'@date-fns/utc@2.1.0':
|
||||
resolution: {integrity: sha512-176grgAgU2U303rD2/vcOmNg0kGPbhzckuH1TEP2al7n0AQipZIy9P15usd2TKQCG1g+E1jX/ZVQSzs4sUDwgA==}
|
||||
|
||||
'@discoveryjs/json-ext@0.5.7':
|
||||
resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
@ -14384,6 +14396,8 @@ snapshots:
|
||||
|
||||
'@date-fns/tz@1.2.0': {}
|
||||
|
||||
'@date-fns/utc@2.1.0': {}
|
||||
|
||||
'@discoveryjs/json-ext@0.5.7': {}
|
||||
|
||||
'@docsearch/css@3.6.2': {}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user