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