mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-24 13:44:54 +00:00
Generated by Spark: Add a quick save indicator showing when project was last saved
This commit is contained in:
22
src/App.tsx
22
src/App.tsx
@@ -38,6 +38,7 @@ import { FeatureIdeaCloud } from '@/components/FeatureIdeaCloud'
|
||||
import { GlobalSearch } from '@/components/GlobalSearch'
|
||||
import { NavigationMenu } from '@/components/NavigationMenu'
|
||||
import { PageHeader } from '@/components/PageHeader'
|
||||
import { SaveIndicator } from '@/components/SaveIndicator'
|
||||
import { useKeyboardShortcuts } from '@/hooks/use-keyboard-shortcuts'
|
||||
import { generateNextJSProject, generatePrismaSchema, generateMUITheme, generatePlaywrightTests, generateStorybookStories, generateUnitTests, generateFlaskApp } from '@/lib/generators'
|
||||
import { AIService } from '@/lib/ai-service'
|
||||
@@ -200,6 +201,7 @@ function App() {
|
||||
const [shortcutsDialogOpen, setShortcutsDialogOpen] = useState(false)
|
||||
const [searchDialogOpen, setSearchDialogOpen] = useState(false)
|
||||
const [generatedCode, setGeneratedCode] = useState<Record<string, string>>({})
|
||||
const [lastSaved, setLastSaved] = useState<number | null>(Date.now())
|
||||
|
||||
const safeFiles = files || []
|
||||
const safeModels = models || []
|
||||
@@ -236,6 +238,25 @@ function App() {
|
||||
}
|
||||
}, [featureToggles, setFeatureToggles])
|
||||
|
||||
useEffect(() => {
|
||||
setLastSaved(Date.now())
|
||||
}, [
|
||||
files,
|
||||
models,
|
||||
components,
|
||||
componentTrees,
|
||||
workflows,
|
||||
lambdas,
|
||||
theme,
|
||||
playwrightTests,
|
||||
storybookStories,
|
||||
unitTests,
|
||||
flaskConfig,
|
||||
nextjsConfig,
|
||||
npmSettings,
|
||||
featureToggles,
|
||||
])
|
||||
|
||||
const { errors: autoDetectedErrors } = useAutoRepair(safeFiles, false)
|
||||
|
||||
useKeyboardShortcuts([
|
||||
@@ -549,6 +570,7 @@ Navigate to the backend directory and follow the setup instructions.
|
||||
Low-Code Next.js App Builder
|
||||
</p>
|
||||
</div>
|
||||
<SaveIndicator lastSaved={lastSaved} />
|
||||
</div>
|
||||
<div className="flex gap-1 sm:gap-2 shrink-0">
|
||||
<Tooltip>
|
||||
|
||||
45
src/components/SaveIndicator.tsx
Normal file
45
src/components/SaveIndicator.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { CheckCircle, CloudCheck } from '@phosphor-icons/react'
|
||||
import { formatDistanceToNow } from 'date-fns'
|
||||
|
||||
interface SaveIndicatorProps {
|
||||
lastSaved: number | null
|
||||
}
|
||||
|
||||
export function SaveIndicator({ lastSaved }: SaveIndicatorProps) {
|
||||
const [timeAgo, setTimeAgo] = useState<string>('')
|
||||
|
||||
useEffect(() => {
|
||||
if (!lastSaved) return
|
||||
|
||||
const updateTimeAgo = () => {
|
||||
const distance = formatDistanceToNow(lastSaved, { addSuffix: true })
|
||||
setTimeAgo(distance)
|
||||
}
|
||||
|
||||
updateTimeAgo()
|
||||
const interval = setInterval(updateTimeAgo, 10000)
|
||||
|
||||
return () => clearInterval(interval)
|
||||
}, [lastSaved])
|
||||
|
||||
if (!lastSaved) return null
|
||||
|
||||
const isRecent = Date.now() - lastSaved < 3000
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-1.5 text-xs text-muted-foreground">
|
||||
{isRecent ? (
|
||||
<>
|
||||
<CheckCircle size={14} weight="fill" className="text-accent animate-in zoom-in duration-200" />
|
||||
<span className="hidden sm:inline">Saved</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<CloudCheck size={14} weight="duotone" />
|
||||
<span className="hidden sm:inline">{timeAgo}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user