This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
"use client"
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useEffect, useState, useCallback } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { api, DeviceDto, PagedResult } from '@/lib/api'
|
||||
import { Settings, Calendar, LogOut, ArrowRight, Search, ChevronRight, ChevronLeft } from 'lucide-react'
|
||||
@@ -18,7 +18,7 @@ export default function DevicesPage() {
|
||||
|
||||
const pageSize = 10
|
||||
|
||||
const fetchDevices = async (page: number, search?: string) => {
|
||||
const fetchDevices = useCallback(async (page: number, search?: string) => {
|
||||
if (!user) return
|
||||
|
||||
setLoading(true)
|
||||
@@ -47,7 +47,7 @@ export default function DevicesPage() {
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
}, [user, router])
|
||||
|
||||
useEffect(() => {
|
||||
// Check authentication
|
||||
@@ -71,7 +71,7 @@ export default function DevicesPage() {
|
||||
if (user) {
|
||||
fetchDevices(currentPage, searchTerm || undefined)
|
||||
}
|
||||
}, [user, currentPage, searchTerm])
|
||||
}, [user, currentPage, searchTerm, fetchDevices])
|
||||
|
||||
const handleSearch = (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
|
||||
@@ -30,6 +30,7 @@ export default function RootLayout({ children }: Readonly<{ children: React.Reac
|
||||
<meta name="apple-mobile-web-app-title" content="GreenHome" />
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<link rel="apple-touch-icon" href="/icon-512.png" />
|
||||
{/* eslint-disable-next-line @next/next/no-css-tags */}
|
||||
<link rel="stylesheet" href="/fonts/vazirmatn/style.css" />
|
||||
</head>
|
||||
<body className='persian-number'>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
"use client"
|
||||
import { useState, useRef, useEffect } from 'react'
|
||||
import { api } from '@/lib/api'
|
||||
import { Smartphone, ArrowLeft, ArrowRight } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { Smartphone, ArrowLeft } from 'lucide-react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import Loading from '@/components/Loading'
|
||||
|
||||
@@ -77,9 +76,9 @@ export default function LoginPage() {
|
||||
} else {
|
||||
setError(result.message || 'خطا در ارسال کد')
|
||||
}
|
||||
} catch (error: any) {
|
||||
} catch (error: unknown) {
|
||||
console.error('Error sending code:', error)
|
||||
setError(error.message || 'خطا در ارتباط با سرور')
|
||||
setError(error instanceof Error ? error.message : 'خطا در ارتباط با سرور')
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export default function Home() {
|
||||
|
||||
if (token && userStr) {
|
||||
try {
|
||||
const user = JSON.parse(userStr)
|
||||
JSON.parse(userStr)
|
||||
// Redirect to devices check
|
||||
router.push('/devices')
|
||||
} catch {
|
||||
@@ -92,9 +92,9 @@ export default function Home() {
|
||||
} else {
|
||||
setError(result.message || 'خطا در ارسال کد')
|
||||
}
|
||||
} catch (error: any) {
|
||||
} catch (error: unknown) {
|
||||
console.error('Error sending code:', error)
|
||||
setError(error.message || 'خطا در ارتباط با سرور')
|
||||
setError(error instanceof Error ? error.message : 'خطا در ارتباط با سرور')
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ self.addEventListener('fetch', (event: FetchEvent) => {
|
||||
}
|
||||
|
||||
return await fetch(event.request);
|
||||
} catch (e) {
|
||||
} catch {
|
||||
const cache = await caches.open(CACHE_NAME);
|
||||
return await cache.match('/') || new Response('', {
|
||||
status: 404,
|
||||
@@ -84,7 +84,7 @@ self.addEventListener('fetch', (event: FetchEvent) => {
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return new Response('', {
|
||||
status: 404,
|
||||
statusText: 'Not Found',
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
"use client"
|
||||
import { useState, useEffect, useRef } from 'react'
|
||||
import { useState, useEffect, useRef, useCallback, Suspense } from 'react'
|
||||
import { useSearchParams, useRouter } from 'next/navigation'
|
||||
import { api } from '@/lib/api'
|
||||
import { Shield, ArrowRight, ArrowLeft, RotateCcw } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import Loading from '@/components/Loading'
|
||||
|
||||
export default function VerifyCodePage() {
|
||||
function VerifyCodeContent() {
|
||||
const searchParams = useSearchParams()
|
||||
const router = useRouter()
|
||||
const mobile = searchParams.get('mobile') || ''
|
||||
@@ -18,6 +18,21 @@ export default function VerifyCodePage() {
|
||||
const [canResend, setCanResend] = useState(false)
|
||||
const inputRefs = useRef<(HTMLInputElement | null)[]>([])
|
||||
|
||||
const checkResendStatus = useCallback(async () => {
|
||||
try {
|
||||
const result = await api.canResend(mobile)
|
||||
if (result.canResend) {
|
||||
setCanResend(true)
|
||||
setResendCooldown(0)
|
||||
} else {
|
||||
setCanResend(false)
|
||||
setResendCooldown(120)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking resend status:', error)
|
||||
}
|
||||
}, [mobile])
|
||||
|
||||
useEffect(() => {
|
||||
if (!mobile || mobile.length !== 11) {
|
||||
router.push('/login')
|
||||
@@ -37,22 +52,7 @@ export default function VerifyCodePage() {
|
||||
}, 1000)
|
||||
|
||||
return () => clearInterval(interval)
|
||||
}, [mobile, router])
|
||||
|
||||
const checkResendStatus = async () => {
|
||||
try {
|
||||
const result = await api.canResend(mobile)
|
||||
if (result.canResend) {
|
||||
setCanResend(true)
|
||||
setResendCooldown(0)
|
||||
} else {
|
||||
setCanResend(false)
|
||||
setResendCooldown(120)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking resend status:', error)
|
||||
}
|
||||
}
|
||||
}, [mobile, router, checkResendStatus])
|
||||
|
||||
const handleCodeChange = (index: number, value: string) => {
|
||||
if (!/^\d*$/.test(value)) return
|
||||
@@ -141,9 +141,9 @@ export default function VerifyCodePage() {
|
||||
setCode(['', '', '', ''])
|
||||
inputRefs.current[0]?.focus()
|
||||
}
|
||||
} catch (error: any) {
|
||||
} catch (error: unknown) {
|
||||
console.error('Error verifying code:', error)
|
||||
setError(error.message || 'خطا در ارتباط با سرور')
|
||||
setError(error instanceof Error ? error.message : 'خطا در ارتباط با سرور')
|
||||
setCode(['', '', '', ''])
|
||||
inputRefs.current[0]?.focus()
|
||||
} finally {
|
||||
@@ -171,9 +171,9 @@ export default function VerifyCodePage() {
|
||||
setError(result.message || 'خطا در ارسال مجدد کد')
|
||||
setCanResend(true)
|
||||
}
|
||||
} catch (error: any) {
|
||||
} catch (error: unknown) {
|
||||
console.error('Error resending code:', error)
|
||||
setError(error.message || 'خطا در ارتباط با سرور')
|
||||
setError(error instanceof Error ? error.message : 'خطا در ارتباط با سرور')
|
||||
setCanResend(true)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
@@ -305,3 +305,11 @@ export default function VerifyCodePage() {
|
||||
)
|
||||
}
|
||||
|
||||
export default function VerifyCodePage() {
|
||||
return (
|
||||
<Suspense fallback={<Loading message="در حال بارگذاری..." />}>
|
||||
<VerifyCodeContent />
|
||||
</Suspense>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ async function http<T>(url: string, init?: RequestInit): Promise<T> {
|
||||
} catch {
|
||||
// Ignore JSON parse errors
|
||||
}
|
||||
const error: any = new Error(errorMessage)
|
||||
const error = new Error(errorMessage) as Error & { status?: number }
|
||||
error.status = res.status
|
||||
throw error
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user