feat: initial smart home dashboard
All checks were successful
Deploy to Coolify / deploy (push) Successful in 44s
All checks were successful
Deploy to Coolify / deploy (push) Successful in 44s
- Next.js 14 + TypeScript + Tailwind CSS - Glassmorphism design with ambient orbs - Cards: Light x2, Temperature, AirPurifier, Tasks, Weather, Savings - Home Assistant integration (demo mode if no token) - Vikunja tasks API - Pulse savings API - wttr.in weather - Framer Motion animations - Dark/light theme toggle - Bottom navigation - Dockerfile for deployment
This commit is contained in:
82
app/api/tasks/route.ts
Normal file
82
app/api/tasks/route.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
const VIKUNJA_URL = process.env.VIKUNJA_URL || "https://tasks.digital-home.site";
|
||||
const VIKUNJA_TOKEN = process.env.VIKUNJA_TOKEN || "tk_03787e3778789fd5bfaff0542a8dd9390aae0f82";
|
||||
|
||||
const MOCK_TASKS = [
|
||||
{ id: 1, title: "Записаться на ТО", done: false, priority: 2 },
|
||||
{ id: 2, title: "Оплатить аренду", done: true, priority: 3 },
|
||||
{ id: 3, title: "Купить продукты", done: false, priority: 1 },
|
||||
];
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const today = new Date().toISOString().split("T")[0];
|
||||
const res = await fetch(
|
||||
`${VIKUNJA_URL}/api/v1/tasks/all?filter_by=due_date&filter_value=${today}&filter_comparator=equals&per_page=20`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${VIKUNJA_TOKEN}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
next: { revalidate: 0 },
|
||||
}
|
||||
);
|
||||
|
||||
if (!res.ok) throw new Error(`Vikunja responded ${res.status}`);
|
||||
const data = await res.json();
|
||||
return NextResponse.json({ tasks: Array.isArray(data) ? data : [] });
|
||||
} catch (e) {
|
||||
return NextResponse.json({ tasks: MOCK_TASKS, demo: true });
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
const { title } = await req.json();
|
||||
if (!title) return NextResponse.json({ error: "Title required" }, { status: 400 });
|
||||
|
||||
const today = new Date();
|
||||
today.setHours(23, 59, 59, 0);
|
||||
|
||||
try {
|
||||
const res = await fetch(`${VIKUNJA_URL}/api/v1/projects/3/tasks`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
Authorization: `Bearer ${VIKUNJA_TOKEN}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
title,
|
||||
due_date: today.toISOString(),
|
||||
}),
|
||||
});
|
||||
|
||||
if (!res.ok) throw new Error(`Vikunja responded ${res.status}`);
|
||||
const task = await res.json();
|
||||
return NextResponse.json({ task });
|
||||
} catch (e) {
|
||||
return NextResponse.json(
|
||||
{ task: { id: Date.now(), title, done: false }, demo: true }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function PATCH(req: NextRequest) {
|
||||
const { id, done } = await req.json();
|
||||
|
||||
try {
|
||||
const res = await fetch(`${VIKUNJA_URL}/api/v1/tasks/${id}`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${VIKUNJA_TOKEN}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ done }),
|
||||
});
|
||||
|
||||
if (!res.ok) throw new Error(`Vikunja responded ${res.status}`);
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (e) {
|
||||
return NextResponse.json({ success: true, demo: true });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user