From cebcb4c8cdec39a043a07b7cce03152d164ecaa8 Mon Sep 17 00:00:00 2001 From: Shivam Patel Date: Mon, 9 Feb 2026 17:56:49 -0500 Subject: [PATCH] Revert "Fix RSS time filters and add draggable grid layout" This reverts commit 4ee365cfc06ed3201b55fe3d2ce30ebbb5337490. --- app/api/rss/feeds/route.ts | 9 +- app/api/rss/route.ts | 2 +- app/globals.css | 26 ----- app/page.tsx | 13 ++- components/dashboard/GridShell.tsx | 173 +++-------------------------- components/widgets/GlobeCard.tsx | 4 +- components/widgets/NewsFeed.tsx | 8 +- components/widgets/UptimeCard.tsx | 15 +-- components/widgets/WeatherCard.tsx | 8 +- lib/db.ts | 18 --- monitor.js | 9 +- package-lock.json | 84 +------------- package.json | 2 - 13 files changed, 47 insertions(+), 324 deletions(-) diff --git a/app/api/rss/feeds/route.ts b/app/api/rss/feeds/route.ts index c9a9528..05893f9 100644 --- a/app/api/rss/feeds/route.ts +++ b/app/api/rss/feeds/route.ts @@ -4,13 +4,6 @@ import Parser from 'rss-parser'; export const dynamic = 'force-dynamic'; -function normalizeDate(item: { isoDate?: string; pubDate?: string }): string | null { - const raw = item.isoDate || item.pubDate; - if (!raw) return null; - const d = new Date(raw); - return isNaN(d.getTime()) ? null : d.toISOString(); -} - export async function GET() { const db = await getDb(); const feeds = await db.all(` @@ -63,7 +56,7 @@ export async function POST(req: NextRequest) { feedId, item.title, item.link, - normalizeDate(item), + item.pubDate || item.isoDate || null, item.creator || item.author || null, (item.contentSnippet || item.content || '').substring(0, 500) || null ); diff --git a/app/api/rss/route.ts b/app/api/rss/route.ts index 017da9e..dc2051c 100644 --- a/app/api/rss/route.ts +++ b/app/api/rss/route.ts @@ -30,7 +30,7 @@ export async function GET(req: NextRequest) { } if (since) { const sinceMap: Record = { - '12h': '-12 hours', + '1h': '-1 hours', '24h': '-24 hours', '7d': '-7 days', '30d': '-30 days', diff --git a/app/globals.css b/app/globals.css index dc6c8b6..5413518 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,5 +1,3 @@ -@import "react-grid-layout/css/styles.css"; -@import "react-resizable/css/styles.css"; @import "tailwindcss"; :root { @@ -45,27 +43,3 @@ body { .scrollbar-thin::-webkit-scrollbar-thumb:hover { background: #525252; } - -/* react-grid-layout dark theme overrides */ -.react-grid-item > .react-resizable-handle::after { - border-right-color: #525252; - border-bottom-color: #525252; -} -.react-grid-item > .react-resizable-handle:hover::after { - border-right-color: #a1a1aa; - border-bottom-color: #a1a1aa; -} -.react-grid-item.react-grid-placeholder { - background: rgba(245, 158, 11, 0.15); - border: 1px dashed rgba(245, 158, 11, 0.4); - border-radius: 0.75rem; -} -.react-grid-item { - transition: all 200ms ease; -} -.widget-drag-handle { - cursor: grab; -} -.widget-drag-handle:active { - cursor: grabbing; -} diff --git a/app/page.tsx b/app/page.tsx index 567abe3..1112dba 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -7,10 +7,15 @@ import { NewsFeed } from "@/components/widgets/NewsFeed"; export default function Home() { return ( -
-
-
-
+ {/* Row 1 */} + + + + {/* Row 1 & 2 (Globe spans 2 rows) */} + + + {/* Row 2-4: NewsFeed spans 4 cols, 3 rows */} +
); } diff --git a/components/dashboard/GridShell.tsx b/components/dashboard/GridShell.tsx index 79ffb78..72301c6 100644 --- a/components/dashboard/GridShell.tsx +++ b/components/dashboard/GridShell.tsx @@ -1,168 +1,29 @@ -'use client'; - -import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; -import { ResponsiveGridLayout, useContainerWidth, verticalCompactor, type ResponsiveLayouts, type Layout } from 'react-grid-layout'; -import { RotateCcw } from 'lucide-react'; - -const STORAGE_KEY = 'dashboard-layouts'; - -const BREAKPOINTS = { lg: 1024, md: 768, sm: 0 }; -const COLS = { lg: 6, md: 4, sm: 1 }; -const ROW_HEIGHT = 200; -const MARGIN: [number, number] = [16, 16]; - -const DEFAULT_LAYOUTS: ResponsiveLayouts = { - lg: [ - { i: 'uptime', x: 0, y: 0, w: 2, h: 1, minW: 2, minH: 1 }, - { i: 'weather', x: 2, y: 0, w: 2, h: 1, minW: 2, minH: 1 }, - { i: 'globe', x: 4, y: 0, w: 2, h: 2, minW: 2, minH: 2 }, - { i: 'newsfeed', x: 0, y: 1, w: 4, h: 3, minW: 2, minH: 2 }, - ], - md: [ - { i: 'uptime', x: 0, y: 0, w: 2, h: 1, minW: 2, minH: 1 }, - { i: 'weather', x: 2, y: 0, w: 2, h: 1, minW: 2, minH: 1 }, - { i: 'globe', x: 0, y: 1, w: 2, h: 2, minW: 2, minH: 2 }, - { i: 'newsfeed', x: 2, y: 1, w: 2, h: 3, minW: 2, minH: 2 }, - ], - sm: [ - { i: 'uptime', x: 0, y: 0, w: 1, h: 1, minW: 1, minH: 1 }, - { i: 'weather', x: 0, y: 1, w: 1, h: 1, minW: 1, minH: 1 }, - { i: 'globe', x: 0, y: 2, w: 1, h: 2, minW: 1, minH: 2 }, - { i: 'newsfeed', x: 0, y: 4, w: 1, h: 3, minW: 1, minH: 2 }, - ], -}; - -const DRAG_CONFIG = { handle: '.widget-drag-handle' }; - -// --- Layout Context --- - -interface LayoutContextValue { - updateWidgetSize: (key: string, w: number, h: number) => void; -} - -const LayoutContext = createContext({ - updateWidgetSize: () => {}, -}); - -export function useLayoutContext() { - return useContext(LayoutContext); -} - -// --- GridShell --- +import React from 'react'; interface GridShellProps { children: React.ReactNode; } -function loadSavedLayouts(): ResponsiveLayouts | null { - if (typeof window === 'undefined') return null; - try { - const raw = localStorage.getItem(STORAGE_KEY); - if (raw) return JSON.parse(raw); - } catch {} - return null; -} - -function persistLayouts(layouts: ResponsiveLayouts) { - try { - localStorage.setItem(STORAGE_KEY, JSON.stringify(layouts)); - } catch {} -} - export function GridShell({ children }: GridShellProps) { - const [layouts, setLayouts] = useState(DEFAULT_LAYOUTS); - const [ready, setReady] = useState(false); - const { width, containerRef, mounted } = useContainerWidth({ initialWidth: 1280 }); - - useEffect(() => { - const saved = loadSavedLayouts(); - if (saved) setLayouts(saved); - setReady(true); - }, []); - - const handleLayoutChange = useCallback((_layout: Layout, allLayouts: ResponsiveLayouts) => { - setLayouts(allLayouts); - persistLayouts(allLayouts); - }, []); - - const handleReset = useCallback(() => { - setLayouts(DEFAULT_LAYOUTS); - persistLayouts(DEFAULT_LAYOUTS); - }, []); - - const updateWidgetSize = useCallback((key: string, w: number, h: number) => { - setLayouts((prev) => { - const next: ResponsiveLayouts = {}; - for (const bp of Object.keys(prev)) { - const bpLayout = prev[bp]; - if (!bpLayout) continue; - next[bp] = bpLayout.map((item) => - item.i === key ? { ...item, w, h } : item - ); - } - persistLayouts(next); - return next; - }); - }, []); - - const contextValue = useMemo( - () => ({ updateWidgetSize }), - [updateWidgetSize] - ); - - const childArray = React.Children.toArray(children); - return ( - -
-
-
-
-

Mission Control

-
-
- -
-
- SYSTEM ONLINE -
-
-
+
+
+
+
+

Mission Control

-
}> - {mounted && ready && ( - - {childArray.map((child) => { - if (!React.isValidElement(child)) return null; - const key = child.key as string; - return ( -
- {child} -
- ); - })} -
- )}
-
+
+ {/* Future header controls */} +
+ SYSTEM ONLINE +
+
+ +
+ {children} +
- +
); } diff --git a/components/widgets/GlobeCard.tsx b/components/widgets/GlobeCard.tsx index 4767359..3eefcb4 100644 --- a/components/widgets/GlobeCard.tsx +++ b/components/widgets/GlobeCard.tsx @@ -155,8 +155,8 @@ export function GlobeCard() { }, []); return ( -
-
+
+
Visitor Map diff --git a/components/widgets/NewsFeed.tsx b/components/widgets/NewsFeed.tsx index a0dc6cf..d243a53 100644 --- a/components/widgets/NewsFeed.tsx +++ b/components/widgets/NewsFeed.tsx @@ -150,10 +150,10 @@ function FeedFilterPills({ ); } -type TimeFilter = '12h' | '24h' | '7d' | '30d'; +type TimeFilter = '1h' | '24h' | '7d' | '30d'; const TIME_FILTER_OPTIONS: { value: TimeFilter; label: string }[] = [ - { value: '12h', label: '12h' }, + { value: '1h', label: '1h' }, { value: '24h', label: '24h' }, { value: '7d', label: '7d' }, { value: '30d', label: '30d' }, @@ -479,9 +479,9 @@ export function NewsFeed() { const hasFeeds = feeds.length > 0; return ( -
+
{/* Header */} -
+
Feed diff --git a/components/widgets/UptimeCard.tsx b/components/widgets/UptimeCard.tsx index bd69f45..f52d2d4 100644 --- a/components/widgets/UptimeCard.tsx +++ b/components/widgets/UptimeCard.tsx @@ -3,7 +3,6 @@ import { Activity, RefreshCcw, AlertCircle, X, Plus, Trash2, ExternalLink, ChevronDown, ChevronUp, Pencil, Check } from 'lucide-react'; import { useState, useEffect, useCallback, useRef } from 'react'; import { format, subHours, subDays, subMonths } from 'date-fns'; -import { useLayoutContext } from '@/components/dashboard/GridShell'; // --- Types --- @@ -593,20 +592,14 @@ export function UptimeCard() { } }; - const { updateWidgetSize } = useLayoutContext(); + const rowSpan = expanded ? 'row-span-2' : 'row-span-1'; const [leftLabel, rightLabel] = rangeEdgeLabels(timeRange); - const handleToggleExpand = useCallback(() => { - const next = !expanded; - setExpanded(next); - updateWidgetSize('uptime', 2, next ? 2 : 1); - }, [expanded, updateWidgetSize]); - return ( <> -
+
{/* Header */} -
+
Uptime Monitor @@ -615,7 +608,7 @@ export function UptimeCard() {