-
{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
}