diff --git a/package-lock.json b/package-lock.json index 770a6bf..848f974 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,13 +36,15 @@ "clsx": "^2.0.1", "cmdk": "^0.2.0", "crypto-js": "^4.2.0", + "date-fns": "^3.6.0", "firebase": "^10.12.2", "firebase-admin": "^12.1.1", "input-otp": "^1.2.4", - "next": "14.0.4", + "next": "14.1.1", "next-pwa": "^5.6.0", "next-themes": "^0.2.1", "react": "^18", + "react-day-picker": "^8.10.1", "react-dom": "^18", "react-hook-form": "^7.49.3", "recharts": "^2.10.4", @@ -3196,9 +3198,9 @@ } }, "node_modules/@next/env": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.0.4.tgz", - "integrity": "sha512-irQnbMLbUNQpP1wcE5NstJtbuA/69kRfzBrpAD7Gsn8zm/CY6YQYc3HQBz8QPxwISG26tIm5afvvVbu508oBeQ==" + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1.tgz", + "integrity": "sha512-7CnQyD5G8shHxQIIg3c7/pSeYFeMhsNbpU/bmvH7ZnDql7mNRgg8O2JZrhrc/soFnfBnKP4/xXNiiSIPn2w8gA==" }, "node_modules/@next/eslint-plugin-next": { "version": "14.0.4", @@ -3210,9 +3212,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.0.4.tgz", - "integrity": "sha512-mF05E/5uPthWzyYDyptcwHptucf/jj09i2SXBPwNzbgBNc+XnwzrL0U6BmPjQeOL+FiB+iG1gwBeq7mlDjSRPg==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1.tgz", + "integrity": "sha512-yDjSFKQKTIjyT7cFv+DqQfW5jsD+tVxXTckSe1KIouKk75t1qZmj/mV3wzdmFb0XHVGtyRjDMulfVG8uCKemOQ==", "cpu": [ "arm64" ], @@ -3225,9 +3227,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.0.4.tgz", - "integrity": "sha512-IZQ3C7Bx0k2rYtrZZxKKiusMTM9WWcK5ajyhOZkYYTCc8xytmwSzR1skU7qLgVT/EY9xtXDG0WhY6fyujnI3rw==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1.tgz", + "integrity": "sha512-KCQmBL0CmFmN8D64FHIZVD9I4ugQsDBBEJKiblXGgwn7wBCSe8N4Dx47sdzl4JAg39IkSN5NNrr8AniXLMb3aw==", "cpu": [ "x64" ], @@ -3240,9 +3242,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.0.4.tgz", - "integrity": "sha512-VwwZKrBQo/MGb1VOrxJ6LrKvbpo7UbROuyMRvQKTFKhNaXjUmKTu7wxVkIuCARAfiI8JpaWAnKR+D6tzpCcM4w==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1.tgz", + "integrity": "sha512-YDQfbWyW0JMKhJf/T4eyFr4b3tceTorQ5w2n7I0mNVTFOvu6CGEzfwT3RSAQGTi/FFMTFcuspPec/7dFHuP7Eg==", "cpu": [ "arm64" ], @@ -3255,9 +3257,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.0.4.tgz", - "integrity": "sha512-8QftwPEW37XxXoAwsn+nXlodKWHfpMaSvt81W43Wh8dv0gkheD+30ezWMcFGHLI71KiWmHK5PSQbTQGUiidvLQ==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1.tgz", + "integrity": "sha512-fiuN/OG6sNGRN/bRFxRvV5LyzLB8gaL8cbDH5o3mEiVwfcMzyE5T//ilMmaTrnA8HLMS6hoz4cHOu6Qcp9vxgQ==", "cpu": [ "arm64" ], @@ -3270,9 +3272,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.0.4.tgz", - "integrity": "sha512-/s/Pme3VKfZAfISlYVq2hzFS8AcAIOTnoKupc/j4WlvF6GQ0VouS2Q2KEgPuO1eMBwakWPB1aYFIA4VNVh667A==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1.tgz", + "integrity": "sha512-rv6AAdEXoezjbdfp3ouMuVqeLjE1Bin0AuE6qxE6V9g3Giz5/R3xpocHoAi7CufRR+lnkuUjRBn05SYJ83oKNQ==", "cpu": [ "x64" ], @@ -3285,9 +3287,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.0.4.tgz", - "integrity": "sha512-m8z/6Fyal4L9Bnlxde5g2Mfa1Z7dasMQyhEhskDATpqr+Y0mjOBZcXQ7G5U+vgL22cI4T7MfvgtrM2jdopqWaw==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1.tgz", + "integrity": "sha512-YAZLGsaNeChSrpz/G7MxO3TIBLaMN8QWMr3X8bt6rCvKovwU7GqQlDu99WdvF33kI8ZahvcdbFsy4jAFzFX7og==", "cpu": [ "x64" ], @@ -3300,9 +3302,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.0.4.tgz", - "integrity": "sha512-7Wv4PRiWIAWbm5XrGz3D8HUkCVDMMz9igffZG4NB1p4u1KoItwx9qjATHz88kwCEal/HXmbShucaslXCQXUM5w==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1.tgz", + "integrity": "sha512-1L4mUYPBMvVDMZg1inUYyPvFSduot0g73hgfD9CODgbr4xiTYe0VOMTZzaRqYJYBA9mana0x4eaAaypmWo1r5A==", "cpu": [ "arm64" ], @@ -3315,9 +3317,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.0.4.tgz", - "integrity": "sha512-zLeNEAPULsl0phfGb4kdzF/cAVIfaC7hY+kt0/d+y9mzcZHsMS3hAS829WbJ31DkSlVKQeHEjZHIdhN+Pg7Gyg==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1.tgz", + "integrity": "sha512-jvIE9tsuj9vpbbXlR5YxrghRfMuG0Qm/nZ/1KDHc+y6FpnZ/apsgh+G6t15vefU0zp3WSpTMIdXRUsNl/7RSuw==", "cpu": [ "ia32" ], @@ -3330,9 +3332,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.0.4.tgz", - "integrity": "sha512-yEh2+R8qDlDCjxVpzOTEpBLQTEFAcP2A8fUFLaWNap9GitYKkKv1//y2S6XY6zsR4rCOPRpU7plYDR+az2n30A==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1.tgz", + "integrity": "sha512-S6K6EHDU5+1KrBDLko7/c1MNy/Ya73pIAmvKeFwsF4RmBFJSO7/7YeD4FnZ4iBdzE69PpQ4sOMU9ORKeNuxe8A==", "cpu": [ "x64" ], @@ -7426,6 +7428,15 @@ "node": ">=12" } }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -9170,7 +9181,8 @@ "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "peer": true }, "node_modules/globals": { "version": "13.24.0", @@ -11723,18 +11735,17 @@ "peer": true }, "node_modules/next": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/next/-/next-14.0.4.tgz", - "integrity": "sha512-qbwypnM7327SadwFtxXnQdGiKpkuhaRLE2uq62/nRul9cj9KhQ5LhHmlziTNqUidZotw/Q1I9OjirBROdUJNgA==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.1.tgz", + "integrity": "sha512-McrGJqlGSHeaz2yTRPkEucxQKe5Zq7uPwyeHNmJaZNY4wx9E9QdxmTp310agFRoMuIYgQrCrT3petg13fSVOww==", "dependencies": { - "@next/env": "14.0.4", + "@next/env": "14.1.1", "@swc/helpers": "0.5.2", "busboy": "1.6.0", - "caniuse-lite": "^1.0.30001406", + "caniuse-lite": "^1.0.30001579", "graceful-fs": "^4.2.11", "postcss": "8.4.31", - "styled-jsx": "5.1.1", - "watchpack": "2.4.0" + "styled-jsx": "5.1.1" }, "bin": { "next": "dist/bin/next" @@ -11743,15 +11754,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.0.4", - "@next/swc-darwin-x64": "14.0.4", - "@next/swc-linux-arm64-gnu": "14.0.4", - "@next/swc-linux-arm64-musl": "14.0.4", - "@next/swc-linux-x64-gnu": "14.0.4", - "@next/swc-linux-x64-musl": "14.0.4", - "@next/swc-win32-arm64-msvc": "14.0.4", - "@next/swc-win32-ia32-msvc": "14.0.4", - "@next/swc-win32-x64-msvc": "14.0.4" + "@next/swc-darwin-arm64": "14.1.1", + "@next/swc-darwin-x64": "14.1.1", + "@next/swc-linux-arm64-gnu": "14.1.1", + "@next/swc-linux-arm64-musl": "14.1.1", + "@next/swc-linux-x64-gnu": "14.1.1", + "@next/swc-linux-x64-musl": "14.1.1", + "@next/swc-win32-arm64-msvc": "14.1.1", + "@next/swc-win32-ia32-msvc": "14.1.1", + "@next/swc-win32-x64-msvc": "14.1.1" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -12771,6 +12782,19 @@ "node": ">=0.10.0" } }, + "node_modules/react-day-picker": { + "version": "8.10.1", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.1.tgz", + "integrity": "sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/gpbl" + }, + "peerDependencies": { + "date-fns": "^2.28.0 || ^3.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -14810,18 +14834,6 @@ "makeerror": "1.0.12" } }, - "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", diff --git a/package.json b/package.json index 3275758..c3e8337 100644 --- a/package.json +++ b/package.json @@ -38,13 +38,15 @@ "clsx": "^2.0.1", "cmdk": "^0.2.0", "crypto-js": "^4.2.0", + "date-fns": "^3.6.0", "firebase": "^10.12.2", "firebase-admin": "^12.1.1", "input-otp": "^1.2.4", - "next": "14.0.4", + "next": "14.1.1", "next-pwa": "^5.6.0", "next-themes": "^0.2.1", "react": "^18", + "react-day-picker": "^8.10.1", "react-dom": "^18", "react-hook-form": "^7.49.3", "recharts": "^2.10.4", diff --git a/src/components/dashboard/create-update-transaction.tsx b/src/components/dashboard/create-update-transaction.tsx index c224e65..b998ea7 100644 --- a/src/components/dashboard/create-update-transaction.tsx +++ b/src/components/dashboard/create-update-transaction.tsx @@ -17,7 +17,6 @@ import { import { fetchExchangeRates } from "@/lib/rates" import { Transaction } from "@/lib/transaction" import { Button } from "@/components/ui/button" -import { Checkbox } from "@/components/ui/checkbox" import { Dialog, DialogClose, @@ -39,7 +38,6 @@ import { import { Form, FormControl, - FormDescription, FormField, FormItem, FormLabel, @@ -58,13 +56,14 @@ import { CategorySelect } from "../category-select" import { Icons } from "../icons" import { BaseInput } from "../ui/input" import { Tabs, TabsList, TabsTrigger } from "../ui/tabs" +import { TransactionDateSelector } from "./transaction-date" type TransactionFormValues = { name: string amount: number category?: string currency: SupportedCurrencyCode - isRegular: boolean + date: Transaction["date"] type: "income" | "expense" } @@ -111,12 +110,18 @@ export function CreateUpdateTransaction({ } const newTransaction = { - ...values, + name: values.name, + type: values.type, amount: values.type === "expense" && values.amount > 0 ? values.amount * -1 : values.amount, - date: selectedDate, + category: values.category, + currency: values.currency, + date: { + start: selectedDate, + end: selectedDate, + }, exchangeRate, } as Transaction @@ -144,7 +149,10 @@ export function CreateUpdateTransaction({ )} - + + + + - @@ -180,11 +185,11 @@ export function CreateUpdateTransaction({ )} - - + + @@ -201,7 +206,10 @@ const formSchema = z.object({ amount: z.number().min(1, { message: "Amount is required" }), category: z.string().optional(), type: z.enum(["income", "expense"]), - isRegular: z.boolean(), + date: z.object({ + start: z.string().min(1), + end: z.string().min(1), + }), }) type TransactionFormProps = { @@ -226,7 +234,10 @@ function TransactionForm({ currency: fillData?.currency || baseCurrency, amount: Math.abs(fillData?.amount || 0), category: fillData?.category || "", - isRegular: fillData?.isRegular || false, + date: { + start: fillData?.date?.start || "", + end: fillData?.date?.end || "", + }, type: fillData?.type || "income", }, resolver: zodResolver(formSchema), @@ -304,12 +315,8 @@ function TransactionForm({ - - Income - - - Expense - + Income + Expense @@ -333,23 +340,18 @@ function TransactionForm({ /> ( - + + + Recurring + - -
- - Regular - - - Regular transaction will occur on month - -
)} /> diff --git a/src/components/dashboard/month-picker.tsx b/src/components/dashboard/month-picker.tsx index 949e6a7..3e39ef9 100644 --- a/src/components/dashboard/month-picker.tsx +++ b/src/components/dashboard/month-picker.tsx @@ -1,27 +1,37 @@ "use client" -import { useState } from "react" +import { useEffect, useState } from "react" import { ChevronLeftIcon, ChevronRightIcon } from "@radix-ui/react-icons" -import { Entry, MONTH_ABREVVESIONS } from "@/lib/definitions" -import { createDateFromMonthYear, formatEntry } from "@/lib/utils" +import { MONTH_ABREVVESIONS } from "@/lib/definitions" +import { createDateFromMonthYear } from "@/lib/utils" import { Button } from "@/components/ui/button" import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group" +type MonthYearPickerProps = { + defaultValue: string | number | Date + className?: string + onChange: (change: Date) => void +} + export function MonthYearPicker({ className, + defaultValue, onChange, -}: { - className?: string - onChange: (change: Entry) => void -}) { +}: MonthYearPickerProps) { const currentYear = new Date().getFullYear() const [year, setYear] = useState(currentYear) const [month, setMonth] = useState() + useEffect(() => { + const date = new Date(defaultValue) + setYear(date.getFullYear()) + setMonth(date.getMonth()) + }, [defaultValue]) + return (
-
+
-

{year}

+

{year}

@@ -64,17 +70,14 @@ export function MonthYearPicker({ onValueChange={(value) => { const intValue = Number(value || month) setMonth(intValue) - onChange({ - date: createDateFromMonthYear(intValue, year).toISOString(), - name: formatEntry(intValue, year), - } as Entry) + onChange(createDateFromMonthYear(intValue, year)) }} > {MONTH_ABREVVESIONS.map((m, index) => ( {m} diff --git a/src/components/dashboard/transaction-date.tsx b/src/components/dashboard/transaction-date.tsx new file mode 100644 index 0000000..1d3c935 --- /dev/null +++ b/src/components/dashboard/transaction-date.tsx @@ -0,0 +1,118 @@ +import { useEffect, useMemo, useState } from "react" +import { CalendarIcon } from "@radix-ui/react-icons" +import { format } from "date-fns" + +import { Transaction } from "@/lib/transaction" +import { cn } from "@/lib/utils" +import { Button } from "@/components/ui/button" +import { Calendar } from "@/components/ui/calendar" +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover" +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" + +import { MonthYearPicker } from "./month-picker" + +type DateSelectorProps = { + defaultValue: Transaction["date"] + onValueChange: (value: Transaction["date"]) => void +} + +type TransactionDateTypes = "one-time" | "recurring" | "infinite" + +export function TransactionDateSelector({ + defaultValue, + onValueChange, +}: DateSelectorProps) { + const [dateType, setDateType] = useState("one-time") + + return ( + setDateType(val as TransactionDateTypes)} + className="w-full" + > + + One-time + Recurring + Infinite + + + + + + ) +} + +type SingleDatePickerProps = { + defaultValue: Date + onValueChange: (d: Date) => void +} + +function SingleDatePicker({ + defaultValue, + onValueChange, +}: SingleDatePickerProps) { + const [date, setDate] = useState() + const [enableCalendar, setEnableCalendar] = useState(false) + const dateFormat = useMemo(() => { + if (enableCalendar) { + return "PPP" + } + return "MMMM yyyy" + }, [enableCalendar]) + + useEffect(() => { + setDate(defaultValue) + }, [defaultValue]) + + const handleSelect = (value: Date | undefined) => { + onValueChange(value as Date) + setDate(value) + } + + return ( + + + + + + {enableCalendar && ( + + )} + {!enableCalendar && ( + + )} + + + + ) +} diff --git a/src/components/ui/calendar.tsx b/src/components/ui/calendar.tsx new file mode 100644 index 0000000..018fe26 --- /dev/null +++ b/src/components/ui/calendar.tsx @@ -0,0 +1,72 @@ +"use client" + +import * as React from "react" +import { ChevronLeftIcon, ChevronRightIcon } from "@radix-ui/react-icons" +import { DayPicker } from "react-day-picker" + +import { cn } from "@/lib/utils" +import { buttonVariants } from "@/components/ui/button" + +export type CalendarProps = React.ComponentProps + +function Calendar({ + className, + classNames, + showOutsideDays = true, + ...props +}: CalendarProps) { + return ( + .day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md" + : "[&:has([aria-selected])]:rounded-md" + ), + day: cn( + buttonVariants({ variant: "ghost" }), + "h-8 w-8 p-0 font-normal aria-selected:opacity-100" + ), + day_range_start: "day-range-start", + day_range_end: "day-range-end", + day_selected: + "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground", + day_today: "bg-accent text-accent-foreground", + day_outside: + "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30", + day_disabled: "text-muted-foreground opacity-50", + day_range_middle: + "aria-selected:bg-accent aria-selected:text-accent-foreground", + day_hidden: "invisible", + ...classNames, + }} + components={{ + IconLeft: ({ ...props }) => , + IconRight: ({ ...props }) => , + }} + {...props} + /> + ) +} +Calendar.displayName = "Calendar" + +export { Calendar } diff --git a/src/lib/definitions.ts b/src/lib/definitions.ts index 9983b7a..2659915 100644 --- a/src/lib/definitions.ts +++ b/src/lib/definitions.ts @@ -1,11 +1,5 @@ import { typedObjectKeys } from "./utils" -export type Entry = { - name: string - userId: string - date: string -} - export const MONTH_NAMES: string[] = [ "January", "February", diff --git a/src/lib/server/crypto.ts b/src/lib/server/crypto.ts index ee56230..4e78e7c 100644 --- a/src/lib/server/crypto.ts +++ b/src/lib/server/crypto.ts @@ -1,7 +1,7 @@ import { createCipheriv, createDecipheriv, randomBytes } from "crypto" const algorithm = "aes-256-cbc" -const secretKey = "sDiVAmKrf9YzcFzDAt2t7wFRa5g3mWSB" +const secretKey = process.env["CRYPTO_KEY"] as string export function encrypt(text: string) { const iv = randomBytes(16) diff --git a/src/lib/transaction/index.ts b/src/lib/transaction/index.ts index 201627f..c04d551 100644 --- a/src/lib/transaction/index.ts +++ b/src/lib/transaction/index.ts @@ -7,9 +7,11 @@ export interface Transaction { name: string type: TransactionType amount: number - isRegular: boolean category?: string currency: SupportedCurrencyCode - date: string + date: { + start: number + end: number + } exchangeRate: Record }