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