239 lines
8.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import React, { useEffect, useState } from 'react'
import { useSession } from 'next-auth/react'
import Link from 'next/link'
import Cookies from 'js-cookie'
interface Address {
id: string
street: string
city: string
postcode: string
order: number
}
interface Route {
id: string
createdAt: string
status: string
addresses: Address[]
}
export default function RoutesPage() {
const { data: session, status } = useSession()
const [routes, setRoutes] = useState<Route[]>([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const [isDeleting, setIsDeleting] = useState(false)
const [messages, setMessages] = useState<any>(null)
useEffect(() => {
const loadMessages = async () => {
const lang = Cookies.get('NEXT_LOCALE') || 'de'
const messages = await import(`@/messages/${lang}.json`)
setMessages(messages.default)
}
loadMessages()
}, [])
useEffect(() => {
fetchRoutes()
}, [session])
const fetchRoutes = async () => {
try {
const response = await fetch('/api/routes', {
credentials: 'include'
})
if (!response.ok) {
const errorData = await response.json()
throw new Error(errorData.message || messages?.routes?.error)
}
const data = await response.json()
setRoutes(data)
} catch (err) {
console.error('Rotaları getirme hatası:', err)
setError(err instanceof Error ? err.message : messages?.routes?.error)
} finally {
setLoading(false)
}
}
const handleDelete = async (routeId: string) => {
if (!confirm(messages?.routes?.confirmDelete?.message)) {
return
}
setIsDeleting(true)
try {
const response = await fetch(`/api/routes/${routeId}`, {
method: 'DELETE',
credentials: 'include'
})
if (!response.ok) {
throw new Error(messages?.routes?.error)
}
// Rotayı listeden kaldır
setRoutes(routes.filter(route => route.id !== routeId))
} catch (err) {
console.error('Rota silme hatası:', err)
setError(err instanceof Error ? err.message : messages?.routes?.error)
} finally {
setIsDeleting(false)
}
}
if (!messages || status === 'loading' || loading) {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-indigo-500"></div>
</div>
)
}
if (status === 'unauthenticated') {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="text-center">
<h2 className="text-2xl font-bold mb-4">{messages.common.accessDenied}</h2>
<p className="mb-4">{messages.common.loginRequired}</p>
<Link
href="/auth/login"
className="text-indigo-600 hover:text-indigo-800"
>
{messages.common.login}
</Link>
</div>
</div>
)
}
if (error) {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="text-center">
<h2 className="text-2xl font-bold mb-4">{messages.common.error}</h2>
<p className="text-red-600">{error}</p>
</div>
</div>
)
}
return (
<div className="min-h-screen bg-gray-100 py-6">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center">
<div className="flex items-center space-x-4">
<Link
href="/dashboard"
className="bg-gray-500 text-white px-4 py-2 rounded-md hover:bg-gray-600"
>
{messages?.common?.back}
</Link>
<h1 className="text-3xl font-bold text-gray-900">
{messages?.routes?.title}
</h1>
</div>
<Link
href="/dashboard/new-route"
className="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700"
>
{messages?.dashboard?.newRoute?.title}
</Link>
</div>
<div className="mt-8">
{routes.length === 0 ? (
<div className="text-center py-12">
<p className="text-gray-500">{messages?.routes?.noRoutes}</p>
<Link
href="/dashboard/new-route"
className="text-indigo-600 hover:text-indigo-800 mt-2 inline-block"
>
{messages?.routes?.createFirst}
</Link>
</div>
) : (
<div className="bg-white shadow overflow-hidden sm:rounded-md">
<ul className="divide-y divide-gray-200">
{routes.map((route) => (
<li key={route.id}>
<div className="px-4 py-4 sm:px-6">
<div className="flex items-center justify-between">
<div className="flex flex-col">
<p className="text-sm font-medium text-indigo-600 truncate">
{route.addresses.length} {messages?.routes?.addresses}
</p>
<p className="mt-1 text-sm text-gray-500">
{messages?.routes?.createdAt}: {new Date(route.createdAt).toLocaleDateString()}
</p>
</div>
<div className="flex items-center space-x-4">
<span
className={`px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${
route.status === 'COMPLETED'
? 'bg-green-100 text-green-800'
: route.status === 'IN_PROGRESS'
? 'bg-yellow-100 text-yellow-800'
: 'bg-gray-100 text-gray-800'
}`}
>
{route.status === 'COMPLETED'
? messages?.routes?.status?.completed
: route.status === 'IN_PROGRESS'
? messages?.routes?.status?.active
: messages?.routes?.status?.active}
</span>
<Link
href={`/dashboard/routes/${route.id}/edit`}
className="text-yellow-600 hover:text-yellow-900 font-medium"
>
{messages?.common?.edit}
</Link>
<button
onClick={() => handleDelete(route.id)}
disabled={isDeleting}
className="text-red-600 hover:text-red-900 font-medium disabled:opacity-50"
>
{messages?.common?.delete}
</button>
<Link
href={`/dashboard/routes/${route.id}`}
className="text-indigo-600 hover:text-indigo-900 font-medium"
>
{messages?.common?.details}
</Link>
</div>
</div>
<div className="mt-2">
<div className="text-sm text-gray-500">
<ul className="list-disc list-inside">
{route.addresses
.slice(0, 3)
.map((address) => (
<li key={address.id}>
{address.street}, {address.city} {address.postcode}
</li>
))}
{route.addresses.length > 3 && (
<li>{messages?.routeDetails?.moreAddresses.replace('{count}', String(route.addresses.length - 3))}</li>
)}
</ul>
</div>
</div>
</div>
</li>
))}
</ul>
</div>
)}
</div>
</div>
</div>
)
}