From 274e73837d3e5d9a2556a45c5f38e9c6e565a167 Mon Sep 17 00:00:00 2001 From: despiegk Date: Thu, 31 Oct 2024 09:49:30 +0100 Subject: [PATCH] ... --- react-shadcn-starter/src/App.tsx | 15 ----- react-shadcn-starter/src/Router.tsx | 10 ++++ .../src/components/calendar/calendar.tsx | 47 +++++++++++---- .../src/components/calendar/eventform.tsx | 24 +++++--- react-shadcn-starter/src/components/icons.tsx | 57 ++++++++++++++----- .../src/components/layouts/Header.tsx | 3 +- react-shadcn-starter/src/components/logo.tsx | 17 +++--- .../src/components/webdav-file-manager.tsx | 55 +++++++++++------- react-shadcn-starter/src/config/app.ts | 36 +++++------- react-shadcn-starter/src/config/menu.ts | 23 +++++--- react-shadcn-starter/src/lib/utils.ts | 2 +- react-shadcn-starter/src/pages/Calendar.tsx | 12 ++++ react-shadcn-starter/src/pages/Dashboard.tsx | 4 +- .../src/pages/FileManager.tsx | 6 ++ 14 files changed, 200 insertions(+), 111 deletions(-) create mode 100644 react-shadcn-starter/src/pages/Calendar.tsx create mode 100644 react-shadcn-starter/src/pages/FileManager.tsx diff --git a/react-shadcn-starter/src/App.tsx b/react-shadcn-starter/src/App.tsx index 31da436..b3eb6d7 100644 --- a/react-shadcn-starter/src/App.tsx +++ b/react-shadcn-starter/src/App.tsx @@ -1,24 +1,9 @@ import React from 'react' -import { WebdavFileManager } from './components/webdav-file-manager' import { Toaster } from './components/ui/toaster' -import { OurCalendar } from './components/calendar/calendar' -import { WebDAVConfig } from './lib/calendar-data' - -const webdavConfig: WebDAVConfig = { - url: 'http://localhost:3333', - username: 'admin', - password: '1234', -} function App() { return ( <> - - {/* */} ) diff --git a/react-shadcn-starter/src/Router.tsx b/react-shadcn-starter/src/Router.tsx index c5fbfcb..7019270 100644 --- a/react-shadcn-starter/src/Router.tsx +++ b/react-shadcn-starter/src/Router.tsx @@ -6,6 +6,8 @@ import NoMatch from "./pages/NoMatch"; import Dashboard from "./pages/Dashboard"; import Empty from "./pages/Empty"; import Sample from "./pages/Sample"; +import Calendar from "./pages/Calendar"; +import FileManager from "./pages/FileManager"; export const router = createBrowserRouter([ { @@ -16,6 +18,14 @@ export const router = createBrowserRouter([ path: "", element: , }, + { + path: "calendar", + element: , + }, + { + path: "filemanager", + element: , + }, { path: "sample", element: , diff --git a/react-shadcn-starter/src/components/calendar/calendar.tsx b/react-shadcn-starter/src/components/calendar/calendar.tsx index 67dcfff..6bdb42c 100644 --- a/react-shadcn-starter/src/components/calendar/calendar.tsx +++ b/react-shadcn-starter/src/components/calendar/calendar.tsx @@ -238,6 +238,7 @@ export function OurCalendar({ webdavConfig, calendarFile, circleFile }: Calendar try { await dataManager.saveEvents(newEvents); + setEvents(newEvents); // Update local state after successful save toast({ title: "Changes saved", description: "Your changes have been successfully saved.", @@ -253,22 +254,48 @@ export function OurCalendar({ webdavConfig, calendarFile, circleFile }: Calendar } const handleAddEvent = async (event: Event) => { - const newEvents = [...events, event] - setEvents(newEvents) - setIsAddEventOpen(false) - await saveCalendarData(newEvents) + try { + const newEvents = [...events, event]; + await saveCalendarData(newEvents); + setIsAddEventOpen(false); + } catch (err) { + console.error('Error adding event:', err); + toast({ + title: "Error adding event", + description: "There was a problem adding the event. Please try again.", + variant: "destructive", + }); + } } const handleEditEvent = async (updatedEvent: Event) => { - setEvents(prev => prev.map(event => event.id === updatedEvent.id ? updatedEvent : event)) - setSelectedEvent(null) - await saveCalendarData(events.map(event => event.id === updatedEvent.id ? updatedEvent : event)) + try { + const newEvents = events.map(event => event.id === updatedEvent.id ? updatedEvent : event); + await saveCalendarData(newEvents); + setSelectedEvent(null); + } catch (err) { + console.error('Error editing event:', err); + toast({ + title: "Error editing event", + description: "There was a problem updating the event. Please try again.", + variant: "destructive", + }); + } } const handleDeleteEvent = async (id: string) => { - setEvents(prev => prev.filter(event => event.id !== id)) - setSelectedEvent(null) - await saveCalendarData(events.filter(event => event.id !== id)) + try { + const newEvents = events.filter(event => event.id !== id); + await saveCalendarData(newEvents); + setSelectedEvent(null); + } catch (err) { + console.error('Error deleting event:', err); + toast({ + title: "Error deleting event", + description: "There was a problem deleting the event. Please try again.", + variant: "destructive", + }); + } } return ( diff --git a/react-shadcn-starter/src/components/calendar/eventform.tsx b/react-shadcn-starter/src/components/calendar/eventform.tsx index 2a0f5c5..31ee5b7 100644 --- a/react-shadcn-starter/src/components/calendar/eventform.tsx +++ b/react-shadcn-starter/src/components/calendar/eventform.tsx @@ -42,15 +42,23 @@ export function EventForm({ onSubmit, initialData, isDarkMode }: EventFormProps) const [content, setContent] = React.useState(initialData?.content || '') const [attendees, setAttendees] = React.useState(initialData?.attendees || []) const [isFullDay, setIsFullDay] = React.useState(initialData?.isFullDay || false) + const [isOpen, setIsOpen] = React.useState(false) + + const handleDateSelect = (newDate: Date | undefined) => { + if (newDate) { + setDate(newDate) + setIsOpen(false) + } + } const handleSubmit = (e: React.FormEvent) => { e.preventDefault() if (title && date && category) { const color = categories.find(c => c.name === category)?.color || 'bg-gray-500 dark:bg-gray-700' - onSubmit({ + const eventData: Event = { id: initialData?.id || uuidv4(), title, - date: date.toISOString().split('T')[0], + date: format(date, 'yyyy-MM-dd'), time: isFullDay ? '00:00' : time, duration: parseInt(duration), category, @@ -58,7 +66,8 @@ export function EventForm({ onSubmit, initialData, isDarkMode }: EventFormProps) content, attendees, isFullDay - }) + } + onSubmit(eventData) } } @@ -74,11 +83,12 @@ export function EventForm({ onSubmit, initialData, isDarkMode }: EventFormProps) className="dark:bg-gray-700 dark:text-white dark:border-gray-600" /> -
+
- + - + newDate && setDate(newDate)} + onSelect={handleDateSelect} initialFocus className={isDarkMode ? "dark" : ""} /> diff --git a/react-shadcn-starter/src/components/icons.tsx b/react-shadcn-starter/src/components/icons.tsx index e779374..52deb83 100644 --- a/react-shadcn-starter/src/components/icons.tsx +++ b/react-shadcn-starter/src/components/icons.tsx @@ -1,17 +1,44 @@ -type IconProps = React.HTMLAttributes +import { + LucideProps, + Moon, + SunMedium, + Twitter, + type Icon as LucideIcon, +} from "lucide-react" + +export type Icon = typeof LucideIcon export const Icons = { - logo: (props: IconProps) => ( - - - - ), - gitHub: (props: IconProps) => ( - - - - ), -} \ No newline at end of file + sun: SunMedium, + moon: Moon, + twitter: Twitter, + logo: ({ ...props }: LucideProps) => ( + + + + + + + ), + gitHub: ({ ...props }: LucideProps) => ( + + + + ), +} diff --git a/react-shadcn-starter/src/components/layouts/Header.tsx b/react-shadcn-starter/src/components/layouts/Header.tsx index 6c55dad..4a78046 100644 --- a/react-shadcn-starter/src/components/layouts/Header.tsx +++ b/react-shadcn-starter/src/components/layouts/Header.tsx @@ -77,7 +77,6 @@ export function Header() { ) )} -
{/* mobile */} @@ -209,4 +208,4 @@ export function Header() {
) -} \ No newline at end of file +} diff --git a/react-shadcn-starter/src/components/logo.tsx b/react-shadcn-starter/src/components/logo.tsx index 01e89be..04bf89e 100644 --- a/react-shadcn-starter/src/components/logo.tsx +++ b/react-shadcn-starter/src/components/logo.tsx @@ -1,11 +1,10 @@ -import { appConfig } from "@/config/app"; -import { Icons } from "./icons"; +import { Icons } from "./icons" export function Logo() { - return ( - <> - - {appConfig.name} - - ) -} \ No newline at end of file + return ( +
+ + Hero Web +
+ ) +} diff --git a/react-shadcn-starter/src/components/webdav-file-manager.tsx b/react-shadcn-starter/src/components/webdav-file-manager.tsx index 5dd756d..edc960d 100644 --- a/react-shadcn-starter/src/components/webdav-file-manager.tsx +++ b/react-shadcn-starter/src/components/webdav-file-manager.tsx @@ -6,16 +6,17 @@ import { javascript } from '@codemirror/lang-javascript' import { markdown } from '@codemirror/lang-markdown' import { json } from '@codemirror/lang-json' import { yaml } from '@codemirror/lang-yaml' +import { WebDAVConfig } from "../lib/calendar-data" -import { cn } from "@/lib/utils" -import { Button } from "@/components/ui/button" +import { cn } from "../lib/utils" +import { Button } from "./ui/button" import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuTrigger, -} from "@/components/ui/context-menu" +} from "./ui/context-menu" import { Dialog, DialogContent, @@ -23,11 +24,11 @@ import { DialogFooter, DialogHeader, DialogTitle, -} from "@/components/ui/dialog" -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" -import { ScrollArea } from "@/components/ui/scroll-area" -import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" +} from "./ui/dialog" +import { Input } from "./ui/input" +import { Label } from "./ui/label" +import { ScrollArea } from "./ui/scroll-area" +import { Alert, AlertDescription, AlertTitle } from "./ui/alert" import { useToast } from "./ui/use-toast" // Custom fetch function to handle CORS @@ -44,14 +45,6 @@ async function customFetch(url: string, options: RequestInit = {}) { return response } -// Initialize WebDAV client with custom fetch -const client = createClient("http://localhost:3333", { - username: "admin", - password: "1234", -}) as WebDAVClient - -console.log("WebDAV client initialized:", client) - type FileSystemItem = { basename: string filename: string @@ -125,7 +118,13 @@ const Breadcrumb: React.FC<{ ) } -const FileUploader: React.FC<{ currentPath: string, onUpload: () => void }> = ({ currentPath, onUpload }) => { +interface FileUploaderProps { + currentPath: string + onUpload: () => void + client: WebDAVClient +} + +const FileUploader: React.FC = ({ currentPath, onUpload, client }) => { const { toast } = useToast() const handleFileChange = async (e: React.ChangeEvent) => { @@ -186,11 +185,14 @@ const FileUploader: React.FC<{ currentPath: string, onUpload: () => void }> = ({ ) } -const FileSystemItem: React.FC<{ +interface FileSystemItemProps { item: FileSystemItem currentPath: string onRefresh: () => void -}> = ({ item, currentPath, onRefresh }) => { + client: WebDAVClient +} + +const FileSystemItem: React.FC = ({ item, currentPath, onRefresh, client }) => { const [isEditDialogOpen, setIsEditDialogOpen] = useState(false) const [editedContent, setEditedContent] = useState("") const [isFullscreen, setIsFullscreen] = useState(false) @@ -381,7 +383,11 @@ function formatFileSize(bytes: number): string { return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}` } -export function WebdavFileManager() { +interface WebdavFileManagerProps { + webdavConfig: WebDAVConfig +} + +export function WebdavFileManager({ webdavConfig }: WebdavFileManagerProps) { const [currentPath, setCurrentPath] = useState("/") const [items, setItems] = useState([]) const [isLoading, setIsLoading] = useState(true) @@ -391,6 +397,12 @@ export function WebdavFileManager() { const [newDirName, setNewDirName] = useState("") const { toast } = useToast() + // Initialize WebDAV client with provided config + const client = createClient(webdavConfig.url, { + username: webdavConfig.username, + password: webdavConfig.password, + }) as WebDAVClient + const loadDirectory = async (path: string) => { setIsLoading(true) setError(null) @@ -500,7 +512,7 @@ export function WebdavFileManager() {

WebDAV File Manager

- loadDirectory(currentPath)} /> + loadDirectory(currentPath)} client={client} /> @@ -527,6 +539,7 @@ export function WebdavFileManager() { item={item} currentPath={currentPath} onRefresh={() => loadDirectory(currentPath)} + client={client} /> ))} diff --git a/react-shadcn-starter/src/config/app.ts b/react-shadcn-starter/src/config/app.ts index 6ccc302..725291e 100644 --- a/react-shadcn-starter/src/config/app.ts +++ b/react-shadcn-starter/src/config/app.ts @@ -1,23 +1,17 @@ -interface AppConfig { - name: string, - github: { - title: string, - url: string - }, - author: { - name: string, - url: string - }, +import { WebDAVConfig } from '../lib/calendar-data' + +export const appConfig = { + name: "Hero Web", + github: { + url: "https://github.com/freeflowuniverse/heroweb", + title: "Hero Web on GitHub" + } } -export const appConfig: AppConfig = { - name: "Sample App", - github: { - title: "React Shadcn Starter", - url: "https://github.com/hayyi2/react-shadcn-starter", - }, - author: { - name: "hayyi", - url: "https://github.com/hayyi2/", - } -} \ No newline at end of file +export const webdavConfig: WebDAVConfig = { + url: 'http://localhost:3333', + username: 'admin', + password: '1234', +} + +export type { WebDAVConfig } diff --git a/react-shadcn-starter/src/config/menu.ts b/react-shadcn-starter/src/config/menu.ts index 1f91a65..ebf2e74 100644 --- a/react-shadcn-starter/src/config/menu.ts +++ b/react-shadcn-starter/src/config/menu.ts @@ -18,24 +18,31 @@ export const mainMenu: NavItemWithChildren[] = [ { title: 'Dashboard', to: '', + icon: 'logo' }, { - title: 'Dropdown', + title: 'Calendar', + to: '/calendar', + icon: 'logo' + }, + { + title: 'File Manager', + to: '/filemanager', + icon: 'logo' + }, + { + title: 'More', items: [ { title: 'Sample', to: '/sample', }, { - title: 'Sample Dua', - to: '/#', + title: 'Empty', + to: '/empty', }, ] - }, - { - title: 'Empty', - to: 'empty', - }, + } ] export const sideMenu: NavItemWithChildren[] = [] diff --git a/react-shadcn-starter/src/lib/utils.ts b/react-shadcn-starter/src/lib/utils.ts index d084cca..ec79801 100644 --- a/react-shadcn-starter/src/lib/utils.ts +++ b/react-shadcn-starter/src/lib/utils.ts @@ -1,6 +1,6 @@ import { type ClassValue, clsx } from "clsx" import { twMerge } from "tailwind-merge" - + export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } diff --git a/react-shadcn-starter/src/pages/Calendar.tsx b/react-shadcn-starter/src/pages/Calendar.tsx new file mode 100644 index 0000000..01dcf02 --- /dev/null +++ b/react-shadcn-starter/src/pages/Calendar.tsx @@ -0,0 +1,12 @@ +import { OurCalendar } from '../components/calendar/calendar' +import { webdavConfig } from '../config/app' + +export default function Calendar() { + return ( + + ) +} diff --git a/react-shadcn-starter/src/pages/Dashboard.tsx b/react-shadcn-starter/src/pages/Dashboard.tsx index 7c8e528..7bb35c4 100644 --- a/react-shadcn-starter/src/pages/Dashboard.tsx +++ b/react-shadcn-starter/src/pages/Dashboard.tsx @@ -9,8 +9,8 @@ export default function Dashboard() { - React Shadcn Starter - React + Vite + TypeScript template for building apps with shadcn/ui. + Hero Web + Lets play. diff --git a/react-shadcn-starter/src/pages/FileManager.tsx b/react-shadcn-starter/src/pages/FileManager.tsx new file mode 100644 index 0000000..e5c8bf4 --- /dev/null +++ b/react-shadcn-starter/src/pages/FileManager.tsx @@ -0,0 +1,6 @@ +import { WebdavFileManager } from '../components/webdav-file-manager' +import { webdavConfig } from '../config/app' + +export default function FileManager() { + return +}