Refactor: Implement DashboardLayout, fix mobile nav, and resolve scroll issues
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -32,3 +32,8 @@ next-env.d.ts
|
|||||||
|
|
||||||
# Security
|
# Security
|
||||||
server-settings.json
|
server-settings.json
|
||||||
|
.env
|
||||||
|
auth-otp.json
|
||||||
|
|
||||||
|
# Local dev
|
||||||
|
local_Caddyfile
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { Sidebar, Header, MobileNav } from '@/components/layout'
|
import { DashboardLayout } from '@/components/layout/DashboardLayout'
|
||||||
import { AlertPanel, useAlerts } from '@/components/alerts'
|
import { AlertPanel, useAlerts } from '@/components/alerts'
|
||||||
import { useSidebar } from '@/app/providers'
|
|
||||||
import { RefreshCw } from 'lucide-react'
|
import { RefreshCw } from 'lucide-react'
|
||||||
|
|
||||||
export default function AlertsPage() {
|
export default function AlertsPage() {
|
||||||
const { isOpen, toggle, close } = useSidebar()
|
const { regenerateAlerts, dismissAll } = useAlerts()
|
||||||
const { regenerateAlerts, dismissAll, unreadCount } = useAlerts()
|
|
||||||
|
|
||||||
const handleRegenerateAlerts = () => {
|
const handleRegenerateAlerts = () => {
|
||||||
regenerateAlerts()
|
regenerateAlerts()
|
||||||
@@ -18,16 +16,10 @@ export default function AlertsPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-slate-950">
|
<DashboardLayout title="Alertas">
|
||||||
<Sidebar isOpen={isOpen} onClose={close} unreadAlertsCount={unreadCount} />
|
<div className="space-y-6">
|
||||||
|
|
||||||
<div className="lg:ml-64 min-h-screen flex flex-col">
|
|
||||||
<Header onMenuClick={toggle} title="Alertas" />
|
|
||||||
|
|
||||||
<main className="flex-1 p-4 md:p-6 lg:p-8 pb-20 lg:pb-8">
|
|
||||||
<div className="max-w-4xl mx-auto">
|
|
||||||
{/* Action Buttons */}
|
{/* Action Buttons */}
|
||||||
<div className="flex flex-wrap gap-3 mb-6">
|
<div className="flex flex-wrap gap-3">
|
||||||
<button
|
<button
|
||||||
onClick={handleRegenerateAlerts}
|
onClick={handleRegenerateAlerts}
|
||||||
className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500/20"
|
className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500/20"
|
||||||
@@ -49,10 +41,6 @@ export default function AlertsPage() {
|
|||||||
<AlertPanel />
|
<AlertPanel />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</DashboardLayout>
|
||||||
|
|
||||||
<MobileNav unreadAlertsCount={unreadCount} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
25
app/api/auth/send/route.ts
Normal file
25
app/api/auth/send/route.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { NextResponse } from 'next/server';
|
||||||
|
import TelegramBot from 'node-telegram-bot-api';
|
||||||
|
import { generateOTP, saveOTP } from '@/lib/otp';
|
||||||
|
|
||||||
|
export async function POST() {
|
||||||
|
const token = process.env.TELEGRAM_BOT_TOKEN;
|
||||||
|
const chatId = process.env.TELEGRAM_CHAT_ID;
|
||||||
|
|
||||||
|
if (!token || !chatId) {
|
||||||
|
console.error("Telegram credentials missing");
|
||||||
|
return NextResponse.json({ error: 'Telegram not configured' }, { status: 500 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const otp = generateOTP();
|
||||||
|
saveOTP(otp);
|
||||||
|
|
||||||
|
const bot = new TelegramBot(token, { polling: false });
|
||||||
|
try {
|
||||||
|
await bot.sendMessage(chatId, `🔐 Your Login Code: ${otp}`);
|
||||||
|
return NextResponse.json({ success: true });
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('Telegram Error:', error);
|
||||||
|
return NextResponse.json({ error: 'Failed to send message: ' + error.message }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
24
app/api/auth/verify/route.ts
Normal file
24
app/api/auth/verify/route.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { NextResponse } from 'next/server';
|
||||||
|
import { verifyOTP } from '@/lib/otp';
|
||||||
|
import { cookies } from 'next/headers';
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
try {
|
||||||
|
const { code } = await req.json();
|
||||||
|
|
||||||
|
if (verifyOTP(code)) {
|
||||||
|
// Set cookie
|
||||||
|
cookies().set('auth_token', 'true', {
|
||||||
|
httpOnly: true,
|
||||||
|
secure: process.env.NODE_ENV === 'production',
|
||||||
|
maxAge: 60 * 60 * 24 * 7, // 1 week
|
||||||
|
path: '/'
|
||||||
|
});
|
||||||
|
return NextResponse.json({ success: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({ error: 'Invalid Code' }, { status: 401 });
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json({ error: 'Invalid Request' }, { status: 400 });
|
||||||
|
}
|
||||||
|
}
|
||||||
17
app/api/sync/route.ts
Normal file
17
app/api/sync/route.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { NextResponse } from 'next/server';
|
||||||
|
import { getDatabase, saveDatabase } from '@/lib/server-db';
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
const data = getDatabase();
|
||||||
|
return NextResponse.json(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
try {
|
||||||
|
const body = await req.json();
|
||||||
|
saveDatabase(body);
|
||||||
|
return NextResponse.json({ success: true });
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json({ error: 'Invalid Data' }, { status: 400 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,27 +1,12 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { Sidebar, Header, MobileNav } from '@/components/layout'
|
import { DashboardLayout } from '@/components/layout/DashboardLayout'
|
||||||
import { BudgetSection } from '@/components/budget'
|
import { BudgetSection } from '@/components/budget'
|
||||||
import { useSidebar } from '@/app/providers'
|
|
||||||
import { useAlerts } from '@/components/alerts'
|
|
||||||
|
|
||||||
export default function BudgetPage() {
|
export default function BudgetPage() {
|
||||||
const { isOpen, close, toggle } = useSidebar()
|
|
||||||
const { unreadCount } = useAlerts()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen bg-slate-950">
|
<DashboardLayout title="Presupuesto">
|
||||||
<Sidebar isOpen={isOpen} onClose={close} unreadAlertsCount={unreadCount} />
|
|
||||||
|
|
||||||
<div className="flex-1 flex flex-col min-h-screen">
|
|
||||||
<Header onMenuClick={toggle} title="Presupuesto" />
|
|
||||||
|
|
||||||
<main className="flex-1 p-4 md:p-6 lg:p-8 pb-20">
|
|
||||||
<BudgetSection />
|
<BudgetSection />
|
||||||
</main>
|
</DashboardLayout>
|
||||||
|
|
||||||
<MobileNav unreadAlertsCount={unreadCount} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,12 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Sidebar, Header, MobileNav } from '@/components/layout';
|
import { DashboardLayout } from '@/components/layout/DashboardLayout';
|
||||||
import { CardSection } from '@/components/cards';
|
import { CardSection } from '@/components/cards';
|
||||||
import { useSidebar } from '@/app/providers';
|
|
||||||
import { useAlerts } from '@/components/alerts';
|
|
||||||
|
|
||||||
export default function CardsPage() {
|
export default function CardsPage() {
|
||||||
const { isOpen, toggle, close } = useSidebar();
|
|
||||||
const { unreadCount } = useAlerts();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-slate-950">
|
<DashboardLayout title="Tarjetas de Crédito">
|
||||||
<Sidebar isOpen={isOpen} onClose={close} unreadAlertsCount={unreadCount} />
|
|
||||||
|
|
||||||
<div className="lg:ml-64 min-h-screen flex flex-col">
|
|
||||||
<Header onMenuClick={toggle} title="Tarjetas de Crédito" />
|
|
||||||
|
|
||||||
<main className="flex-1 p-4 md:p-6 lg:p-8 pb-20">
|
|
||||||
<CardSection />
|
<CardSection />
|
||||||
</main>
|
</DashboardLayout>
|
||||||
</div>
|
|
||||||
|
|
||||||
<MobileNav unreadAlertsCount={unreadCount} />
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,12 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { Sidebar, Header, MobileNav } from '@/components/layout'
|
import { DashboardLayout } from '@/components/layout/DashboardLayout'
|
||||||
import { DebtSection } from '@/components/debts'
|
import { DebtSection } from '@/components/debts'
|
||||||
import { useSidebar } from '@/app/providers'
|
|
||||||
import { useAlerts } from '@/components/alerts'
|
|
||||||
|
|
||||||
export default function DebtsPage() {
|
export default function DebtsPage() {
|
||||||
const { isOpen, close, open } = useSidebar()
|
|
||||||
const { unreadCount } = useAlerts()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-slate-950">
|
<DashboardLayout title="Deudas">
|
||||||
{/* Sidebar */}
|
|
||||||
<Sidebar isOpen={isOpen} onClose={close} unreadAlertsCount={unreadCount} />
|
|
||||||
|
|
||||||
{/* Main content */}
|
|
||||||
<div className="lg:ml-64 min-h-screen flex flex-col">
|
|
||||||
{/* Header */}
|
|
||||||
<Header onMenuClick={open} title="Deudas" />
|
|
||||||
|
|
||||||
{/* Page content */}
|
|
||||||
<main className="flex-1 p-4 md:p-6 lg:p-8 pb-20 lg:pb-8">
|
|
||||||
<DebtSection />
|
<DebtSection />
|
||||||
</main>
|
</DashboardLayout>
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Mobile Navigation */}
|
|
||||||
<MobileNav unreadAlertsCount={unreadCount} />
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
165
app/incomes/page.tsx
Normal file
165
app/incomes/page.tsx
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { useFinanzasStore } from '@/lib/store'
|
||||||
|
import { Plus, Trash2, TrendingUp, DollarSign } from 'lucide-react'
|
||||||
|
import { format } from 'date-fns'
|
||||||
|
import { es } from 'date-fns/locale'
|
||||||
|
import { DashboardLayout } from '@/components/layout/DashboardLayout'
|
||||||
|
|
||||||
|
export default function IncomesPage() {
|
||||||
|
const incomes = useFinanzasStore((state) => state.incomes) || []
|
||||||
|
const addIncome = useFinanzasStore((state) => state.addIncome)
|
||||||
|
const removeIncome = useFinanzasStore((state) => state.removeIncome)
|
||||||
|
|
||||||
|
const [newIncome, setNewIncome] = useState({
|
||||||
|
amount: '',
|
||||||
|
description: '',
|
||||||
|
category: 'salary' as const,
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleAdd = () => {
|
||||||
|
if (!newIncome.amount || !newIncome.description) return
|
||||||
|
|
||||||
|
addIncome({
|
||||||
|
amount: parseFloat(newIncome.amount),
|
||||||
|
description: newIncome.description,
|
||||||
|
category: newIncome.category,
|
||||||
|
date: new Date().toISOString(),
|
||||||
|
})
|
||||||
|
setNewIncome({ amount: '', description: '', category: 'salary' })
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalIncomes = incomes.reduce((acc, curr) => acc + curr.amount, 0)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DashboardLayout title="Ingresos">
|
||||||
|
<div className="space-y-6">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<h2 className="text-3xl font-bold flex items-center gap-2 text-white">
|
||||||
|
<TrendingUp className="text-green-500" /> Ingresos
|
||||||
|
</h2>
|
||||||
|
<div className="text-right">
|
||||||
|
<p className="text-sm text-gray-400">Total Acumulado</p>
|
||||||
|
<p className="text-2xl font-bold text-green-400">
|
||||||
|
${totalIncomes.toLocaleString()}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid md:grid-cols-3 gap-6">
|
||||||
|
{/* Formulario */}
|
||||||
|
<div className="bg-slate-800 border border-slate-700 rounded-xl md:col-span-1 h-fit overflow-hidden">
|
||||||
|
<div className="p-6 border-b border-slate-700">
|
||||||
|
<h3 className="font-semibold text-lg text-white">Nuevo Ingreso</h3>
|
||||||
|
</div>
|
||||||
|
<div className="p-6 space-y-4">
|
||||||
|
<div>
|
||||||
|
<label className="text-sm text-gray-400 block mb-2">Descripción</label>
|
||||||
|
<input
|
||||||
|
placeholder="Ej. Pago Freelance"
|
||||||
|
value={newIncome.description}
|
||||||
|
onChange={(e) =>
|
||||||
|
setNewIncome({ ...newIncome, description: e.target.value })
|
||||||
|
}
|
||||||
|
className="w-full bg-slate-700 border-slate-600 border rounded-lg px-3 py-2 text-white focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="text-sm text-gray-400 block mb-2">Monto</label>
|
||||||
|
<div className="relative">
|
||||||
|
<DollarSign className="absolute left-3 top-2.5 h-4 w-4 text-gray-400" />
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
placeholder="0.00"
|
||||||
|
value={newIncome.amount}
|
||||||
|
onChange={(e) =>
|
||||||
|
setNewIncome({ ...newIncome, amount: e.target.value })
|
||||||
|
}
|
||||||
|
className="w-full pl-9 bg-slate-700 border-slate-600 border rounded-lg px-3 py-2 text-white focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="text-sm text-gray-400 block mb-2">Categoría</label>
|
||||||
|
<select
|
||||||
|
className="w-full bg-slate-700 border border-slate-600 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
||||||
|
value={newIncome.category}
|
||||||
|
onChange={(e) =>
|
||||||
|
setNewIncome({
|
||||||
|
...newIncome,
|
||||||
|
category: e.target.value as any,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<option value="salary">Salario</option>
|
||||||
|
<option value="freelance">Freelance</option>
|
||||||
|
<option value="business">Negocio</option>
|
||||||
|
<option value="gift">Regalo</option>
|
||||||
|
<option value="other">Otro</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={handleAdd}
|
||||||
|
className="w-full bg-emerald-600 hover:bg-emerald-700 text-white font-semibold py-2 px-4 rounded-lg flex items-center justify-center gap-2 transition-colors"
|
||||||
|
>
|
||||||
|
<Plus className="w-4 h-4" /> Agregar Ingreso
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Lista */}
|
||||||
|
<div className="bg-slate-800 border border-slate-700 rounded-xl md:col-span-2 overflow-hidden">
|
||||||
|
<div className="p-6 border-b border-slate-700">
|
||||||
|
<h3 className="font-semibold text-lg text-white">Historial de Ingresos</h3>
|
||||||
|
</div>
|
||||||
|
<div className="p-6">
|
||||||
|
{incomes.length === 0 ? (
|
||||||
|
<p className="text-center text-gray-500 py-8">
|
||||||
|
No hay ingresos registrados aún.
|
||||||
|
</p>
|
||||||
|
) : (
|
||||||
|
<div className="space-y-4">
|
||||||
|
{incomes
|
||||||
|
.sort(
|
||||||
|
(a, b) =>
|
||||||
|
new Date(b.date).getTime() - new Date(a.date).getTime()
|
||||||
|
)
|
||||||
|
.map((income) => (
|
||||||
|
<div
|
||||||
|
key={income.id}
|
||||||
|
className="flex items-center justify-between p-4 bg-slate-700/50 rounded-lg border border-slate-700 hover:border-slate-600 transition-colors"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<p className="font-semibold text-white">
|
||||||
|
{income.description}
|
||||||
|
</p>
|
||||||
|
<p className="text-xs text-gray-400 capitalize">
|
||||||
|
{income.category} •{' '}
|
||||||
|
{format(new Date(income.date), "d 'de' MMMM", {
|
||||||
|
locale: es,
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<span className="text-emerald-400 font-mono font-bold">
|
||||||
|
+${income.amount.toLocaleString()}
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
onClick={() => removeIncome(income.id)}
|
||||||
|
className="text-slate-500 hover:text-red-400 transition-colors"
|
||||||
|
>
|
||||||
|
<Trash2 className="w-4 h-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DashboardLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
115
app/login/page.tsx
Normal file
115
app/login/page.tsx
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
import { Lock, Send, Loader2 } from 'lucide-react';
|
||||||
|
|
||||||
|
export default function LoginPage() {
|
||||||
|
const [step, setStep] = useState<'initial' | 'verify'>('initial');
|
||||||
|
const [code, setCode] = useState('');
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [error, setError] = useState('');
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const sendCode = async () => {
|
||||||
|
setLoading(true);
|
||||||
|
setError('');
|
||||||
|
try {
|
||||||
|
const res = await fetch('/api/auth/send', { method: 'POST' });
|
||||||
|
const data = await res.json();
|
||||||
|
if (!res.ok) throw new Error(data.error || 'Failed to send code');
|
||||||
|
setStep('verify');
|
||||||
|
} catch (err: any) {
|
||||||
|
setError(err.message);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const verifyCode = async () => {
|
||||||
|
setLoading(true);
|
||||||
|
setError('');
|
||||||
|
try {
|
||||||
|
const res = await fetch('/api/auth/verify', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ code })
|
||||||
|
});
|
||||||
|
const data = await res.json();
|
||||||
|
if (!res.ok) throw new Error(data.error || 'Invalid code');
|
||||||
|
|
||||||
|
// Redirect
|
||||||
|
router.push('/');
|
||||||
|
router.refresh();
|
||||||
|
} catch (err: any) {
|
||||||
|
setError(err.message);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex min-h-screen items-center justify-center bg-gray-900 text-white p-4">
|
||||||
|
<div className="w-full max-w-md bg-gray-800 rounded-lg shadow-xl p-8 border border-gray-700">
|
||||||
|
<div className="flex flex-col items-center mb-8">
|
||||||
|
<div className="bg-blue-600 p-3 rounded-full mb-4">
|
||||||
|
<Lock className="w-8 h-8 text-white" />
|
||||||
|
</div>
|
||||||
|
<h1 className="text-2xl font-bold">Secure Access</h1>
|
||||||
|
<p className="text-gray-400 mt-2 text-center">
|
||||||
|
Finanzas Personales
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{error && (
|
||||||
|
<div className="bg-red-900/50 border border-red-500 text-red-200 p-3 rounded mb-4 text-sm">
|
||||||
|
{error}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{step === 'initial' ? (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<p className="text-gray-300 text-center text-sm">
|
||||||
|
Click below to receive a login code via Telegram.
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
onClick={sendCode}
|
||||||
|
disabled={loading}
|
||||||
|
className="w-full bg-blue-600 hover:bg-blue-500 text-white font-semibold py-3 px-4 rounded-lg transition flex items-center justify-center gap-2 disabled:opacity-50"
|
||||||
|
>
|
||||||
|
{loading ? <Loader2 className="animate-spin" /> : <Send size={20} />}
|
||||||
|
Send Code to Telegram
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<p className="text-gray-300 text-center text-sm">
|
||||||
|
Enter the 6-digit code sent to your Telegram.
|
||||||
|
</p>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={code}
|
||||||
|
onChange={(e) => setCode(e.target.value)}
|
||||||
|
placeholder="123456"
|
||||||
|
className="w-full bg-gray-700 border border-gray-600 rounded-lg px-4 py-3 text-center text-2xl tracking-widest focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
maxLength={6}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onClick={verifyCode}
|
||||||
|
disabled={loading || code.length < 4}
|
||||||
|
className="w-full bg-green-600 hover:bg-green-500 text-white font-semibold py-3 px-4 rounded-lg transition flex items-center justify-center gap-2 disabled:opacity-50"
|
||||||
|
>
|
||||||
|
{loading ? <Loader2 className="animate-spin" /> : 'Verify & Login'}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setStep('initial')}
|
||||||
|
className="w-full text-gray-400 hover:text-white text-sm"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
50
app/page.tsx
50
app/page.tsx
@@ -1,25 +1,21 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { Sidebar, Header, MobileNav } from '@/components/layout'
|
|
||||||
import { SummarySection, QuickActions, RecentActivity } from '@/components/dashboard'
|
import { SummarySection, QuickActions, RecentActivity } from '@/components/dashboard'
|
||||||
import { useSidebar } from '@/app/providers'
|
|
||||||
import { useFinanzasStore } from '@/lib/store'
|
import { useFinanzasStore } from '@/lib/store'
|
||||||
import { AlertBanner, useAlerts } from '@/components/alerts'
|
import { AlertBanner, useAlerts } from '@/components/alerts'
|
||||||
import { AddDebtModal } from '@/components/modals/AddDebtModal'
|
import { AddDebtModal } from '@/components/modals/AddDebtModal'
|
||||||
import { AddCardModal } from '@/components/modals/AddCardModal'
|
import { AddCardModal } from '@/components/modals/AddCardModal'
|
||||||
import { AddPaymentModal } from '@/components/modals/AddPaymentModal'
|
import { AddPaymentModal } from '@/components/modals/AddPaymentModal'
|
||||||
|
import { DashboardLayout } from '@/components/layout/DashboardLayout'
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
// Sidebar control
|
|
||||||
const sidebar = useSidebar()
|
|
||||||
|
|
||||||
// Datos del store
|
// Datos del store
|
||||||
const markAlertAsRead = useFinanzasStore((state) => state.markAlertAsRead)
|
const markAlertAsRead = useFinanzasStore((state) => state.markAlertAsRead)
|
||||||
const deleteAlert = useFinanzasStore((state) => state.deleteAlert)
|
const deleteAlert = useFinanzasStore((state) => state.deleteAlert)
|
||||||
|
|
||||||
// Alertas
|
// Alertas
|
||||||
const { unreadAlerts, unreadCount, regenerateAlerts } = useAlerts()
|
const { unreadAlerts, regenerateAlerts } = useAlerts()
|
||||||
|
|
||||||
// Estados locales para modales
|
// Estados locales para modales
|
||||||
const [isAddDebtModalOpen, setIsAddDebtModalOpen] = useState(false)
|
const [isAddDebtModalOpen, setIsAddDebtModalOpen] = useState(false)
|
||||||
@@ -31,23 +27,6 @@ export default function Home() {
|
|||||||
regenerateAlerts()
|
regenerateAlerts()
|
||||||
}, [regenerateAlerts])
|
}, [regenerateAlerts])
|
||||||
|
|
||||||
// Efecto para manejar resize de ventana
|
|
||||||
useEffect(() => {
|
|
||||||
const handleResize = () => {
|
|
||||||
if (window.innerWidth >= 1024) {
|
|
||||||
sidebar.open()
|
|
||||||
} else {
|
|
||||||
sidebar.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Estado inicial
|
|
||||||
handleResize()
|
|
||||||
|
|
||||||
window.addEventListener('resize', handleResize)
|
|
||||||
return () => window.removeEventListener('resize', handleResize)
|
|
||||||
}, [sidebar])
|
|
||||||
|
|
||||||
// Handlers para modales
|
// Handlers para modales
|
||||||
const handleAddDebt = () => {
|
const handleAddDebt = () => {
|
||||||
setIsAddDebtModalOpen(true)
|
setIsAddDebtModalOpen(true)
|
||||||
@@ -65,22 +44,8 @@ export default function Home() {
|
|||||||
const topAlerts = unreadAlerts.slice(0, 3)
|
const topAlerts = unreadAlerts.slice(0, 3)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen bg-slate-950">
|
<DashboardLayout title="Dashboard">
|
||||||
{/* Sidebar */}
|
<div className="space-y-6">
|
||||||
<Sidebar
|
|
||||||
isOpen={sidebar.isOpen}
|
|
||||||
onClose={sidebar.close}
|
|
||||||
unreadAlertsCount={unreadCount}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Main content */}
|
|
||||||
<div className="flex flex-1 flex-col lg:ml-0">
|
|
||||||
{/* Header */}
|
|
||||||
<Header onMenuClick={sidebar.toggle} title="Dashboard" />
|
|
||||||
|
|
||||||
{/* Main content area */}
|
|
||||||
<main className="flex-1 p-4 md:p-6 lg:p-8 pb-20 lg:pb-8">
|
|
||||||
<div className="mx-auto max-w-7xl space-y-6">
|
|
||||||
{/* Alertas destacadas */}
|
{/* Alertas destacadas */}
|
||||||
{topAlerts.length > 0 && (
|
{topAlerts.length > 0 && (
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
@@ -108,11 +73,6 @@ export default function Home() {
|
|||||||
{/* Actividad reciente */}
|
{/* Actividad reciente */}
|
||||||
<RecentActivity limit={5} />
|
<RecentActivity limit={5} />
|
||||||
</div>
|
</div>
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Mobile navigation */}
|
|
||||||
<MobileNav unreadAlertsCount={unreadCount} />
|
|
||||||
|
|
||||||
{/* Modales */}
|
{/* Modales */}
|
||||||
<AddDebtModal
|
<AddDebtModal
|
||||||
@@ -129,6 +89,6 @@ export default function Home() {
|
|||||||
isOpen={isAddPaymentModalOpen}
|
isOpen={isAddPaymentModalOpen}
|
||||||
onClose={() => setIsAddPaymentModalOpen(false)}
|
onClose={() => setIsAddPaymentModalOpen(false)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</DashboardLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { createContext, useContext, useState, ReactNode } from "react";
|
import { createContext, useContext, useState, ReactNode } from "react";
|
||||||
|
import { DataSync } from "@/components/DataSync";
|
||||||
|
|
||||||
interface SidebarContextType {
|
interface SidebarContextType {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@@ -27,6 +28,7 @@ export function Providers({ children }: { children: ReactNode }) {
|
|||||||
open: openSidebar,
|
open: openSidebar,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<DataSync />
|
||||||
{children}
|
{children}
|
||||||
</SidebarContext.Provider>
|
</SidebarContext.Provider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { formatCurrency } from '@/lib/utils'
|
|||||||
import { Zap, Droplets, Flame, Wifi, TrendingUp, TrendingDown, Plus, History } from 'lucide-react'
|
import { Zap, Droplets, Flame, Wifi, TrendingUp, TrendingDown, Plus, History } from 'lucide-react'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
import { AddServiceModal } from '@/components/modals/AddServiceModal'
|
import { AddServiceModal } from '@/components/modals/AddServiceModal'
|
||||||
|
import { DashboardLayout } from '@/components/layout/DashboardLayout'
|
||||||
|
|
||||||
const SERVICES = [
|
const SERVICES = [
|
||||||
{ id: 'electricity', label: 'Luz (Electricidad)', icon: Zap, color: 'text-yellow-400', bg: 'bg-yellow-400/10' },
|
{ id: 'electricity', label: 'Luz (Electricidad)', icon: Zap, color: 'text-yellow-400', bg: 'bg-yellow-400/10' },
|
||||||
@@ -20,12 +21,13 @@ export default function ServicesPage() {
|
|||||||
const [isAddModalOpen, setIsAddModalOpen] = useState(false)
|
const [isAddModalOpen, setIsAddModalOpen] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<DashboardLayout title="Servicios">
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
|
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-2xl font-bold text-white">Servicios y Predicciones</h1>
|
<h2 className="text-2xl font-bold text-white">Servicios y Predicciones</h2>
|
||||||
<p className="text-slate-400 text-sm">Gestiona tus consumos de Luz, Agua y Gas.</p>
|
<p className="text-slate-400 text-sm">Gestiona tus consumos de Luz, Agua y Gas.</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@@ -138,5 +140,6 @@ export default function ServicesPage() {
|
|||||||
|
|
||||||
<AddServiceModal isOpen={isAddModalOpen} onClose={() => setIsAddModalOpen(false)} />
|
<AddServiceModal isOpen={isAddModalOpen} onClose={() => setIsAddModalOpen(false)} />
|
||||||
</div>
|
</div>
|
||||||
|
</DashboardLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useState, useEffect } from 'react'
|
|||||||
import { Save, Plus, Trash2, Bot, MessageSquare, Key, Link as LinkIcon, Lock, Send, CheckCircle2, XCircle, Loader2, Sparkles, Box } from 'lucide-react'
|
import { Save, Plus, Trash2, Bot, MessageSquare, Key, Link as LinkIcon, Lock, Send, CheckCircle2, XCircle, Loader2, Sparkles, Box } from 'lucide-react'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
import { AIServiceConfig, AppSettings } from '@/lib/types'
|
import { AIServiceConfig, AppSettings } from '@/lib/types'
|
||||||
|
import { DashboardLayout } from '@/components/layout/DashboardLayout'
|
||||||
|
|
||||||
export default function SettingsPage() {
|
export default function SettingsPage() {
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
@@ -159,11 +160,12 @@ export default function SettingsPage() {
|
|||||||
if (loading) return <div className="p-8 text-center text-slate-400">Cargando configuración...</div>
|
if (loading) return <div className="p-8 text-center text-slate-400">Cargando configuración...</div>
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<DashboardLayout title="Configuración">
|
||||||
<div className="max-w-4xl mx-auto space-y-8 pb-10">
|
<div className="max-w-4xl mx-auto space-y-8 pb-10">
|
||||||
|
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-2xl font-bold text-white">Configuración</h1>
|
<h2 className="text-2xl font-bold text-white">Configuración</h2>
|
||||||
<p className="text-slate-400 text-sm">Gestiona la integración con Telegram e Inteligencia Artificial.</p>
|
<p className="text-slate-400 text-sm">Gestiona la integración con Telegram e Inteligencia Artificial.</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@@ -365,5 +367,6 @@ export default function SettingsPage() {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
</DashboardLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
64
components/DataSync.tsx
Normal file
64
components/DataSync.tsx
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useEffect, useRef } from 'react';
|
||||||
|
import { useFinanzasStore } from '@/lib/store';
|
||||||
|
|
||||||
|
export function DataSync() {
|
||||||
|
// const isHydrated = useFinanzasStore(state => state._hasHydrated);
|
||||||
|
const store = useFinanzasStore();
|
||||||
|
const initialized = useRef(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function init() {
|
||||||
|
if (initialized.current) return;
|
||||||
|
initialized.current = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch('/api/sync');
|
||||||
|
if (!res.ok) return;
|
||||||
|
const serverData = await res.json();
|
||||||
|
|
||||||
|
// Simple logic: if server has data (debts or cards or something), trust server.
|
||||||
|
const hasServerData = serverData.fixedDebts?.length > 0 || serverData.creditCards?.length > 0;
|
||||||
|
|
||||||
|
if (hasServerData) {
|
||||||
|
console.log("Sync: Hydrating from Server");
|
||||||
|
useFinanzasStore.setState(serverData);
|
||||||
|
} else {
|
||||||
|
// Server is empty, but we might have local data.
|
||||||
|
// Push local data to server to initialize it.
|
||||||
|
console.log("Sync: Initializing Server with Local Data");
|
||||||
|
syncToServer(useFinanzasStore.getState());
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Sync init error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Sync on change
|
||||||
|
useEffect(() => {
|
||||||
|
if (!initialized.current) return;
|
||||||
|
|
||||||
|
const unsub = useFinanzasStore.subscribe((state) => {
|
||||||
|
syncToServer(state);
|
||||||
|
});
|
||||||
|
return () => unsub();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let timeout: NodeJS.Timeout;
|
||||||
|
function syncToServer(state: any) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(() => {
|
||||||
|
fetch('/api/sync', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type': 'application/json'},
|
||||||
|
body: JSON.stringify(state)
|
||||||
|
}).catch(e => console.error("Sync error", e));
|
||||||
|
}, 2000); // Debounce 2s
|
||||||
|
}
|
||||||
60
components/layout/DashboardLayout.tsx
Normal file
60
components/layout/DashboardLayout.tsx
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { ReactNode, useEffect } from 'react'
|
||||||
|
import { Sidebar, Header, MobileNav } from '@/components/layout'
|
||||||
|
import { useSidebar } from '@/app/providers'
|
||||||
|
import { useAlerts } from '@/components/alerts'
|
||||||
|
|
||||||
|
interface DashboardLayoutProps {
|
||||||
|
children: ReactNode
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DashboardLayout({ children, title }: DashboardLayoutProps) {
|
||||||
|
const { isOpen, toggle, close, open } = useSidebar()
|
||||||
|
const { unreadCount } = useAlerts()
|
||||||
|
|
||||||
|
// Ensure sidebar is open on desktop mount
|
||||||
|
useEffect(() => {
|
||||||
|
const handleResize = () => {
|
||||||
|
if (window.innerWidth >= 1024) {
|
||||||
|
open()
|
||||||
|
} else {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initial check
|
||||||
|
handleResize()
|
||||||
|
|
||||||
|
window.addEventListener('resize', handleResize)
|
||||||
|
return () => window.removeEventListener('resize', handleResize)
|
||||||
|
}, [open, close])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex min-h-screen bg-slate-950">
|
||||||
|
{/* Sidebar */}
|
||||||
|
<Sidebar
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={close}
|
||||||
|
unreadAlertsCount={unreadCount}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Main content wrapper */}
|
||||||
|
<div className="flex flex-1 flex-col lg:ml-0 min-w-0">
|
||||||
|
{/* Header */}
|
||||||
|
<Header onMenuClick={toggle} title={title} />
|
||||||
|
|
||||||
|
{/* Page content */}
|
||||||
|
<main className="flex-1 p-4 md:p-6 lg:p-8 pb-24 lg:pb-8">
|
||||||
|
<div className="mx-auto max-w-7xl h-full">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Navigation */}
|
||||||
|
<MobileNav unreadAlertsCount={unreadCount} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
Bell,
|
Bell,
|
||||||
Lightbulb,
|
Lightbulb,
|
||||||
Settings,
|
Settings,
|
||||||
|
TrendingUp,
|
||||||
X,
|
X,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
@@ -22,6 +23,7 @@ interface SidebarProps {
|
|||||||
|
|
||||||
const navigationItems = [
|
const navigationItems = [
|
||||||
{ name: 'Dashboard', href: '/', icon: LayoutDashboard },
|
{ name: 'Dashboard', href: '/', icon: LayoutDashboard },
|
||||||
|
{ name: 'Ingresos', href: '/incomes', icon: TrendingUp },
|
||||||
{ name: 'Deudas', href: '/debts', icon: Wallet },
|
{ name: 'Deudas', href: '/debts', icon: Wallet },
|
||||||
{ name: 'Tarjetas', href: '/cards', icon: CreditCard },
|
{ name: 'Tarjetas', href: '/cards', icon: CreditCard },
|
||||||
{ name: 'Presupuesto', href: '/budget', icon: PiggyBank },
|
{ name: 'Presupuesto', href: '/budget', icon: PiggyBank },
|
||||||
|
|||||||
29
data/db.json
Normal file
29
data/db.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"fixedDebts": [],
|
||||||
|
"variableDebts": [
|
||||||
|
{
|
||||||
|
"name": "netflix",
|
||||||
|
"amount": 5000,
|
||||||
|
"date": "2026-01-29T00:00:00.000Z",
|
||||||
|
"category": "shopping",
|
||||||
|
"isPaid": false,
|
||||||
|
"id": "f2e424ca-5f07-4f57-9386-822354e0ee1e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "youtube",
|
||||||
|
"amount": 2500,
|
||||||
|
"date": "2026-01-29T00:00:00.000Z",
|
||||||
|
"category": "shopping",
|
||||||
|
"isPaid": false,
|
||||||
|
"id": "621c3caf-529b-4c33-b46f-3d86b119dd75"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"creditCards": [],
|
||||||
|
"cardPayments": [],
|
||||||
|
"monthlyBudgets": [],
|
||||||
|
"currentMonth": 1,
|
||||||
|
"currentYear": 2026,
|
||||||
|
"alerts": [],
|
||||||
|
"serviceBills": [],
|
||||||
|
"incomes": []
|
||||||
|
}
|
||||||
1
dist/404.html
vendored
Normal file
1
dist/404.html
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/4SrcMtBIfNF-pqHyUpitS/_buildManifest.js
vendored
Normal file
1
dist/_next/static/4SrcMtBIfNF-pqHyUpitS/_buildManifest.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
self.__BUILD_MANIFEST={__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/_error":["static/chunks/pages/_error-7ba65e1336b92748.js"],sortedPages:["/_app","/_error"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
||||||
1
dist/_next/static/4SrcMtBIfNF-pqHyUpitS/_ssgManifest.js
vendored
Normal file
1
dist/_next/static/4SrcMtBIfNF-pqHyUpitS/_ssgManifest.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
self.__SSG_MANIFEST=new Set([]);self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()
|
||||||
2
dist/_next/static/chunks/117-14b82d0a7edfd352.js
vendored
Normal file
2
dist/_next/static/chunks/117-14b82d0a7edfd352.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/489-4b7fe4fae3b6ef80.js
vendored
Normal file
1
dist/_next/static/chunks/489-4b7fe4fae3b6ef80.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/697-93a9cd29100d0d50.js
vendored
Normal file
1
dist/_next/static/chunks/697-93a9cd29100d0d50.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/71-fccb418814321416.js
vendored
Normal file
1
dist/_next/static/chunks/71-fccb418814321416.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[71],{2489:function(e,t,r){r.d(t,{Z:function(){return n}});let n=(0,r(8755).Z)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]])},4147:function(e,t,r){let n;r.d(t,{Z:function(){return u}});var o={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};let a=new Uint8Array(16),i=[];for(let e=0;e<256;++e)i.push((e+256).toString(16).slice(1));var u=function(e,t,r){return!o.randomUUID||t||e?function(e,t,r){let o=(e=e||{}).random??e.rng?.()??function(){if(!n){if("undefined"==typeof crypto||!crypto.getRandomValues)throw Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");n=crypto.getRandomValues.bind(crypto)}return n(a)}();if(o.length<16)throw Error("Random bytes length must be >= 16");if(o[6]=15&o[6]|64,o[8]=63&o[8]|128,t){if((r=r||0)<0||r+16>t.length)throw RangeError(`UUID byte range ${r}:${r+15} is out of buffer bounds`);for(let e=0;e<16;++e)t[r+e]=o[e];return t}return function(e,t=0){return(i[e[t+0]]+i[e[t+1]]+i[e[t+2]]+i[e[t+3]]+"-"+i[e[t+4]]+i[e[t+5]]+"-"+i[e[t+6]]+i[e[t+7]]+"-"+i[e[t+8]]+i[e[t+9]]+"-"+i[e[t+10]]+i[e[t+11]]+i[e[t+12]]+i[e[t+13]]+i[e[t+14]]+i[e[t+15]]).toLowerCase()}(o)}(e,t,r):o.randomUUID()}},6885:function(e,t,r){r.d(t,{tJ:function(){return o}});let n=e=>t=>{try{let r=e(t);if(r instanceof Promise)return r;return{then:e=>n(e)(r),catch(e){return this}}}catch(e){return{then(e){return this},catch:t=>n(t)(e)}}},o=(e,t)=>(r,o,a)=>{let i,u={storage:function(e,t){let r;try{r=e()}catch(e){return}return{getItem:e=>{var t;let n=e=>null===e?null:JSON.parse(e,void 0),o=null!=(t=r.getItem(e))?t:null;return o instanceof Promise?o.then(n):n(o)},setItem:(e,t)=>r.setItem(e,JSON.stringify(t,void 0)),removeItem:e=>r.removeItem(e)}}(()=>localStorage),partialize:e=>e,version:0,merge:(e,t)=>({...t,...e}),...t},l=!1,s=0,c=new Set,d=new Set,f=u.storage;if(!f)return e((...e)=>{console.warn(`[zustand persist middleware] Unable to update item '${u.name}', the given storage is currently unavailable.`),r(...e)},o,a);let m=()=>{let e=u.partialize({...o()});return f.setItem(u.name,{state:e,version:u.version})},g=a.setState;a.setState=(e,t)=>(g(e,t),m());let h=e((...e)=>(r(...e),m()),o,a);a.getInitialState=()=>h;let p=()=>{var e,t;if(!f)return;let a=++s;l=!1,c.forEach(e=>{var t;return e(null!=(t=o())?t:h)});let g=(null==(t=u.onRehydrateStorage)?void 0:t.call(u,null!=(e=o())?e:h))||void 0;return n(f.getItem.bind(f))(u.name).then(e=>{if(e){if("number"!=typeof e.version||e.version===u.version)return[!1,e.state];if(u.migrate){let t=u.migrate(e.state,e.version);return t instanceof Promise?t.then(e=>[!0,e]):[!0,t]}console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}return[!1,void 0]}).then(e=>{var t;if(a!==s)return;let[n,l]=e;if(r(i=u.merge(l,null!=(t=o())?t:h),!0),n)return m()}).then(()=>{a===s&&(null==g||g(i,void 0),i=o(),l=!0,d.forEach(e=>e(i)))}).catch(e=>{a===s&&(null==g||g(void 0,e))})};return a.persist={setOptions:e=>{u={...u,...e},e.storage&&(f=e.storage)},clearStorage:()=>{null==f||f.removeItem(u.name)},getOptions:()=>u,rehydrate:()=>p(),hasHydrated:()=>l,onHydrate:e=>(c.add(e),()=>{c.delete(e)}),onFinishHydration:e=>(d.add(e),()=>{d.delete(e)})},u.skipHydration||p(),i||h}},3011:function(e,t,r){r.d(t,{U:function(){return l}});var n=r(2265);let o=e=>{let t;let r=new Set,n=(e,n)=>{let o="function"==typeof e?e(t):e;if(!Object.is(o,t)){let e=t;t=(null!=n?n:"object"!=typeof o||null===o)?o:Object.assign({},t,o),r.forEach(r=>r(t,e))}},o=()=>t,a={setState:n,getState:o,getInitialState:()=>i,subscribe:e=>(r.add(e),()=>r.delete(e))},i=t=e(n,o,a);return a},a=e=>e?o(e):o,i=e=>e,u=e=>{let t=a(e),r=e=>(function(e,t=i){let r=n.useSyncExternalStore(e.subscribe,n.useCallback(()=>t(e.getState()),[e,t]),n.useCallback(()=>t(e.getInitialState()),[e,t]));return n.useDebugValue(r),r})(t,e);return Object.assign(r,t),r},l=e=>e?u(e):u}}]);
|
||||||
1
dist/_next/static/chunks/796-9d56fd2c469c90a6.js
vendored
Normal file
1
dist/_next/static/chunks/796-9d56fd2c469c90a6.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/838-3b22f3c21887b523.js
vendored
Normal file
1
dist/_next/static/chunks/838-3b22f3c21887b523.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/app/_not-found/page-e30cecccd190b7d4.js
vendored
Normal file
1
dist/_next/static/chunks/app/_not-found/page-e30cecccd190b7d4.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[409],{7589:function(e,t,n){(window.__NEXT_P=window.__NEXT_P||[]).push(["/_not-found/page",function(){return n(3634)}])},3634:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return s}}),n(7043);let i=n(7437);n(2265);let o={fontFamily:'system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"',height:"100vh",textAlign:"center",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},l={display:"inline-block"},r={display:"inline-block",margin:"0 20px 0 0",padding:"0 23px 0 0",fontSize:24,fontWeight:500,verticalAlign:"top",lineHeight:"49px"},d={fontSize:14,fontWeight:400,lineHeight:"49px",margin:0};function s(){return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("title",{children:"404: This page could not be found."}),(0,i.jsx)("div",{style:o,children:(0,i.jsxs)("div",{children:[(0,i.jsx)("style",{dangerouslySetInnerHTML:{__html:"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}),(0,i.jsx)("h1",{className:"next-error-h1",style:r,children:"404"}),(0,i.jsx)("div",{style:l,children:(0,i.jsx)("h2",{style:d,children:"This page could not be found."})})]})})]})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)}},function(e){e.O(0,[971,117,744],function(){return e(e.s=7589)}),_N_E=e.O()}]);
|
||||||
1
dist/_next/static/chunks/app/alerts/page-6f170ee2c75a0961.js
vendored
Normal file
1
dist/_next/static/chunks/app/alerts/page-6f170ee2c75a0961.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[78],{4033:function(e,s,n){Promise.resolve().then(n.bind(n,5949))},5949:function(e,s,n){"use strict";n.r(s),n.d(s,{default:function(){return c}});var l=n(7437),t=n(553),i=n(3263),a=n(9294);let r=(0,n(8755).Z)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);function c(){let{isOpen:e,toggle:s,close:n}=(0,a.A)(),{regenerateAlerts:c,dismissAll:o,unreadCount:u}=(0,i.Z7)();return(0,l.jsxs)("div",{className:"min-h-screen bg-slate-950",children:[(0,l.jsx)(t.YE,{isOpen:e,onClose:n,unreadAlertsCount:u}),(0,l.jsxs)("div",{className:"lg:ml-64 min-h-screen flex flex-col",children:[(0,l.jsx)(t.h4,{onMenuClick:s,title:"Alertas"}),(0,l.jsx)("main",{className:"flex-1 p-4 md:p-6 lg:p-8 pb-20 lg:pb-8",children:(0,l.jsxs)("div",{className:"max-w-4xl mx-auto",children:[(0,l.jsxs)("div",{className:"flex flex-wrap gap-3 mb-6",children:[(0,l.jsxs)("button",{onClick:()=>{c()},className:"inline-flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500/20",children:[(0,l.jsx)(r,{className:"h-4 w-4"}),"Regenerar Alertas"]}),(0,l.jsx)("button",{onClick:()=>{o()},className:"inline-flex items-center gap-2 px-4 py-2 bg-slate-800 hover:bg-slate-700 text-slate-300 hover:text-white text-sm font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-slate-500/20",children:"Limpiar Todas"})]}),(0,l.jsx)("div",{className:"w-full",children:(0,l.jsx)(i.KG,{})})]})}),(0,l.jsx)(t.zM,{unreadAlertsCount:u})]})]})}}},function(e){e.O(0,[697,71,796,489,971,117,744],function(){return e(e.s=4033)}),_N_E=e.O()}]);
|
||||||
1
dist/_next/static/chunks/app/budget/page-1c1157916eee3b45.js
vendored
Normal file
1
dist/_next/static/chunks/app/budget/page-1c1157916eee3b45.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/app/cards/page-a9843d3be56b680d.js
vendored
Normal file
1
dist/_next/static/chunks/app/cards/page-a9843d3be56b680d.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/app/debts/page-28aedff94a342b70.js
vendored
Normal file
1
dist/_next/static/chunks/app/debts/page-28aedff94a342b70.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/app/layout-639440f4d8b9b6b3.js
vendored
Normal file
1
dist/_next/static/chunks/app/layout-639440f4d8b9b6b3.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[185],{1556:function(e,n,t){Promise.resolve().then(t.bind(t,9294)),Promise.resolve().then(t.t.bind(t,8925,23)),Promise.resolve().then(t.t.bind(t,7960,23))},9294:function(e,n,t){"use strict";t.d(n,{A:function(){return u},Providers:function(){return s}});var r=t(7437),o=t(2265);let i=(0,o.createContext)(void 0);function s(e){let{children:n}=e,[t,s]=(0,o.useState)(!0);return(0,r.jsx)(i.Provider,{value:{isOpen:t,toggle:()=>s(e=>!e),close:()=>s(!1),open:()=>s(!0)},children:n})}function u(){let e=(0,o.useContext)(i);if(void 0===e)throw Error("useSidebar must be used within a Providers");return e}},7960:function(){},8925:function(e){e.exports={style:{fontFamily:"'__Inter_f367f3', '__Inter_Fallback_f367f3'",fontStyle:"normal"},className:"__className_f367f3",variable:"__variable_f367f3"}}},function(e){e.O(0,[832,971,117,744],function(){return e(e.s=1556)}),_N_E=e.O()}]);
|
||||||
1
dist/_next/static/chunks/app/login/page-6be400e8521677b4.js
vendored
Normal file
1
dist/_next/static/chunks/app/login/page-6be400e8521677b4.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/app/page-c63080d1806e3966.js
vendored
Normal file
1
dist/_next/static/chunks/app/page-c63080d1806e3966.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/app/services/page-624950d2fabe2b7b.js
vendored
Normal file
1
dist/_next/static/chunks/app/services/page-624950d2fabe2b7b.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/app/settings/page-88d3fd0faab66996.js
vendored
Normal file
1
dist/_next/static/chunks/app/settings/page-88d3fd0faab66996.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/fd9d1056-307a36020502e7d7.js
vendored
Normal file
1
dist/_next/static/chunks/fd9d1056-307a36020502e7d7.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/framework-f66176bb897dc684.js
vendored
Normal file
1
dist/_next/static/chunks/framework-f66176bb897dc684.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/main-478a66ed427fba46.js
vendored
Normal file
1
dist/_next/static/chunks/main-478a66ed427fba46.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/_next/static/chunks/main-app-4119cbfe984dfca9.js
vendored
Normal file
1
dist/_next/static/chunks/main-app-4119cbfe984dfca9.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[744],{2300:function(e,n,t){Promise.resolve().then(t.t.bind(t,2846,23)),Promise.resolve().then(t.t.bind(t,9107,23)),Promise.resolve().then(t.t.bind(t,1060,23)),Promise.resolve().then(t.t.bind(t,4707,23)),Promise.resolve().then(t.t.bind(t,80,23)),Promise.resolve().then(t.t.bind(t,6423,23))}},function(e){var n=function(n){return e(e.s=n)};e.O(0,[971,117],function(){return n(4278),n(2300)}),_N_E=e.O()}]);
|
||||||
1
dist/_next/static/chunks/pages/_app-72b849fbd24ac258.js
vendored
Normal file
1
dist/_next/static/chunks/pages/_app-72b849fbd24ac258.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[888],{1597:function(n,_,u){(window.__NEXT_P=window.__NEXT_P||[]).push(["/_app",function(){return u(8141)}])}},function(n){var _=function(_){return n(n.s=_)};n.O(0,[774,179],function(){return _(1597),_(7253)}),_N_E=n.O()}]);
|
||||||
1
dist/_next/static/chunks/pages/_error-7ba65e1336b92748.js
vendored
Normal file
1
dist/_next/static/chunks/pages/_error-7ba65e1336b92748.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[820],{1981:function(n,_,u){(window.__NEXT_P=window.__NEXT_P||[]).push(["/_error",function(){return u(8529)}])}},function(n){n.O(0,[888,774,179],function(){return n(n.s=1981)}),_N_E=n.O()}]);
|
||||||
1
dist/_next/static/chunks/webpack-785ddfc5aaaa81eb.js
vendored
Normal file
1
dist/_next/static/chunks/webpack-785ddfc5aaaa81eb.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!function(){"use strict";var e,t,n,r,o,u,i,c,f,a={},l={};function s(e){var t=l[e];if(void 0!==t)return t.exports;var n=l[e]={exports:{}},r=!0;try{a[e].call(n.exports,n,n.exports,s),r=!1}finally{r&&delete l[e]}return n.exports}s.m=a,e=[],s.O=function(t,n,r,o){if(n){o=o||0;for(var u=e.length;u>0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[n,r,o];return}for(var i=1/0,u=0;u<e.length;u++){for(var n=e[u][0],r=e[u][1],o=e[u][2],c=!0,f=0;f<n.length;f++)i>=o&&Object.keys(s.O).every(function(e){return s.O[e](n[f])})?n.splice(f--,1):(c=!1,o<i&&(i=o));if(c){e.splice(u--,1);var a=r();void 0!==a&&(t=a)}}return t},s.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return s.d(t,{a:t}),t},n=Object.getPrototypeOf?function(e){return Object.getPrototypeOf(e)}:function(e){return e.__proto__},s.t=function(e,r){if(1&r&&(e=this(e)),8&r||"object"==typeof e&&e&&(4&r&&e.__esModule||16&r&&"function"==typeof e.then))return e;var o=Object.create(null);s.r(o);var u={};t=t||[null,n({}),n([]),n(n)];for(var i=2&r&&e;"object"==typeof i&&!~t.indexOf(i);i=n(i))Object.getOwnPropertyNames(i).forEach(function(t){u[t]=function(){return e[t]}});return u.default=function(){return e},s.d(o,u),o},s.d=function(e,t){for(var n in t)s.o(t,n)&&!s.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},s.f={},s.e=function(e){return Promise.all(Object.keys(s.f).reduce(function(t,n){return s.f[n](e,t),t},[]))},s.u=function(e){},s.miniCssF=function(e){},s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),s.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r={},o="_N_E:",s.l=function(e,t,n,u){if(r[e]){r[e].push(t);return}if(void 0!==n)for(var i,c,f=document.getElementsByTagName("script"),a=0;a<f.length;a++){var l=f[a];if(l.getAttribute("src")==e||l.getAttribute("data-webpack")==o+n){i=l;break}}i||(c=!0,(i=document.createElement("script")).charset="utf-8",i.timeout=120,s.nc&&i.setAttribute("nonce",s.nc),i.setAttribute("data-webpack",o+n),i.src=s.tu(e)),r[e]=[t];var d=function(t,n){i.onerror=i.onload=null,clearTimeout(p);var o=r[e];if(delete r[e],i.parentNode&&i.parentNode.removeChild(i),o&&o.forEach(function(e){return e(n)}),t)return t(n)},p=setTimeout(d.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=d.bind(null,i.onerror),i.onload=d.bind(null,i.onload),c&&document.head.appendChild(i)},s.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},s.tt=function(){return void 0===u&&(u={createScriptURL:function(e){return e}},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(u=trustedTypes.createPolicy("nextjs#bundler",u))),u},s.tu=function(e){return s.tt().createScriptURL(e)},s.p="/_next/",i={272:0,832:0},s.f.j=function(e,t){var n=s.o(i,e)?i[e]:void 0;if(0!==n){if(n)t.push(n[2]);else if(/^(27|83)2$/.test(e))i[e]=0;else{var r=new Promise(function(t,r){n=i[e]=[t,r]});t.push(n[2]=r);var o=s.p+s.u(e),u=Error();s.l(o,function(t){if(s.o(i,e)&&(0!==(n=i[e])&&(i[e]=void 0),n)){var r=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;u.message="Loading chunk "+e+" failed.\n("+r+": "+o+")",u.name="ChunkLoadError",u.type=r,u.request=o,n[1](u)}},"chunk-"+e,e)}}},s.O.j=function(e){return 0===i[e]},c=function(e,t){var n,r,o=t[0],u=t[1],c=t[2],f=0;if(o.some(function(e){return 0!==i[e]})){for(n in u)s.o(u,n)&&(s.m[n]=u[n]);if(c)var a=c(s)}for(e&&e(t);f<o.length;f++)r=o[f],s.o(i,r)&&i[r]&&i[r][0](),i[r]=0;return s.O(a)},(f=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(c.bind(null,0)),f.push=c.bind(null,f.push.bind(f))}();
|
||||||
3
dist/_next/static/css/9effa8aa186c096c.css
vendored
Normal file
3
dist/_next/static/css/9effa8aa186c096c.css
vendored
Normal file
File diff suppressed because one or more lines are too long
54
dist/alerts.html
vendored
Normal file
54
dist/alerts.html
vendored
Normal file
File diff suppressed because one or more lines are too long
8
dist/alerts.txt
vendored
Normal file
8
dist/alerts.txt
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
2:I[9107,[],"ClientPageRoot"]
|
||||||
|
3:I[5949,["697","static/chunks/697-93a9cd29100d0d50.js","71","static/chunks/71-fccb418814321416.js","796","static/chunks/796-9d56fd2c469c90a6.js","489","static/chunks/489-4b7fe4fae3b6ef80.js","78","static/chunks/app/alerts/page-6f170ee2c75a0961.js"],"default",1]
|
||||||
|
4:I[4707,[],""]
|
||||||
|
5:I[6423,[],""]
|
||||||
|
6:I[9294,["185","static/chunks/app/layout-639440f4d8b9b6b3.js"],"Providers"]
|
||||||
|
0:["4SrcMtBIfNF-pqHyUpitS",[[["",{"children":["alerts",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["alerts",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","alerts","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/9effa8aa186c096c.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"es","className":"__variable_f367f3","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__className_f367f3 antialiased min-h-screen bg-slate-950 text-slate-50","children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
|
||||||
|
7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Finanzas Personales"}],["$","meta","3",{"name":"description","content":"Gestiona tus finanzas personales de forma inteligente"}],["$","meta","4",{"name":"keywords","content":"finanzas,presupuesto,gastos,ingresos,ahorro"}],["$","meta","5",{"name":"next-size-adjust"}]]
|
||||||
|
1:null
|
||||||
25
dist/app-build-manifest.json
vendored
25
dist/app-build-manifest.json
vendored
@@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"pages": {
|
|
||||||
"/layout": [
|
|
||||||
"static/chunks/webpack.js",
|
|
||||||
"static/chunks/main-app.js",
|
|
||||||
"static/css/app/layout.css",
|
|
||||||
"static/chunks/app/layout.js"
|
|
||||||
],
|
|
||||||
"/page": [
|
|
||||||
"static/chunks/webpack.js",
|
|
||||||
"static/chunks/main-app.js",
|
|
||||||
"static/chunks/app/page.js"
|
|
||||||
],
|
|
||||||
"/settings/page": [
|
|
||||||
"static/chunks/webpack.js",
|
|
||||||
"static/chunks/main-app.js",
|
|
||||||
"static/chunks/app/settings/page.js"
|
|
||||||
],
|
|
||||||
"/_not-found/page": [
|
|
||||||
"static/chunks/webpack.js",
|
|
||||||
"static/chunks/main-app.js",
|
|
||||||
"static/chunks/app/_not-found/page.js"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
54
dist/budget.html
vendored
Normal file
54
dist/budget.html
vendored
Normal file
File diff suppressed because one or more lines are too long
8
dist/budget.txt
vendored
Normal file
8
dist/budget.txt
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
2:I[9107,[],"ClientPageRoot"]
|
||||||
|
3:I[7268,["697","static/chunks/697-93a9cd29100d0d50.js","71","static/chunks/71-fccb418814321416.js","796","static/chunks/796-9d56fd2c469c90a6.js","489","static/chunks/489-4b7fe4fae3b6ef80.js","379","static/chunks/app/budget/page-1c1157916eee3b45.js"],"default",1]
|
||||||
|
4:I[4707,[],""]
|
||||||
|
5:I[6423,[],""]
|
||||||
|
6:I[9294,["185","static/chunks/app/layout-639440f4d8b9b6b3.js"],"Providers"]
|
||||||
|
0:["4SrcMtBIfNF-pqHyUpitS",[[["",{"children":["budget",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["budget",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","budget","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/9effa8aa186c096c.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"es","className":"__variable_f367f3","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__className_f367f3 antialiased min-h-screen bg-slate-950 text-slate-50","children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
|
||||||
|
7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Finanzas Personales"}],["$","meta","3",{"name":"description","content":"Gestiona tus finanzas personales de forma inteligente"}],["$","meta","4",{"name":"keywords","content":"finanzas,presupuesto,gastos,ingresos,ahorro"}],["$","meta","5",{"name":"next-size-adjust"}]]
|
||||||
|
1:null
|
||||||
19
dist/build-manifest.json
vendored
19
dist/build-manifest.json
vendored
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"polyfillFiles": [
|
|
||||||
"static/chunks/polyfills.js"
|
|
||||||
],
|
|
||||||
"devFiles": [],
|
|
||||||
"ampDevFiles": [],
|
|
||||||
"lowPriorityFiles": [
|
|
||||||
"static/development/_buildManifest.js",
|
|
||||||
"static/development/_ssgManifest.js"
|
|
||||||
],
|
|
||||||
"rootMainFiles": [
|
|
||||||
"static/chunks/webpack.js",
|
|
||||||
"static/chunks/main-app.js"
|
|
||||||
],
|
|
||||||
"pages": {
|
|
||||||
"/_app": []
|
|
||||||
},
|
|
||||||
"ampFirstPages": []
|
|
||||||
}
|
|
||||||
BIN
dist/cache/webpack/client-development/0.pack.gz
vendored
BIN
dist/cache/webpack/client-development/0.pack.gz
vendored
Binary file not shown.
BIN
dist/cache/webpack/client-development/1.pack.gz
vendored
BIN
dist/cache/webpack/client-development/1.pack.gz
vendored
Binary file not shown.
BIN
dist/cache/webpack/client-development/2.pack.gz
vendored
BIN
dist/cache/webpack/client-development/2.pack.gz
vendored
Binary file not shown.
BIN
dist/cache/webpack/client-development/index.pack.gz
vendored
BIN
dist/cache/webpack/client-development/index.pack.gz
vendored
Binary file not shown.
Binary file not shown.
BIN
dist/cache/webpack/server-development/0.pack.gz
vendored
BIN
dist/cache/webpack/server-development/0.pack.gz
vendored
Binary file not shown.
BIN
dist/cache/webpack/server-development/1.pack.gz
vendored
BIN
dist/cache/webpack/server-development/1.pack.gz
vendored
Binary file not shown.
BIN
dist/cache/webpack/server-development/2.pack.gz
vendored
BIN
dist/cache/webpack/server-development/2.pack.gz
vendored
Binary file not shown.
BIN
dist/cache/webpack/server-development/3.pack.gz
vendored
BIN
dist/cache/webpack/server-development/3.pack.gz
vendored
Binary file not shown.
BIN
dist/cache/webpack/server-development/index.pack.gz
vendored
BIN
dist/cache/webpack/server-development/index.pack.gz
vendored
Binary file not shown.
Binary file not shown.
54
dist/cards.html
vendored
Normal file
54
dist/cards.html
vendored
Normal file
File diff suppressed because one or more lines are too long
8
dist/cards.txt
vendored
Normal file
8
dist/cards.txt
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
2:I[9107,[],"ClientPageRoot"]
|
||||||
|
3:I[3234,["697","static/chunks/697-93a9cd29100d0d50.js","71","static/chunks/71-fccb418814321416.js","796","static/chunks/796-9d56fd2c469c90a6.js","489","static/chunks/489-4b7fe4fae3b6ef80.js","137","static/chunks/app/cards/page-a9843d3be56b680d.js"],"default",1]
|
||||||
|
4:I[4707,[],""]
|
||||||
|
5:I[6423,[],""]
|
||||||
|
6:I[9294,["185","static/chunks/app/layout-639440f4d8b9b6b3.js"],"Providers"]
|
||||||
|
0:["4SrcMtBIfNF-pqHyUpitS",[[["",{"children":["cards",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["cards",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","cards","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/9effa8aa186c096c.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"es","className":"__variable_f367f3","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__className_f367f3 antialiased min-h-screen bg-slate-950 text-slate-50","children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
|
||||||
|
7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Finanzas Personales"}],["$","meta","3",{"name":"description","content":"Gestiona tus finanzas personales de forma inteligente"}],["$","meta","4",{"name":"keywords","content":"finanzas,presupuesto,gastos,ingresos,ahorro"}],["$","meta","5",{"name":"next-size-adjust"}]]
|
||||||
|
1:null
|
||||||
54
dist/debts.html
vendored
Normal file
54
dist/debts.html
vendored
Normal file
File diff suppressed because one or more lines are too long
8
dist/debts.txt
vendored
Normal file
8
dist/debts.txt
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
2:I[9107,[],"ClientPageRoot"]
|
||||||
|
3:I[9220,["697","static/chunks/697-93a9cd29100d0d50.js","71","static/chunks/71-fccb418814321416.js","796","static/chunks/796-9d56fd2c469c90a6.js","489","static/chunks/489-4b7fe4fae3b6ef80.js","273","static/chunks/app/debts/page-28aedff94a342b70.js"],"default",1]
|
||||||
|
4:I[4707,[],""]
|
||||||
|
5:I[6423,[],""]
|
||||||
|
6:I[9294,["185","static/chunks/app/layout-639440f4d8b9b6b3.js"],"Providers"]
|
||||||
|
0:["4SrcMtBIfNF-pqHyUpitS",[[["",{"children":["debts",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["debts",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","debts","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/9effa8aa186c096c.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"es","className":"__variable_f367f3","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__className_f367f3 antialiased min-h-screen bg-slate-950 text-slate-50","children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
|
||||||
|
7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Finanzas Personales"}],["$","meta","3",{"name":"description","content":"Gestiona tus finanzas personales de forma inteligente"}],["$","meta","4",{"name":"keywords","content":"finanzas,presupuesto,gastos,ingresos,ahorro"}],["$","meta","5",{"name":"next-size-adjust"}]]
|
||||||
|
1:null
|
||||||
69
dist/index.html
vendored
Normal file
69
dist/index.html
vendored
Normal file
File diff suppressed because one or more lines are too long
8
dist/index.txt
vendored
Normal file
8
dist/index.txt
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
2:I[9107,[],"ClientPageRoot"]
|
||||||
|
3:I[291,["697","static/chunks/697-93a9cd29100d0d50.js","71","static/chunks/71-fccb418814321416.js","796","static/chunks/796-9d56fd2c469c90a6.js","838","static/chunks/838-3b22f3c21887b523.js","489","static/chunks/489-4b7fe4fae3b6ef80.js","931","static/chunks/app/page-c63080d1806e3966.js"],"default",1]
|
||||||
|
4:I[9294,["185","static/chunks/app/layout-639440f4d8b9b6b3.js"],"Providers"]
|
||||||
|
5:I[4707,[],""]
|
||||||
|
6:I[6423,[],""]
|
||||||
|
0:["4SrcMtBIfNF-pqHyUpitS",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/9effa8aa186c096c.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"es","className":"__variable_f367f3","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__className_f367f3 antialiased min-h-screen bg-slate-950 text-slate-50","children":["$","$L4",null,{"children":["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L6",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
|
||||||
|
7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Finanzas Personales"}],["$","meta","3",{"name":"description","content":"Gestiona tus finanzas personales de forma inteligente"}],["$","meta","4",{"name":"keywords","content":"finanzas,presupuesto,gastos,ingresos,ahorro"}],["$","meta","5",{"name":"next-size-adjust"}]]
|
||||||
|
1:null
|
||||||
1
dist/login.html
vendored
Normal file
1
dist/login.html
vendored
Normal file
File diff suppressed because one or more lines are too long
8
dist/login.txt
vendored
Normal file
8
dist/login.txt
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
2:I[9107,[],"ClientPageRoot"]
|
||||||
|
3:I[6374,["626","static/chunks/app/login/page-6be400e8521677b4.js"],"default",1]
|
||||||
|
4:I[4707,[],""]
|
||||||
|
5:I[6423,[],""]
|
||||||
|
6:I[9294,["185","static/chunks/app/layout-639440f4d8b9b6b3.js"],"Providers"]
|
||||||
|
0:["4SrcMtBIfNF-pqHyUpitS",[[["",{"children":["login",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["login",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","login","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/9effa8aa186c096c.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"es","className":"__variable_f367f3","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__className_f367f3 antialiased min-h-screen bg-slate-950 text-slate-50","children":["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]}]],null],null],["$L7",null]]]]
|
||||||
|
7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Finanzas Personales"}],["$","meta","3",{"name":"description","content":"Gestiona tus finanzas personales de forma inteligente"}],["$","meta","4",{"name":"keywords","content":"finanzas,presupuesto,gastos,ingresos,ahorro"}],["$","meta","5",{"name":"next-size-adjust"}]]
|
||||||
|
1:null
|
||||||
1
dist/package.json
vendored
1
dist/package.json
vendored
@@ -1 +0,0 @@
|
|||||||
{"type": "commonjs"}
|
|
||||||
1
dist/react-loadable-manifest.json
vendored
1
dist/react-loadable-manifest.json
vendored
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
7
dist/server/app-paths-manifest.json
vendored
7
dist/server/app-paths-manifest.json
vendored
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"/page": "app/page.js",
|
|
||||||
"/api/settings/route": "app/api/settings/route.js",
|
|
||||||
"/settings/page": "app/settings/page.js",
|
|
||||||
"/api/test/ai/route": "app/api/test/ai/route.js",
|
|
||||||
"/api/proxy/models/route": "app/api/proxy/models/route.js"
|
|
||||||
}
|
|
||||||
155
dist/server/app/_not-found/page.js
vendored
155
dist/server/app/_not-found/page.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
66
dist/server/app/api/proxy/models/route.js
vendored
66
dist/server/app/api/proxy/models/route.js
vendored
File diff suppressed because one or more lines are too long
86
dist/server/app/api/settings/route.js
vendored
86
dist/server/app/api/settings/route.js
vendored
File diff suppressed because one or more lines are too long
66
dist/server/app/api/test/ai/route.js
vendored
66
dist/server/app/api/test/ai/route.js
vendored
File diff suppressed because one or more lines are too long
557
dist/server/app/page.js
vendored
557
dist/server/app/page.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
205
dist/server/app/settings/page.js
vendored
205
dist/server/app/settings/page.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
|||||||
self.__INTERCEPTION_ROUTE_REWRITE_MANIFEST="[]"
|
|
||||||
21
dist/server/middleware-build-manifest.js
vendored
21
dist/server/middleware-build-manifest.js
vendored
@@ -1,21 +0,0 @@
|
|||||||
self.__BUILD_MANIFEST = {
|
|
||||||
"polyfillFiles": [
|
|
||||||
"static/chunks/polyfills.js"
|
|
||||||
],
|
|
||||||
"devFiles": [],
|
|
||||||
"ampDevFiles": [],
|
|
||||||
"lowPriorityFiles": [],
|
|
||||||
"rootMainFiles": [
|
|
||||||
"static/chunks/webpack.js",
|
|
||||||
"static/chunks/main-app.js"
|
|
||||||
],
|
|
||||||
"pages": {
|
|
||||||
"/_app": []
|
|
||||||
},
|
|
||||||
"ampFirstPages": []
|
|
||||||
};
|
|
||||||
self.__BUILD_MANIFEST.lowPriorityFiles = [
|
|
||||||
"/static/" + process.env.__NEXT_BUILD_ID + "/_buildManifest.js",
|
|
||||||
,"/static/" + process.env.__NEXT_BUILD_ID + "/_ssgManifest.js",
|
|
||||||
|
|
||||||
];
|
|
||||||
6
dist/server/middleware-manifest.json
vendored
6
dist/server/middleware-manifest.json
vendored
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"version": 3,
|
|
||||||
"middleware": {},
|
|
||||||
"functions": {},
|
|
||||||
"sortedMiddleware": []
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
self.__REACT_LOADABLE_MANIFEST="{}"
|
|
||||||
1
dist/server/next-font-manifest.js
vendored
1
dist/server/next-font-manifest.js
vendored
@@ -1 +0,0 @@
|
|||||||
self.__NEXT_FONT_MANIFEST="{\"pages\":{},\"app\":{},\"appUsingSizeAdjust\":false,\"pagesUsingSizeAdjust\":false}"
|
|
||||||
1
dist/server/next-font-manifest.json
vendored
1
dist/server/next-font-manifest.json
vendored
@@ -1 +0,0 @@
|
|||||||
{"pages":{},"app":{},"appUsingSizeAdjust":false,"pagesUsingSizeAdjust":false}
|
|
||||||
1
dist/server/pages-manifest.json
vendored
1
dist/server/pages-manifest.json
vendored
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
1
dist/server/server-reference-manifest.js
vendored
1
dist/server/server-reference-manifest.js
vendored
@@ -1 +0,0 @@
|
|||||||
self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"process.env.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY\"\n}"
|
|
||||||
5
dist/server/server-reference-manifest.json
vendored
5
dist/server/server-reference-manifest.json
vendored
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"node": {},
|
|
||||||
"edge": {},
|
|
||||||
"encryptionKey": "bNoGWlCooOUGQMrF3XDKlehaXh5PleSvIPcww3mfySw="
|
|
||||||
}
|
|
||||||
35
dist/server/vendor-chunks/@reduxjs.js
vendored
35
dist/server/vendor-chunks/@reduxjs.js
vendored
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user