Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
6eeae28
Integrate billing popup, usage sidebar, and credit preview toggle
CJWTRUST Jan 20, 2026
160e082
Recover lost commit 488b47c and restore branch head
google-labs-jules[bot] Jan 28, 2026
ae085cf
Merge pull request #456 from QueueLab/jules-16847885310673003402-db9c…
ngoiyaeric Jan 28, 2026
73c385c
Restore branch history to 488b47c and integrate latest fixes
google-labs-jules[bot] Jan 28, 2026
1508c04
Restore branch history to 488b47c and resolve build errors
google-labs-jules[bot] Jan 28, 2026
c8c028b
Restore branch history, fix build errors, and re-enable pricing popup
google-labs-jules[bot] Jan 28, 2026
e2c0615
Finalize recovery with performance optimizations and UI fixes
google-labs-jules[bot] Jan 28, 2026
43179e7
Synchronize with main, restore history, and optimize performance
google-labs-jules[bot] Jan 29, 2026
7d45e02
Finalize recovery with prioritized main branch code and usage UI
google-labs-jules[bot] Jan 29, 2026
5623831
Refine usage UI and Lottie animation visibility
google-labs-jules[bot] Jan 29, 2026
44e86b6
Complete recovery, synchronization with main, and usage UI integration
google-labs-jules[bot] Jan 29, 2026
0a48018
feat: recover branch state, optimize resolution search, and fix UI st…
google-labs-jules[bot] Jan 29, 2026
6acfbe5
fix: resolve build error and ESLint warnings
google-labs-jules[bot] Jan 29, 2026
8ae549a
Update LICENSE
ngoiyaeric Feb 1, 2026
3495da1
Update LICENSE
ngoiyaeric Feb 1, 2026
ba36e58
Merge pull request #469 from QueueLab/ngoiyaeric-patch-4
ngoiyaeric Feb 1, 2026
6431b41
fix: reduce padding in mobile chat input area
google-labs-jules[bot] Feb 1, 2026
8a04d49
Merge pull request #470 from QueueLab/fix/mobile-chat-input-padding-1…
ngoiyaeric Feb 1, 2026
10ab3fe
feat: update Stripe checkout links to new URL
google-labs-jules[bot] Feb 1, 2026
250283e
Merge pull request #471 from QueueLab/update-stripe-links-17354207767…
ngoiyaeric Feb 1, 2026
1b56819
feat: implement GeoJSON upload and tool ingestion pipeline
google-labs-jules[bot] Feb 1, 2026
9f79929
feat: implement GeoJSON upload and tool ingestion pipeline
google-labs-jules[bot] Feb 1, 2026
6554775
fix: ensure long sentences wrap to the next line across UI components
google-labs-jules[bot] Feb 1, 2026
bfe62f9
feat: support pasted GeoJSON and fix refresh loop
google-labs-jules[bot] Feb 1, 2026
9450b15
feat: enable GeoJSON uploads, paste support, and fix refresh loop
google-labs-jules[bot] Feb 1, 2026
e95a25b
Merge pull request #473 from QueueLab/fix/text-overflow-wrapping-4739…
ngoiyaeric Feb 1, 2026
f80c87f
Resolve merge conflicts and synchronize with main
CJWTRUST Feb 2, 2026
c4278e9
feat: final stability and performance improvements
google-labs-jules[bot] Feb 2, 2026
813d264
Resolve merge conflicts and synchronize with main, preserving branch …
google-labs-jules[bot] Feb 2, 2026
c868dcd
Merge branch 'feature/billing-integration-recovery-648258468266820429…
ngoiyaeric Feb 2, 2026
3b5ed27
Resolve merge conflicts: synchronization with main while preserving b…
google-labs-jules[bot] Feb 2, 2026
3984b9b
Restore missing features from commit c4278e9: tenttree usage UI, popu…
CJWTRUST Feb 2, 2026
f45f687
Merge branch 'main' into jules-8488824498232079115-26d4e4cd
ngoiyaeric Feb 2, 2026
67c26d5
Merge pull request #476 from QueueLab/jules-8488824498232079115-26d4e4cd
ngoiyaeric Feb 2, 2026
a842df1
chore: update stripe payment links
google-labs-jules[bot] Feb 2, 2026
184f678
Merge pull request #477 from QueueLab/update-stripe-links-20260202-15…
ngoiyaeric Feb 2, 2026
895bf37
Update UsageView to yearly refresh model
google-labs-jules[bot] Feb 2, 2026
dc345b9
Update usage-view.tsx
ngoiyaeric Feb 2, 2026
86013ed
Update usage-view.tsx
ngoiyaeric Feb 2, 2026
2ba1f9e
Merge pull request #479 from QueueLab/update-usage-view-to-yearly-ref…
ngoiyaeric Feb 2, 2026
dda7a32
fix: standardize header icon spacing and remove unused portals
google-labs-jules[bot] Feb 2, 2026
23a1d3f
Merge pull request #480 from QueueLab/fix-header-icon-spacing-1628392…
ngoiyaeric Feb 2, 2026
885dbbe
feat: make zoom controls conditional on drawing mode
google-labs-jules[bot] Feb 2, 2026
dd812c1
Merge pull request #482 from QueueLab/conditional-zoom-controls-22256…
ngoiyaeric Feb 2, 2026
00c2e1a
Update usage-view.tsx
ngoiyaeric Feb 2, 2026
54d9d6e
Update usage-view.tsx
ngoiyaeric Feb 2, 2026
c9bd9b2
Merge pull request #484 from QueueLab/ngoiyaeric-patch-5
ngoiyaeric Feb 2, 2026
85a85c5
Merge branch 'main' into feature/geojson-upload-pipeline-111249932693…
ngoiyaeric Feb 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Recover lost commit 488b47c and restore branch head
Restored the branch to the expected head at commit 488b47c.
This recovers several missing features and architectural improvements:
- Integrated HistoryToggleProvider and HistorySidebar.
- Integrated UsageToggleProvider and the new UsageView component.
- Removed legacy usage-sidebar.tsx.
- Restored pricing and feature updates in PurchaseCreditsPopup.
- Fixed layout structure in app/layout.tsx to support these new global state providers.

Resolved previous merge conflicts and incorrect force-push state.

Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
  • Loading branch information
google-labs-jules[bot] and ngoiyaeric committed Jan 28, 2026
commit 160e08243d1e0859c269c699623ff9e2bde720ab
52 changes: 30 additions & 22 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import { SpeedInsights } from "@vercel/speed-insights/next"
import { Toaster } from '@/components/ui/sonner'
import { MapToggleProvider } from '@/components/map-toggle-context'
import { ProfileToggleProvider } from '@/components/profile-toggle-context'
import { UsageToggleProvider } from '@/components/usage-toggle-context'
import { CalendarToggleProvider } from '@/components/calendar-toggle-context'
import { HistoryToggleProvider } from '@/components/history-toggle-context'
import { HistorySidebar } from '@/components/history-sidebar'
import { MapLoadingProvider } from '@/components/map-loading-context';
import ConditionalLottie from '@/components/conditional-lottie';
import { MapProvider as MapContextProvider } from '@/components/map/map-context'
Expand Down Expand Up @@ -70,28 +73,33 @@ export default function RootLayout({
)}
>
<CalendarToggleProvider>
<MapToggleProvider>
<ProfileToggleProvider>
<ThemeProvider
attribute="class"
defaultTheme="earth"
enableSystem
disableTransitionOnChange
themes={['light', 'dark', 'earth']}
>
<MapContextProvider>
<MapLoadingProvider>
<Header />
<ConditionalLottie />
{children}
<Sidebar />
<Footer />
<Toaster />
</MapLoadingProvider>
</MapContextProvider>
</ThemeProvider>
</ProfileToggleProvider>
</MapToggleProvider>
<HistoryToggleProvider>
<MapToggleProvider>
<ProfileToggleProvider>
<UsageToggleProvider>
<ThemeProvider
attribute="class"
defaultTheme="earth"
enableSystem
disableTransitionOnChange
themes={['light', 'dark', 'earth']}
>
<MapContextProvider>
<MapLoadingProvider>
<Header />
<ConditionalLottie />
{children}
<Sidebar />
<HistorySidebar />
<Footer />
<Toaster />
</MapLoadingProvider>
</MapContextProvider>
</ThemeProvider>
</UsageToggleProvider>
</ProfileToggleProvider>
</MapToggleProvider>
</HistoryToggleProvider>
</CalendarToggleProvider>
<Analytics />
<SpeedInsights />
Expand Down
7 changes: 5 additions & 2 deletions components/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import { MapProvider } from './map/map-provider'
import { useUIState, useAIState } from 'ai/rsc'
import MobileIconsBar from './mobile-icons-bar'
import { useProfileToggle, ProfileToggleEnum } from "@/components/profile-toggle-context";
import { useUsageToggle } from "@/components/usage-toggle-context";
import SettingsView from "@/components/settings/settings-view";
import { UsageView } from "@/components/usage-view";
import { MapDataProvider, useMapData } from './map/map-data-context'; // Add this and useMapData
import { updateDrawingContext } from '@/lib/actions/chat'; // Import the server action
import dynamic from 'next/dynamic'
Expand All @@ -31,6 +33,7 @@ export function Chat({ id }: ChatProps) {
const [aiState] = useAIState()
const [isMobile, setIsMobile] = useState(false)
const { activeView } = useProfileToggle();
const { isUsageOpen } = useUsageToggle();
const { isCalendarOpen } = useCalendarToggle()
const [input, setInput] = useState('')
const [showEmptyScreen, setShowEmptyScreen] = useState(false)
Expand Down Expand Up @@ -107,7 +110,7 @@ export function Chat({ id }: ChatProps) {
<HeaderSearchButton />
<div className="mobile-layout-container">
<div className="mobile-map-section">
{activeView ? <SettingsView /> : <MapProvider />}
{isUsageOpen ? <UsageView /> : activeView ? <SettingsView /> : <MapProvider />}
</div>
<div className="mobile-icons-bar">
<MobileIconsBar onAttachmentClick={handleAttachment} onSubmitClick={handleMobileSubmit} />
Expand Down Expand Up @@ -218,7 +221,7 @@ export function Chat({ id }: ChatProps) {
className="w-1/2 p-4 fixed h-[calc(100vh-0.5in)] top-0 right-0 mt-[0.5in]"
style={{ zIndex: 10 }} // Added z-index
>
{activeView ? <SettingsView /> : <MapProvider />}
{isUsageOpen ? <UsageView /> : activeView ? <SettingsView /> : <MapProvider />}
</div>
</div>
</MapDataProvider>
Expand Down
6 changes: 4 additions & 2 deletions components/conditional-lottie.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import LottiePlayer from '@/components/ui/lottie-player';
import { useMapLoading } from '@/components/map-loading-context';
import { useProfileToggle } from '@/components/profile-toggle-context'; // Added import
import { useUsageToggle } from '@/components/usage-toggle-context';

const ConditionalLottie = () => {
const { isMapLoaded } = useMapLoading();
const { activeView } = useProfileToggle(); // Added this line
const { isUsageOpen } = useUsageToggle();

// Updated isVisible logic
return <LottiePlayer isVisible={!isMapLoaded && activeView === null} />;
// Updated isVisible logic to hide lottie when settings or usage is open
return <LottiePlayer isVisible={!isMapLoaded && activeView === null && !isUsageOpen} />;
};

export default ConditionalLottie;
27 changes: 19 additions & 8 deletions components/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,25 @@ import {
import { MapToggle } from './map-toggle'
import { ProfileToggle } from './profile-toggle'
import { PurchaseCreditsPopup } from './purchase-credits-popup'
import { UsageSidebar } from './usage-sidebar'
import { useUsageToggle } from './usage-toggle-context'
import { useProfileToggle } from './profile-toggle-context'
import { useHistoryToggle } from './history-toggle-context'
import { useState, useEffect } from 'react'

export const Header = () => {
const { toggleCalendar } = useCalendarToggle()
const [isPurchaseOpen, setIsPurchaseOpen] = useState(false)
const [isUsageOpen, setIsUsageOpen] = useState(false)
const { toggleUsage, isUsageOpen } = useUsageToggle()
const { activeView, closeProfileView } = useProfileToggle()
const { toggleHistory } = useHistoryToggle()

const handleUsageToggle = () => {
// If we're about to open usage and profile is open, close profile first
if (!isUsageOpen && activeView) {
closeProfileView()
}
toggleUsage()
}

useEffect(() => {
// Open payment popup as soon as application opens
Expand All @@ -32,16 +44,15 @@ export const Header = () => {
return (
<>
<PurchaseCreditsPopup isOpen={isPurchaseOpen} onClose={() => setIsPurchaseOpen(false)} />
<UsageSidebar isOpen={isUsageOpen} onClose={() => setIsUsageOpen(false)} />
<header className="fixed w-full p-1 md:p-2 flex justify-between items-center z-20 backdrop-blur bg-background/95 border-b border-border/40">
<header className="fixed w-full p-1 md:p-2 flex justify-between items-center z-[60] backdrop-blur bg-background/95 border-b border-border/40">
<div>
<a href="/">
<span className="sr-only">Chat</span>
</a>
</div>

<div className="absolute left-1 flex items-center">
<Button variant="ghost" size="icon">
<Button variant="ghost" size="icon" onClick={toggleHistory} data-testid="logo-history-toggle">
<Image
src="/images/logo.svg"
alt="Logo"
Expand All @@ -67,7 +78,7 @@ export const Header = () => {

<div id="header-search-portal" />

<Button variant="ghost" size="icon" onClick={() => setIsUsageOpen(true)}>
<Button variant="ghost" size="icon" onClick={handleUsageToggle}>
<TentTree className="h-[1.2rem] w-[1.2rem]" />
</Button>

Expand All @@ -79,7 +90,7 @@ export const Header = () => {
{/* Mobile menu buttons */}
<div className="flex md:hidden gap-2">

<Button variant="ghost" size="icon" onClick={() => setIsUsageOpen(true)}>
<Button variant="ghost" size="icon" onClick={handleUsageToggle}>
<TentTree className="h-[1.2rem] w-[1.2rem]" />
</Button>
<ProfileToggle/>
Expand All @@ -89,4 +100,4 @@ export const Header = () => {
)
}

export default Header
export default Header
35 changes: 35 additions & 0 deletions components/history-sidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use client'

import {
Sheet,
SheetContent,
SheetHeader,
SheetTitle,
} from '@/components/ui/sheet'
import { History as HistoryIcon } from 'lucide-react'
import { ChatHistoryClient } from './sidebar/chat-history-client'
import { Suspense } from 'react'
import { HistorySkeleton } from './history-skelton'
import { useHistoryToggle } from './history-toggle-context'

export function HistorySidebar() {
const { isHistoryOpen, setHistoryOpen } = useHistoryToggle()

return (
<Sheet open={isHistoryOpen} onOpenChange={setHistoryOpen}>
<SheetContent className="w-64 rounded-tl-xl rounded-bl-xl" data-testid="history-panel">
<SheetHeader>
<SheetTitle className="flex items-center gap-1 text-sm font-normal mb-2">
<HistoryIcon size={14} />
History
</SheetTitle>
</SheetHeader>
<div className="my-2 h-full pb-12 md:pb-10">
<Suspense fallback={<HistorySkeleton />}>
<ChatHistoryClient />
</Suspense>
</div>
</SheetContent>
</Sheet>
)
}
30 changes: 30 additions & 0 deletions components/history-toggle-context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use client'

import { createContext, useContext, useState, ReactNode } from "react"

interface HistoryToggleContextType {
isHistoryOpen: boolean
toggleHistory: () => void
setHistoryOpen: (open: boolean) => void
}

const HistoryToggleContext = createContext<HistoryToggleContextType | undefined>(undefined)

export const HistoryToggleProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [isHistoryOpen, setIsHistoryOpen] = useState(false)

const toggleHistory = () => setIsHistoryOpen(prev => !prev)
const setHistoryOpen = (open: boolean) => setIsHistoryOpen(open)

return (
<HistoryToggleContext.Provider value={{ isHistoryOpen, toggleHistory, setHistoryOpen }}>
{children}
</HistoryToggleContext.Provider>
)
}

export const useHistoryToggle = () => {
const context = useContext(HistoryToggleContext)
if (!context) throw new Error('useHistoryToggle must be used within HistoryToggleProvider')
return context
}
54 changes: 16 additions & 38 deletions components/history.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,28 @@
import {
Sheet,
SheetContent,
SheetHeader,
SheetTitle,
SheetTrigger
} from '@/components/ui/sheet'
'use client'

import { Button } from '@/components/ui/button'
import { ChevronLeft, Menu } from 'lucide-react'
import { cn } from '@/lib/utils'
import { History as HistoryIcon } from 'lucide-react'
import { ChatHistoryClient } from './sidebar/chat-history-client' // Updated import
import { Suspense } from 'react'
import { HistorySkeleton } from './history-skelton'
import { useHistoryToggle } from './history-toggle-context'

type HistoryProps = {
location: 'sidebar' | 'header'
}

export function History({ location }: HistoryProps) {
const { toggleHistory } = useHistoryToggle()

return (
<Sheet>
<SheetTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn({
'rounded-full text-foreground/30': location === 'sidebar'
})}
data-testid="history-button"
>
{location === 'header' ? <Menu /> : <ChevronLeft size={16} />}
</Button>
</SheetTrigger>
<SheetContent className="w-64 rounded-tl-xl rounded-bl-xl" data-testid="history-panel">
<SheetHeader>
<SheetTitle className="flex items-center gap-1 text-sm font-normal mb-2">
<HistoryIcon size={14} />
History
</SheetTitle>
</SheetHeader>
<div className="my-2 h-full pb-12 md:pb-10">
<Suspense fallback={<HistorySkeleton />}>
<ChatHistoryClient />
</Suspense>
</div>
</SheetContent>
</Sheet>
<Button
variant="ghost"
size="icon"
className={cn({
'rounded-full text-foreground/30': location === 'sidebar'
})}
data-testid="history-button"
onClick={toggleHistory}
>
{location === 'header' ? <Menu /> : <ChevronLeft size={16} />}
</Button>
)
}
7 changes: 6 additions & 1 deletion components/profile-toggle-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export enum ProfileToggleEnum {
interface ProfileToggleContextType {
activeView: ProfileToggleEnum | null
toggleProfileSection: (section: ProfileToggleEnum) => void
closeProfileView: () => void
}

const ProfileToggleContext = createContext<ProfileToggleContextType | undefined>(undefined)
Expand All @@ -28,8 +29,12 @@ export const ProfileToggleProvider: React.FC<ProfileToggleProviderProps> = ({ ch
setActiveView(prevView => (prevView === section ? null : section))
}

const closeProfileView = () => {
setActiveView(null)
}

return (
<ProfileToggleContext.Provider value={{ activeView, toggleProfileSection }}>
<ProfileToggleContext.Provider value={{ activeView, toggleProfileSection, closeProfileView }}>
{children}
</ProfileToggleContext.Provider>
)
Expand Down
18 changes: 12 additions & 6 deletions components/profile-toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { User, Settings, Paintbrush, Shield, CircleUserRound } from "lucide-reac
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import { Button } from "@/components/ui/button"
import { ProfileToggleEnum, useProfileToggle } from "./profile-toggle-context"
import { useUsageToggle } from "./usage-toggle-context"

export function ProfileToggle() {
const { toggleProfileSection } = useProfileToggle()
const { toggleProfileSection, activeView } = useProfileToggle()
const { isUsageOpen, closeUsage } = useUsageToggle()
const [alignValue, setAlignValue] = useState<'start' | 'end'>("end")
const [isMobile, setIsMobile] = useState(false)

Expand All @@ -32,7 +34,11 @@ export function ProfileToggle() {
return () => window.removeEventListener("resize", debouncedResize)
}, [])

const handleSectionChange = (section: ProfileToggleEnum) => {
const handleSectionToggle = (section: ProfileToggleEnum) => {
// If we're about to open a profile section and usage is open, close usage first
if (activeView !== section && isUsageOpen) {
closeUsage()
}
toggleProfileSection(section)
}

Expand All @@ -54,19 +60,19 @@ export function ProfileToggle() {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56" align={alignValue} forceMount>
<DropdownMenuItem onClick={() => handleSectionChange(ProfileToggleEnum.Account)} data-testid="profile-account">
<DropdownMenuItem onClick={() => handleSectionToggle(ProfileToggleEnum.Account)} data-testid="profile-account">
<User className="mr-2 h-4 w-4" />
<span>Account</span>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleSectionChange(ProfileToggleEnum.Settings)} data-testid="profile-settings">
<DropdownMenuItem onClick={() => handleSectionToggle(ProfileToggleEnum.Settings)} data-testid="profile-settings">
<Settings className="mr-2 h-4 w-4" />
<span>Settings</span>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleSectionChange(ProfileToggleEnum.Appearance)} data-testid="profile-appearance">
<DropdownMenuItem onClick={() => handleSectionToggle(ProfileToggleEnum.Appearance)} data-testid="profile-appearance">
<Paintbrush className="mr-2 h-4 w-4" />
<span>Appearance</span>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleSectionChange(ProfileToggleEnum.Security)} data-testid="profile-security">
<DropdownMenuItem onClick={() => handleSectionToggle(ProfileToggleEnum.Security)} data-testid="profile-security">
<Shield className="mr-2 h-4 w-4" />
<span>Security</span>
</DropdownMenuItem>
Expand Down
Loading