Add full SEO optimization for Spanglish social and language events

- Add comprehensive metadata to root layout with Open Graph, Twitter cards
- Create dynamic sitemap.ts for all pages and events
- Create robots.ts with proper allow/disallow rules
- Add JSON-LD Event structured data to event detail pages
- Add page-specific metadata to events, community, contact, FAQ pages
- Add FAQ structured data schema
- Update footer with local SEO text for Asunción, Paraguay
- Add web manifest for mobile SEO
- Create 404 page with proper noindex
- Optimize image alt text and add lazy loading
- Add NEXT_PUBLIC_SITE_URL env variable
- Add about/ folder to gitignore
This commit is contained in:
root
2026-01-30 21:05:25 +00:00
parent d0ea55dc5b
commit 47ba754f05
40 changed files with 2659 additions and 420 deletions
+9 -68
View File
@@ -1,36 +1,22 @@
'use client';
import { useState, useEffect, Suspense } from 'react';
import { useState, Suspense } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import Link from 'next/link';
import Script from 'next/script';
import { useLanguage } from '@/context/LanguageContext';
import { useAuth } from '@/context/AuthContext';
import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button';
import Input from '@/components/ui/Input';
import GoogleSignInButton from '@/components/GoogleSignInButton';
import { authApi } from '@/lib/api';
import toast from 'react-hot-toast';
declare global {
interface Window {
google?: {
accounts: {
id: {
initialize: (config: any) => void;
renderButton: (element: HTMLElement | null, options: any) => void;
prompt: () => void;
};
};
};
}
}
function LoginContent() {
const router = useRouter();
const searchParams = useSearchParams();
const { t, locale: language } = useLanguage();
const { login, loginWithGoogle } = useAuth();
const { login } = useAuth();
const [loading, setLoading] = useState(false);
const [loginMode, setLoginMode] = useState<'password' | 'magic-link'>('password');
const [magicLinkSent, setMagicLinkSent] = useState(false);
@@ -42,47 +28,6 @@ function LoginContent() {
// Check for redirect after login
const redirectTo = searchParams.get('redirect') || '/dashboard';
// Initialize Google Sign-In
useEffect(() => {
if (typeof window !== 'undefined' && window.google) {
initializeGoogleSignIn();
}
}, []);
const initializeGoogleSignIn = () => {
const clientId = process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID;
if (!clientId || !window.google) return;
window.google.accounts.id.initialize({
client_id: clientId,
callback: handleGoogleCallback,
});
const buttonElement = document.getElementById('google-signin-button');
if (buttonElement) {
window.google.accounts.id.renderButton(buttonElement, {
type: 'standard',
theme: 'outline',
size: 'large',
text: 'continue_with',
width: '100%',
});
}
};
const handleGoogleCallback = async (response: { credential: string }) => {
setLoading(true);
try {
await loginWithGoogle(response.credential);
toast.success(language === 'es' ? '¡Bienvenido!' : 'Welcome!');
router.push(redirectTo);
} catch (error: any) {
toast.error(error.message || (language === 'es' ? 'Error de inicio de sesión' : 'Login failed'));
} finally {
setLoading(false);
}
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
@@ -122,14 +67,7 @@ function LoginContent() {
};
return (
<>
<Script
src="https://accounts.google.com/gsi/client"
strategy="afterInteractive"
onLoad={initializeGoogleSignIn}
/>
<div className="section-padding min-h-[70vh] flex items-center">
<div className="section-padding min-h-[70vh] flex items-center">
<div className="container-page">
<div className="max-w-md mx-auto">
<div className="text-center mb-8">
@@ -139,7 +77,11 @@ function LoginContent() {
<Card className="p-8">
{/* Google Sign-In Button */}
<div id="google-signin-button" className="mb-4 flex justify-center"></div>
<GoogleSignInButton
redirectTo={redirectTo}
text="continue_with"
className="mb-4"
/>
{/* Or Divider */}
<div className="relative my-6">
@@ -266,7 +208,6 @@ function LoginContent() {
</div>
</div>
</div>
</>
);
}