feat: update Next.js configuration, add 'use client' directive to multiple components, and create new pages for music, editor, and videos
Some checks failed
GBCI / build (push) Failing after 1m45s
Some checks failed
GBCI / build (push) Failing after 1m45s
This commit is contained in:
parent
f3a659f8b0
commit
4e57232f08
31 changed files with 114 additions and 132 deletions
|
@ -1,20 +0,0 @@
|
||||||
import { NextResponse } from 'next/server'
|
|
||||||
|
|
||||||
export async function POST() {
|
|
||||||
try {
|
|
||||||
const response = await fetch('https://generalbots.online/directline/PROD-GeneralBots006/conversations', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const data = await response.json()
|
|
||||||
return NextResponse.json(data)
|
|
||||||
} catch (error) {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: 'Failed to create conversation' },
|
|
||||||
{ status: 500 }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
import { NextResponse } from 'next/server'
|
|
||||||
|
|
||||||
export async function GET(request: Request) {
|
|
||||||
const { searchParams } = new URL(request.url)
|
|
||||||
const room = searchParams.get('room')
|
|
||||||
const identity = searchParams.get('identity')
|
|
||||||
|
|
||||||
const response = await fetch(
|
|
||||||
`https://generalbots.online/PROD-GeneralBots006/meeting-token?room=${room}&identity=${identity}`
|
|
||||||
)
|
|
||||||
const data = await response.json()
|
|
||||||
|
|
||||||
return NextResponse.json(data)
|
|
||||||
}
|
|
|
@ -6,7 +6,6 @@ import '../../styles/chat.css';
|
||||||
|
|
||||||
export function ChatInput() {
|
export function ChatInput() {
|
||||||
const [message, setMessage] = React.useState('');
|
const [message, setMessage] = React.useState('');
|
||||||
const [showEmoji, setShowEmoji] = React.useState(false);
|
|
||||||
const { sendActivity } = useChat();
|
const { sendActivity } = useChat();
|
||||||
const { playSound } = useSound();
|
const { playSound } = useSound();
|
||||||
|
|
||||||
|
@ -20,10 +19,6 @@ export function ChatInput() {
|
||||||
setMessage('');
|
setMessage('');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEmojiSelect = (emoji) => {
|
|
||||||
playSound('click');
|
|
||||||
setMessage((prev) => prev + emoji);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -33,7 +28,7 @@ export function ChatInput() {
|
||||||
<path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" />
|
<path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button className="icon-button" onClick={() => setShowEmoji(true)}>
|
<button className="icon-button">
|
||||||
<svg className="icon" viewBox="0 0 24 24">
|
<svg className="icon" viewBox="0 0 24 24">
|
||||||
<path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zM8 14s1.5 2 4 2 4-2 4-2M9 9h.01M15 9h.01" />
|
<path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zM8 14s1.5 2 4 2 4-2 4-2M9 9h.01M15 9h.01" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
import React, { createContext, useContext, useState, useEffect } from 'react';
|
import React, { createContext, useContext, useState, useEffect } from 'react';
|
||||||
import { User, ChatInstance } from '../types';
|
import { User } from '../types';
|
||||||
|
|
||||||
const ChatContext = createContext(undefined);
|
const ChatContext = createContext(undefined);
|
||||||
|
|
||||||
|
@ -28,8 +28,8 @@ export function ChatProvider({ children }) {
|
||||||
|
|
||||||
const chatService = {
|
const chatService = {
|
||||||
activity$: { subscribe: () => {} },
|
activity$: { subscribe: () => {} },
|
||||||
postActivity: (activity) => ({
|
postActivity: () => ({
|
||||||
subscribe: (observer) => {
|
subscribe: () => {
|
||||||
return { unsubscribe: () => {} };
|
return { unsubscribe: () => {} };
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
"use client";
|
"use client";
|
||||||
import React, { createContext, useContext, useCallback } from 'react';
|
import React, { createContext, useCallback } from 'react';
|
||||||
|
|
||||||
const SoundContext = createContext(undefined);
|
const SoundContext = createContext(undefined);
|
||||||
|
|
||||||
export function SoundProvider({ children }) {
|
export function SoundProvider({ children }) {
|
||||||
const [enabled, setEnabled] = React.useState(true);
|
const [enabled, setEnabled] = React.useState(true);
|
||||||
|
|
||||||
const playSound = useCallback((sound) => {
|
const playSound = useCallback(() => {
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
const audio = new Audio();
|
const audio = new Audio();
|
||||||
audio.play().catch((err) => console.error('Failed to play sound:', err));
|
audio.play().catch((err) => console.error('Failed to play sound:', err));
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
'use client'
|
||||||
|
|
||||||
|
export default function MainPage() {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col h-screen bg-gray-50">
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
import { ThemeProvider } from "@/components/ui/theme-provider";
|
import { ThemeProvider } from "@/components/ui/theme-provider";
|
||||||
import { Metadata } from 'next';
|
|
||||||
import { Nav } from './client-nav';
|
import { Nav } from './client-nav';
|
||||||
import './globals.css';
|
import './globals.css';
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ import {
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from "@/components/ui/tooltip"
|
} from "@/components/ui/tooltip"
|
||||||
import { Mail } from "./data"
|
import { Mail } from "../data"
|
||||||
|
|
||||||
interface MailDisplayProps {
|
interface MailDisplayProps {
|
||||||
mail: Mail | null
|
mail: Mail | null
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import NextLink from 'next/link'; // Changed from lucide-react
|
import NextLink from 'next/link'; // Changed from lucide-react
|
||||||
import { Link as LinkIcon } from 'lucide-react'; // Renamed to avoid conflict
|
|
||||||
import { LucideIcon } from "lucide-react"
|
import { LucideIcon } from "lucide-react"
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils"
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import Image from "next/image"
|
|
||||||
|
|
||||||
import { Mail } from "./components/mail"
|
import { Mail } from "./components/mail"
|
||||||
import { accounts, mails } from "./data"
|
import { accounts, mails } from "./data"
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
import { useState, useEffect, useRef } from 'react'
|
import { useState, useEffect, useRef } from 'react'
|
||||||
import { LiveKitRoom, VideoConference } from '@livekit/components-react'
|
import { LiveKitRoom, VideoConference } from '@livekit/components-react'
|
||||||
import { RoomEvent, Track } from 'livekit-client'
|
|
||||||
import { useRouter } from 'next/navigation'
|
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Input } from '@/components/ui/input'
|
import { Input } from '@/components/ui/input'
|
||||||
import { Card } from '@/components/ui/card'
|
import { Card } from '@/components/ui/card'
|
||||||
|
@ -12,28 +10,29 @@ import { ScrollArea } from '@/components/ui/scroll-area'
|
||||||
import '@livekit/components-styles';
|
import '@livekit/components-styles';
|
||||||
import { Avatar, AvatarFallback } from '@/components/ui/avatar'
|
import { Avatar, AvatarFallback } from '@/components/ui/avatar'
|
||||||
import { Mic, MicOff, Video, VideoOff, Send, Bot } from 'lucide-react'
|
import { Mic, MicOff, Video, VideoOff, Send, Bot } from 'lucide-react'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
|
||||||
export default function MeetingPage({ params }: { params: { room: string } }) {
|
export default function MeetRoomPage() {
|
||||||
|
|
||||||
|
const [name, setName] = useState('');
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const [name, setName] = useState('')
|
|
||||||
const [roomName, setRoomName] = useState(params.room || '')
|
const [roomName, setRoomName] = useState(router.query.slug || '');
|
||||||
|
|
||||||
const [token, setToken] = useState('')
|
const [token, setToken] = useState('')
|
||||||
const [isConnected, setIsConnected] = useState(false)
|
const [isConnected, setIsConnected] = useState(false)
|
||||||
const [messages, setMessages] = useState<Array<{sender: string, text: string, isBot: boolean}>>([])
|
const [messages, setMessages] = useState<Array<{ sender: string, text: string, isBot: boolean }>>([])
|
||||||
const [inputMessage, setInputMessage] = useState('')
|
const [inputMessage, setInputMessage] = useState('')
|
||||||
const [micEnabled, setMicEnabled] = useState(true)
|
const [micEnabled, setMicEnabled] = useState(true)
|
||||||
const [cameraEnabled, setCameraEnabled] = useState(true)
|
const [cameraEnabled, setCameraEnabled] = useState(true)
|
||||||
const [botTyping, setBotTyping] = useState(false)
|
const [botTyping, setBotTyping] = useState(false)
|
||||||
const botConnectionRef = useRef<any>(null)
|
const botConnectionRef = useRef<any>(null)
|
||||||
const audioContextRef = useRef<AudioContext>()
|
|
||||||
const processorRef = useRef<ScriptProcessorNode>()
|
|
||||||
const participantsRef = useRef<Map<string, MediaStreamAudioSourceNode>>(new Map())
|
|
||||||
|
|
||||||
|
|
||||||
// Connect to LiveKit room
|
// Connect to LiveKit room
|
||||||
const connectToRoom = async () => {
|
const connectToRoom = async () => {
|
||||||
try {
|
try {
|
||||||
const resp = await fetch(`/api/get-token?room=${roomName}&identity=${name || 'user'}`)
|
const resp = await fetch(`https://generalbots.online/PROD-GeneralBots006/meeting-token?room=${roomName}&identity=${name || 'user'}`)
|
||||||
const data = await resp.json()
|
const data = await resp.json()
|
||||||
setToken(data.token)
|
setToken(data.token)
|
||||||
setIsConnected(true)
|
setIsConnected(true)
|
||||||
|
@ -48,19 +47,15 @@ export default function MeetingPage({ params }: { params: { room: string } }) {
|
||||||
// Connect to Bot Framework via Next.js API proxy
|
// Connect to Bot Framework via Next.js API proxy
|
||||||
const connectBot = async () => {
|
const connectBot = async () => {
|
||||||
try {
|
try {
|
||||||
// First create a conversation through our API proxy
|
|
||||||
const convResponse = await fetch('/api/bot/create-conversation', {
|
const response = await fetch('https://generalbots.online/directline/PROD-GeneralBots006/conversations', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
|
|
||||||
const convData = await convResponse.json();
|
const data = await response.json()
|
||||||
|
|
||||||
if (!convData.conversationId) {
|
|
||||||
throw new Error('Failed to create conversation');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then connect using WebSocket (which doesn't have CORS restrictions)
|
// Then connect using WebSocket (which doesn't have CORS restrictions)
|
||||||
const { DirectLine } = await import('botframework-directlinejs')
|
const { DirectLine } = await import('botframework-directlinejs')
|
||||||
|
@ -68,8 +63,8 @@ export default function MeetingPage({ params }: { params: { room: string } }) {
|
||||||
|
|
||||||
botConnectionRef.current = new DirectLine({
|
botConnectionRef.current = new DirectLine({
|
||||||
domain: 'https://generalbots.online/directline/PROD-GeneralBots006',
|
domain: 'https://generalbots.online/directline/PROD-GeneralBots006',
|
||||||
conversationId: convData.conversationId,
|
|
||||||
userId: userId,
|
userId: userId,
|
||||||
|
conversationId: data.conversationId,
|
||||||
webSocket: false // Force WebSocket connection
|
webSocket: false // Force WebSocket connection
|
||||||
} as any);
|
} as any);
|
||||||
botConnectionRef.current.setUserId(userId);
|
botConnectionRef.current.setUserId(userId);
|
||||||
|
@ -126,7 +121,7 @@ export default function MeetingPage({ params }: { params: { room: string } }) {
|
||||||
type: 'message',
|
type: 'message',
|
||||||
text
|
text
|
||||||
}).subscribe(
|
}).subscribe(
|
||||||
() => {},
|
() => { },
|
||||||
(err: any) => console.error('Error sending to bot:', err)
|
(err: any) => console.error('Error sending to bot:', err)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -189,7 +184,7 @@ export default function MeetingPage({ params }: { params: { room: string } }) {
|
||||||
<VideoConference className="absolute inset-0" />
|
<VideoConference className="absolute inset-0" />
|
||||||
<div className="absolute bottom-4 left-1/2 transform -translate-x-1/2 flex gap-2 bg-gray-800/80 backdrop-blur-sm p-2 rounded-full">
|
<div className="absolute bottom-4 left-1/2 transform -translate-x-1/2 flex gap-2 bg-gray-800/80 backdrop-blur-sm p-2 rounded-full">
|
||||||
<Button
|
<Button
|
||||||
variant={micEnabled ? 'primary' : 'outline'}
|
variant={micEnabled ? 'link' : 'outline'}
|
||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => setMicEnabled(!micEnabled)}
|
onClick={() => setMicEnabled(!micEnabled)}
|
||||||
className="rounded-full h-10 w-10 hover:bg-gray-700 transition-colors"
|
className="rounded-full h-10 w-10 hover:bg-gray-700 transition-colors"
|
||||||
|
@ -197,7 +192,7 @@ export default function MeetingPage({ params }: { params: { room: string } }) {
|
||||||
{micEnabled ? <Mic className="h-5 w-5" /> : <MicOff className="h-5 w-5" />}
|
{micEnabled ? <Mic className="h-5 w-5" /> : <MicOff className="h-5 w-5" />}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant={cameraEnabled ? 'primary' : 'outline'}
|
variant={cameraEnabled ? 'link' : 'outline'}
|
||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => setCameraEnabled(!cameraEnabled)}
|
onClick={() => setCameraEnabled(!cameraEnabled)}
|
||||||
className="rounded-full h-10 w-10 hover:bg-gray-700 transition-colors"
|
className="rounded-full h-10 w-10 hover:bg-gray-700 transition-colors"
|
|
@ -0,0 +1,8 @@
|
||||||
|
'use client'
|
||||||
|
|
||||||
|
export default function MainPage() {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col h-screen bg-gray-50">
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,3 +1,6 @@
|
||||||
|
|
||||||
|
"use client";
|
||||||
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useForm, Controller } from 'react-hook-form';
|
import { useForm, Controller } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
"use client";
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { AccountForm } from './account-form';
|
import { AccountForm } from './account-form';
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useForm, Controller } from 'react-hook-form';
|
import { useForm, Controller } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { AppearanceForm } from './appearance-form';
|
import { AppearanceForm } from './appearance-form';
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
'use client'; // Required for client-side interactivity
|
||||||
|
|
||||||
|
import { usePathname, useRouter } from 'next/navigation';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useNavigate, useLocation } from 'react-router-dom';
|
|
||||||
|
|
||||||
interface SidebarNavProps {
|
interface SidebarNavProps {
|
||||||
items: {
|
items: {
|
||||||
|
@ -9,17 +11,17 @@ interface SidebarNavProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SidebarNav({ items }: SidebarNavProps) {
|
export function SidebarNav({ items }: SidebarNavProps) {
|
||||||
const navigate = useNavigate();
|
const router = useRouter();
|
||||||
const location = useLocation();
|
const pathname = usePathname();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
{items.map((item) => (
|
{items.map((item) => (
|
||||||
<button
|
<button
|
||||||
key={item.href}
|
key={item.href}
|
||||||
onClick={() => navigate(item.href)}
|
onClick={() => router.push(item.href)}
|
||||||
className={`px-3 py-2 rounded-md text-sm font-medium ${
|
className={`px-3 py-2 rounded-md text-sm font-medium ${
|
||||||
location.pathname === item.href ? 'bg-gray-100' : 'hover:bg-gray-50'
|
pathname === item.href ? 'bg-gray-100' : 'hover:bg-gray-50'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{item.title}
|
{item.title}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useForm, Controller } from 'react-hook-form';
|
import { useForm, Controller } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { DisplayForm } from './display-form';
|
import { DisplayForm } from './display-form';
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useForm, Controller } from 'react-hook-form';
|
import { useForm, Controller } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { NotificationsForm } from './notifications-form';
|
import { NotificationsForm } from './notifications-form';
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useForm, Controller } from 'react-hook-form';
|
import { useForm, Controller } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
|
@ -60,13 +60,13 @@ function Page() {
|
||||||
const config: RcloneConfig = {
|
const config: RcloneConfig = {
|
||||||
name: state.name,
|
name: state.name,
|
||||||
remote_path: `s3://${state.name}`,
|
remote_path: `s3://${state.name}`,
|
||||||
local_path: `${window.__TAURI__.path.homeDir}/General Bots/${state.name}`,
|
local_path: `${window['__TAURI__'].path.homeDir}/General Bots/${state.name}`,
|
||||||
access_key: state.access_key,
|
access_key: state.access_key,
|
||||||
secret_key: state.secret_key,
|
secret_key: state.secret_key,
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await core.invoke("save_config", { config });
|
await invoke("save_config", { config });
|
||||||
setState(prev => ({
|
setState(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
status_text: "New sync saved!",
|
status_text: "New sync saved!",
|
||||||
|
@ -85,13 +85,13 @@ function Page() {
|
||||||
const config: RcloneConfig = {
|
const config: RcloneConfig = {
|
||||||
name: state.name || "example",
|
name: state.name || "example",
|
||||||
remote_path: `s3://${state.name || "example"}`,
|
remote_path: `s3://${state.name || "example"}`,
|
||||||
local_path: `${window.__TAURI__.path.homeDir}/General Bots/${state.name || "example"}`,
|
local_path: `${window['__TAURI__'].path.homeDir}/General Bots/${state.name || "example"}`,
|
||||||
access_key: state.access_key || "dummy",
|
access_key: state.access_key || "dummy",
|
||||||
secret_key: state.secret_key || "dummy",
|
secret_key: state.secret_key || "dummy",
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await core.invoke("start_sync", { config });
|
await invoke("start_sync", { config });
|
||||||
setState(prev => ({
|
setState(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
status_text: "Sync started!"
|
status_text: "Sync started!"
|
||||||
|
@ -106,7 +106,7 @@ function Page() {
|
||||||
|
|
||||||
const stopSync = async () => {
|
const stopSync = async () => {
|
||||||
try {
|
try {
|
||||||
await core.invoke("stop_sync");
|
await invoke("stop_sync");
|
||||||
setState(prev => ({
|
setState(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
status_text: "Sync stopped."
|
status_text: "Sync stopped."
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import { core } from '@tauri-apps/api';
|
import { core } from '@tauri-apps/api';
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { api } from '@tauri-apps/api';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
interface FileOperationsProps {
|
interface FileOperationsProps {
|
||||||
|
@ -15,21 +13,6 @@ export function FileOperations({ currentPath, onRefresh }: FileOperationsProps)
|
||||||
|
|
||||||
const handleUpload = async () => {
|
const handleUpload = async () => {
|
||||||
try {
|
try {
|
||||||
const selected = await open({
|
|
||||||
multiple: false,
|
|
||||||
directory: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (selected) {
|
|
||||||
const filePath = Array.isArray(selected) ? selected[0] : selected;
|
|
||||||
await core.invoke('upload_file', {
|
|
||||||
srcPath: filePath,
|
|
||||||
destPath: currentPath,
|
|
||||||
onProgress: (progress: number) => setUploadProgress(progress)
|
|
||||||
});
|
|
||||||
onRefresh();
|
|
||||||
alert('File uploaded successfully!');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Upload failed:', error);
|
console.error('Upload failed:', error);
|
||||||
alert('Upload failed!');
|
alert('Upload failed!');
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { core } from '@tauri-apps/api';
|
import { core } from '@tauri-apps/api';
|
||||||
|
import { FileBrowser } from './FileBrowser';
|
||||||
|
|
||||||
interface FileItem {
|
interface FileItem {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -47,7 +48,7 @@ export function FileTree({ onSelect }: FileTreeProps) {
|
||||||
</div>
|
</div>
|
||||||
{expanded[item.path] && (
|
{expanded[item.path] && (
|
||||||
<div className="pl-4">
|
<div className="pl-4">
|
||||||
<FileBrowser path={item.path} onSelect={onSelect} />
|
<FileBrowser path={item.path} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
'use client'
|
||||||
|
|
||||||
|
export default function MainPage() {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col h-screen bg-gray-50">
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
|
output: 'export',
|
||||||
images: { unoptimized: true }
|
images: { unoptimized: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
package-lock.json
generated
8
package-lock.json
generated
|
@ -59,7 +59,7 @@
|
||||||
"react": "18.3.1",
|
"react": "18.3.1",
|
||||||
"react-day-picker": "^8.10.1",
|
"react-day-picker": "^8.10.1",
|
||||||
"react-dom": "18.3.1",
|
"react-dom": "18.3.1",
|
||||||
"react-hook-form": "^7.53.2",
|
"react-hook-form": "^7.56.1",
|
||||||
"react-markdown": "10.1.0",
|
"react-markdown": "10.1.0",
|
||||||
"react-resizable-panels": "^2.1.7",
|
"react-resizable-panels": "^2.1.7",
|
||||||
"tailwind-merge": "3.0.2",
|
"tailwind-merge": "3.0.2",
|
||||||
|
@ -12617,9 +12617,9 @@
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/react-hook-form": {
|
"node_modules/react-hook-form": {
|
||||||
"version": "7.53.2",
|
"version": "7.56.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.53.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.56.1.tgz",
|
||||||
"integrity": "sha512-YVel6fW5sOeedd1524pltpHX+jgU2u3DSDtXEaBORNdqiNrsX/nUI/iGXONegttg0mJVnfrIkiV0cmTU6Oo2xw==",
|
"integrity": "sha512-qWAVokhSpshhcEuQDSANHx3jiAEFzu2HAaaQIzi/r9FNPm1ioAvuJSD4EuZzWd7Al7nTRKcKPnBKO7sRn+zavQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
"react": "18.3.1",
|
"react": "18.3.1",
|
||||||
"react-day-picker": "^8.10.1",
|
"react-day-picker": "^8.10.1",
|
||||||
"react-dom": "18.3.1",
|
"react-dom": "18.3.1",
|
||||||
"react-hook-form": "^7.53.2",
|
"react-hook-form": "^7.56.1",
|
||||||
"react-markdown": "10.1.0",
|
"react-markdown": "10.1.0",
|
||||||
"react-resizable-panels": "^2.1.7",
|
"react-resizable-panels": "^2.1.7",
|
||||||
"tailwind-merge": "3.0.2",
|
"tailwind-merge": "3.0.2",
|
||||||
|
|
|
@ -7,5 +7,5 @@ export async function getServerCookie(key: string): Promise<string | undefined>
|
||||||
if (process.env.NEXT_PHASE === 'phase-production-build') {
|
if (process.env.NEXT_PHASE === 'phase-production-build') {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return cookies().get(key)?.value;
|
return (await cookies()).get(key)?.value;
|
||||||
}
|
}
|
File diff suppressed because one or more lines are too long
Loading…
Add table
Reference in a new issue