Compare commits

...

2 Commits

Author SHA1 Message Date
6ec15c9124 fix description overflow 2025-08-16 11:34:47 -04:00
e7de213c18 use button as a file picker 2025-08-16 11:34:34 -04:00
2 changed files with 61 additions and 7 deletions

View File

@@ -7,6 +7,7 @@ import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '
import { Input } from '@/components/ui/input'
import { Card } from '@/components/ui/card'
import { RecurrencePicker } from '@/components/recurrence-picker'
import { IcsFilePicker } from '@/components/ics-file-picker'
import { addEvent, deleteEvent, getAllEvents, clearEvents, getDB } from '@/lib/db'
import { parseICS, generateICS } from '@/lib/ical'
@@ -248,18 +249,13 @@ export default function HomePage() {
{/* Control Toolbar */}
<div className="flex flex-wrap gap-2 mb-4">
<Button onClick={() => setDialogOpen(true)}>Add Event</Button>
<IcsFilePicker onFileSelect={handleImport} variant='secondary'>Import .ics</IcsFilePicker>
{events.length > 0 && (
<>
<Button variant="secondary" onClick={handleExport}>Export .ics</Button>
<Button variant="destructive" onClick={handleClearAll}>Clear All</Button>
</>
)}
<label className="cursor-pointer">
<span className="px-3 py-2 bg-blue-500 text-white rounded">Import .ics</span>
<input type="file" accept=".ics" hidden onChange={e => {
if (e.target.files?.length) handleImport(e.target.files[0])
}} />
</label>
</div>
{/* Event List */}
@@ -278,7 +274,7 @@ export default function HomePage() {
{ev.allDay ? ev.start.split('T')[0] : new Date(ev.start).toLocaleString()}
{ev.location && <span> @ {ev.location}</span>}
</div>
{ev.description && <div className="text-sm mt-1">{ev.description}</div>}
{ev.description && <div className="text-sm mt-1 wrap-anywhere">{ev.description}</div>}
</div>
<div className="flex gap-2">
<Button size="sm" onClick={() => {

View File

@@ -0,0 +1,58 @@
"use client"
import type React from "react"
import { useRef } from "react"
import { Button } from "@/components/ui/button"
import { Calendar } from "lucide-react"
interface IcsFilePickerProps {
onFileSelect?: (file: File) => void
className?: string
children?: React.ReactNode
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link"
size?: "default" | "sm" | "lg" | "icon"
}
export function IcsFilePicker({
onFileSelect,
className,
children,
variant = "default",
size = "default",
}: IcsFilePickerProps) {
const fileInputRef = useRef<HTMLInputElement>(null)
const handleButtonClick = () => {
fileInputRef.current?.click()
}
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0]
if (file && onFileSelect) {
onFileSelect(file)
}
}
return (
<>
<input
ref={fileInputRef}
type="file"
accept=".ics"
onChange={handleFileChange}
className="hidden"
aria-hidden="true"
/>
<Button onClick={handleButtonClick} variant={variant} size={size} className={className}>
{children || (
<>
<Calendar className="mr-2 h-4 w-4" />
Import Calendar
</>
)}
</Button>
</>
)
}