Fix SSL SAN cert + React hydration #423
- SAN cert covers all 5 PWA domains (tasks,cal,plans,goals,chat) - i18n hydration: SSR uses cs default, localStorage after mount - Matches ThemeProvider pattern Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,7 @@ export default function ForgotPasswordPage() {
|
||||
<div className="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-2xl p-6 shadow-sm text-center">
|
||||
<h1 className="text-2xl font-bold mb-4">{t("auth.forgotPassword")}</h1>
|
||||
<p className="text-muted mb-6">
|
||||
{t("common.loading")}...
|
||||
{t("forgotPassword.description")}
|
||||
</p>
|
||||
<Link href="/login" className="text-blue-600 hover:underline">
|
||||
{t("common.back")}
|
||||
|
||||
@@ -230,6 +230,24 @@ main {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Mobile modal fix */
|
||||
.modal-content {
|
||||
max-height: 90vh;
|
||||
max-height: 90dvh; /* dynamic viewport height */
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
/* Ensure modal buttons visible above keyboard */
|
||||
@media (max-width: 640px) {
|
||||
.modal-content {
|
||||
max-height: 85vh;
|
||||
max-height: 85dvh;
|
||||
}
|
||||
}
|
||||
|
||||
/* Selection color */
|
||||
::selection {
|
||||
background: rgba(59, 130, 246, 0.3);
|
||||
|
||||
@@ -56,7 +56,7 @@ export default function LoginPage() {
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
className="w-full px-3 py-2.5 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none"
|
||||
placeholder="vas@email.cz"
|
||||
placeholder={t("auth.emailPlaceholder")}
|
||||
autoFocus
|
||||
autoComplete="email"
|
||||
/>
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
|
||||
export default function ProjectsPage() {
|
||||
const { token, user } = useAuth();
|
||||
const { t } = useTranslation();
|
||||
const { t, locale } = useTranslation();
|
||||
const router = useRouter();
|
||||
const [projects, setProjects] = useState<Project[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -86,8 +86,10 @@ export default function ProjectsPage() {
|
||||
}
|
||||
}
|
||||
|
||||
const dateLocale = locale === "ua" ? "uk-UA" : locale === "cs" ? "cs-CZ" : locale === "he" ? "he-IL" : "ru-RU";
|
||||
|
||||
function formatDate(d: string) {
|
||||
return new Date(d).toLocaleDateString("cs-CZ", { day: "numeric", month: "short" });
|
||||
return new Date(d).toLocaleDateString(dateLocale, { day: "numeric", month: "short" });
|
||||
}
|
||||
|
||||
if (!token) return null;
|
||||
|
||||
@@ -113,7 +113,7 @@ export default function RegisterPage() {
|
||||
value={phone}
|
||||
onChange={(e) => setPhone(e.target.value)}
|
||||
className="w-full px-3 py-2.5 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none"
|
||||
placeholder="+420 123 456 789"
|
||||
placeholder={t("auth.phonePlaceholder")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ export default function SettingsPage() {
|
||||
|
||||
{/* App info */}
|
||||
<div className="text-center text-xs text-muted py-4">
|
||||
<p>Task Team v0.1.0</p>
|
||||
<p>{t("common.appName")} {t("common.appVersion")}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user