feat: enforce 12-hour limit for active tasting sessions
This commit is contained in:
@@ -5,6 +5,7 @@ import Link from 'next/link';
|
||||
import { Search, Filter, X, Calendar, Clock, Package, Lock, Unlock, Ghost, FlaskConical, AlertCircle, Trash2, AlertTriangle, PlusCircle } from 'lucide-react';
|
||||
import { getStorageUrl } from '@/lib/supabase';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { validateSession } from '@/services/validate-session';
|
||||
|
||||
interface Bottle {
|
||||
id: string;
|
||||
@@ -115,6 +116,19 @@ interface BottleGridProps {
|
||||
export default function BottleGrid({ bottles }: BottleGridProps) {
|
||||
const searchParams = useSearchParams();
|
||||
const sessionId = searchParams.get('session_id');
|
||||
const [validatedSessionId, setValidatedSessionId] = useState<string | null>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
const checkSession = async () => {
|
||||
if (sessionId) {
|
||||
const isValid = await validateSession(sessionId);
|
||||
setValidatedSessionId(isValid ? sessionId : null);
|
||||
} else {
|
||||
setValidatedSessionId(null);
|
||||
}
|
||||
};
|
||||
checkSession();
|
||||
}, [sessionId]);
|
||||
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
|
||||
@@ -284,7 +298,7 @@ export default function BottleGrid({ bottles }: BottleGridProps) {
|
||||
{filteredBottles.length > 0 ? (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 w-full max-w-6xl mx-auto px-4">
|
||||
{filteredBottles.map((bottle) => (
|
||||
<BottleCard key={bottle.id} bottle={bottle} sessionId={sessionId} />
|
||||
<BottleCard key={bottle.id} bottle={bottle} sessionId={validatedSessionId} />
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -10,6 +10,7 @@ import { BottleMetadata } from '@/types/whisky';
|
||||
import { savePendingBottle } from '@/lib/offline-db';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { findMatchingBottle } from '@/services/find-matching-bottle';
|
||||
import { validateSession } from '@/services/validate-session';
|
||||
import Link from 'next/link';
|
||||
|
||||
interface CameraCaptureProps {
|
||||
@@ -23,6 +24,19 @@ export default function CameraCapture({ onImageCaptured, onAnalysisComplete, onS
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const sessionId = searchParams.get('session_id');
|
||||
const [validatedSessionId, setValidatedSessionId] = React.useState<string | null>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
const checkSession = async () => {
|
||||
if (sessionId) {
|
||||
const isValid = await validateSession(sessionId);
|
||||
setValidatedSessionId(isValid ? sessionId : null);
|
||||
} else {
|
||||
setValidatedSessionId(null);
|
||||
}
|
||||
};
|
||||
checkSession();
|
||||
}, [sessionId]);
|
||||
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const [isProcessing, setIsProcessing] = useState(false);
|
||||
@@ -222,7 +236,7 @@ export default function CameraCapture({ onImageCaptured, onAnalysisComplete, onS
|
||||
|
||||
<button
|
||||
onClick={() => {
|
||||
const url = `/bottles/${lastSavedId}${sessionId ? `?session_id=${sessionId}` : ''}`;
|
||||
const url = `/bottles/${lastSavedId}${validatedSessionId ? `?session_id=${validatedSessionId}` : ''}`;
|
||||
router.push(url);
|
||||
}}
|
||||
className="w-full py-4 px-6 bg-zinc-900 dark:bg-zinc-100 text-white dark:text-zinc-900 rounded-2xl font-black uppercase tracking-widest flex items-center justify-center gap-2 hover:bg-zinc-800 dark:hover:bg-white transition-all shadow-xl"
|
||||
@@ -244,7 +258,7 @@ export default function CameraCapture({ onImageCaptured, onAnalysisComplete, onS
|
||||
</div>
|
||||
) : matchingBottle ? (
|
||||
<Link
|
||||
href={`/bottles/${matchingBottle.id}${sessionId ? `?session_id=${sessionId}` : ''}`}
|
||||
href={`/bottles/${matchingBottle.id}${validatedSessionId ? `?session_id=${validatedSessionId}` : ''}`}
|
||||
className="w-full py-4 px-6 bg-amber-600 hover:bg-amber-700 text-white rounded-xl font-semibold flex items-center justify-center gap-2 transition-all active:scale-[0.98] shadow-lg shadow-amber-600/20"
|
||||
>
|
||||
<ExternalLink size={20} />
|
||||
|
||||
Reference in New Issue
Block a user