Files
GreenHomeUI/src/app/page.tsx
alireza 9da69c96b1
Some checks failed
Deploy MyApp on Same Server / build-and-deploy (push) Has been cancelled
refactor(alert-settings): integrate AppShell layout and update cache version
- Replace custom page layout with AppShell component for consistent UI
- Remove unused PageHeader and UpdateAlertConditionDto imports
- Update service worker cache names and version.json to new timestamp
2026-05-11 22:19:30 +03:30

170 lines
6.3 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation'
import { api } from '@/lib/api'
import { Smartphone, ArrowLeft } from 'lucide-react'
import Loading from '@/components/Loading'
import { MobileInput } from '@/components/forms'
import { ErrorMessage } from '@/components/common'
import { getCurrentPersianYear, getCurrentPersianMonth, getCurrentPersianDay } from '@/lib/date/persian-date'
export default function Home() {
const router = useRouter()
const [mobile, setMobile] = useState('')
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
// Check if user is logged in
const token = localStorage.getItem('authToken')
const userStr = localStorage.getItem('user')
if (token && userStr) {
try {
const user = JSON.parse(userStr)
// Try to use the saved device from localStorage first
const savedDeviceId = localStorage.getItem('selectedDeviceId')
if (savedDeviceId) {
const today = `${getCurrentPersianYear()}/${String(getCurrentPersianMonth()).padStart(2, '0')}/${String(getCurrentPersianDay()).padStart(2, '0')}`
router.push(`/daily-report?deviceId=${savedDeviceId}&date=${encodeURIComponent(today)}`)
return
}
// No saved device — fetch user devices and auto-select the first one
api.getUserDevices(user.id)
.then((devices) => {
if (devices.length > 0) {
const firstDevice = devices[0]
// Save to localStorage
localStorage.setItem('selectedDeviceId', String(firstDevice.id))
localStorage.setItem('selectedDeviceName', firstDevice.deviceName)
const today = `${getCurrentPersianYear()}/${String(getCurrentPersianMonth()).padStart(2, '0')}/${String(getCurrentPersianDay()).padStart(2, '0')}`
router.push(`/daily-report?deviceId=${firstDevice.id}&date=${encodeURIComponent(today)}`)
} else {
// No devices — go to devices page to show the error
router.push('/devices')
}
})
.catch(() => {
// On error, fall back to devices page
router.push('/devices')
})
} catch {
// Invalid user data, go to login
}
}
}, [router])
const normalizeMobile = (mobile: string): string => {
const digitsOnly = mobile.replace(/\D/g, '')
if (digitsOnly.startsWith('9') && digitsOnly.length === 10) {
return '0' + digitsOnly
}
if (digitsOnly.startsWith('0098') && digitsOnly.length === 13) {
return '0' + digitsOnly.substring(3)
}
if (digitsOnly.startsWith('98') && digitsOnly.length === 12) {
return '0' + digitsOnly.substring(2)
}
return digitsOnly
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setError(null)
const normalizedMobile = normalizeMobile(mobile)
if (!normalizedMobile || normalizedMobile.length !== 11 || !normalizedMobile.startsWith('09')) {
setError('لطفاً شماره موبایل معتبر وارد کنید (مثال: 09123456789)')
return
}
setLoading(true)
try {
const result = await api.sendCode({ mobile: normalizedMobile })
if (result.success) {
// Redirect to verify page with mobile number
router.push(`/verify-code?mobile=${encodeURIComponent(normalizedMobile)}`)
return // Don't set loading to false — component will unmount
} else {
setError(result.message || 'خطا در ارسال کد')
}
} catch (error: unknown) {
console.error('Error sending code:', error)
setError(error instanceof Error ? error.message : 'خطا در ارتباط با سرور')
} finally {
setLoading(false)
}
}
const canSubmit = mobile.length >= 10
if (loading) {
return <Loading message="در حال ارسال کد..." />
}
return (
<div className="min-h-screen flex items-center justify-center p-4">
<div className="w-full max-w-md">
<div className="bg-white rounded-2xl shadow-xl p-8 border border-gray-100">
<div className="text-center mb-8">
<div className="inline-flex items-center justify-center w-16 h-16 bg-gradient-to-br from-green-500 to-green-600 rounded-2xl shadow-lg mb-4">
<Smartphone className="w-8 h-8 text-white" />
</div>
<h1 className="text-2xl font-bold text-gray-900 mb-2">
ورود با شماره موبایل
</h1>
<p className="text-sm text-gray-600">
شماره موبایل خود را وارد کنید تا کد فعال‌سازی برای شما ارسال شود
</p>
</div>
<form onSubmit={handleSubmit} className="space-y-5">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
شماره موبایل
</label>
<MobileInput
value={mobile}
onValueChange={(value) => {
setMobile(value)
setError(null)
}}
disabled={loading}
/>
</div>
{error && <ErrorMessage message={error} />}
<button
type="submit"
disabled={loading || !canSubmit}
className={`w-full py-3 rounded-xl text-white font-medium transition-all duration-200 flex items-center justify-center gap-2 shadow-md ${
!loading && canSubmit
? 'bg-gradient-to-r from-green-500 to-green-600 hover:from-green-600 hover:to-green-700 hover:shadow-lg transform hover:-translate-y-0.5'
: 'bg-gray-300 cursor-not-allowed'
}`}
>
{loading ? (
<>
<div className="w-5 h-5 border-2 border-white border-t-transparent rounded-full animate-spin" />
در حال ارسال...
</>
) : (
<>
ارسال کد فعال‌سازی
<ArrowLeft className="w-5 h-5" />
</>
)}
</button>
</form>
</div>
</div>
</div>
)
}