ui improvement + fix search card in deck manager that leaded to a crash when card was found
This commit is contained in:
@@ -82,7 +82,7 @@ define(['./workbox-ca84f546'], (function (workbox) { 'use strict';
|
||||
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
||||
}, {
|
||||
"url": "index.html",
|
||||
"revision": "0.8gqbvnk5km4"
|
||||
"revision": "0.bbuf8ja4298"
|
||||
}], {});
|
||||
workbox.cleanupOutdatedCaches();
|
||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||
|
||||
10
src/App.tsx
10
src/App.tsx
@@ -40,7 +40,7 @@ function AppContent() {
|
||||
switch (currentPage) {
|
||||
case 'home':
|
||||
return (
|
||||
<div className="bg-gray-900 text-white p-3 sm:p-6 animate-fade-in">
|
||||
<div className="relative bg-gray-900 text-white p-3 sm:p-6 animate-fade-in md:min-h-screen">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<h1 className="text-2xl md:text-3xl font-bold mb-4 md:mb-6 animate-slide-in-left">My Decks</h1>
|
||||
<DeckList
|
||||
@@ -78,10 +78,12 @@ function AppContent() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-900">
|
||||
<div className="min-h-screen bg-gray-900 flex flex-col">
|
||||
<Navigation currentPage={currentPage} setCurrentPage={setCurrentPage} />
|
||||
<main className="pt-0 pb-20 md:pt-16 md:pb-0">
|
||||
{renderPage()}
|
||||
<main className="relative flex-1 overflow-y-auto pt-0 md:pt-16">
|
||||
<div className="relative min-h-full pb-20 md:pb-0">
|
||||
{renderPage()}
|
||||
</div>
|
||||
</main>
|
||||
<PWAInstallPrompt />
|
||||
</div>
|
||||
|
||||
@@ -201,7 +201,7 @@ const CardSearch = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-gray-900 text-white p-3 sm:p-6">
|
||||
<div className="relative bg-gray-900 text-white p-3 sm:p-6 md:min-h-screen">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<h1 className="text-2xl md:text-3xl font-bold mb-4 md:mb-6">Card Search</h1>
|
||||
<form onSubmit={handleSearch} className="mb-8 space-y-4">
|
||||
@@ -774,7 +774,7 @@ const CardSearch = () => {
|
||||
<div
|
||||
className={`fixed bottom-4 right-4 p-4 rounded-lg shadow-lg transition-all duration-300 ${
|
||||
snackbar.type === 'success' ? 'bg-green-500' : 'bg-red-500'
|
||||
} text-white z-50`}
|
||||
} text-white z-[140]`}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
|
||||
@@ -189,7 +189,7 @@ export default function Collection() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-gray-900 text-white p-3 sm:p-6">
|
||||
<div className="relative bg-gray-900 text-white p-3 sm:p-6 md:min-h-screen">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<h1 className="text-2xl md:text-3xl font-bold mb-4 md:mb-6">My Collection</h1>
|
||||
|
||||
@@ -295,7 +295,7 @@ export default function Collection() {
|
||||
const displayOracleText = currentFace?.oracle_text || hoveredCard.oracle_text;
|
||||
|
||||
return (
|
||||
<div className="hidden lg:block fixed top-1/2 right-8 transform -translate-y-1/2 z-40 pointer-events-none">
|
||||
<div className="hidden lg:block fixed top-1/2 right-8 transform -translate-y-1/2 z-30 pointer-events-none">
|
||||
<div className="bg-gray-800 rounded-lg shadow-2xl p-4 max-w-md">
|
||||
<div className="relative">
|
||||
<img
|
||||
@@ -344,16 +344,16 @@ export default function Collection() {
|
||||
<>
|
||||
{/* Backdrop */}
|
||||
<div
|
||||
className="fixed inset-0 bg-black bg-opacity-50 z-40 transition-opacity duration-300"
|
||||
className="fixed inset-0 bg-black bg-opacity-50 z-[110] transition-opacity duration-300"
|
||||
onClick={() => setSelectedCard(null)}
|
||||
/>
|
||||
|
||||
{/* Sliding Panel */}
|
||||
<div className="fixed top-0 right-0 h-full w-full md:w-96 bg-gray-800 shadow-2xl z-50 overflow-y-auto animate-slide-in-right">
|
||||
<div className="fixed top-0 right-0 h-full w-full md:w-96 bg-gray-800 shadow-2xl z-[120] overflow-y-auto animate-slide-in-right">
|
||||
{/* Close button - fixed position, stays visible when scrolling */}
|
||||
<button
|
||||
onClick={() => setSelectedCard(null)}
|
||||
className="fixed top-4 right-4 bg-gray-700 hover:bg-gray-600 text-white p-2 md:p-1.5 rounded-full transition-colors z-[60] shadow-lg"
|
||||
className="fixed top-4 right-4 bg-gray-700 hover:bg-gray-600 text-white p-2 md:p-1.5 rounded-full transition-colors z-[130] shadow-lg"
|
||||
aria-label="Close"
|
||||
>
|
||||
<X size={24} className="md:w-5 md:h-5" />
|
||||
@@ -478,7 +478,7 @@ export default function Collection() {
|
||||
<div
|
||||
className={`fixed bottom-4 right-4 p-4 rounded-lg shadow-lg transition-all duration-300 ${
|
||||
snackbar.type === 'success' ? 'bg-green-500' : 'bg-red-500'
|
||||
} text-white z-50`}
|
||||
} text-white z-[140]`}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
|
||||
@@ -480,7 +480,7 @@ export default function Community() {
|
||||
|
||||
// ============ MAIN VIEW ============
|
||||
return (
|
||||
<div className="bg-gray-900 text-white min-h-screen">
|
||||
<div className="relative bg-gray-900 text-white md:min-h-screen">
|
||||
{/* Header */}
|
||||
<div className="sticky top-0 bg-gray-900/95 backdrop-blur border-b border-gray-800 p-3 z-10">
|
||||
<h1 className="text-xl font-bold mb-3">Community</h1>
|
||||
|
||||
@@ -31,7 +31,7 @@ export default function DeckBuilder({
|
||||
initial={{ x: "100%" }}
|
||||
animate={{ x: isOpen ? "0%" : "100%" }}
|
||||
transition={{ type: "spring", stiffness: 300, damping: 30 }}
|
||||
className="fixed top-0 right-0 w-4/5 h-full bg-gray-800 p-6 shadow-lg md:static md:w-full md:h-auto md:p-6 md:shadow-none z-50"
|
||||
className="fixed top-0 right-0 w-4/5 h-full bg-gray-800 p-6 shadow-lg md:static md:w-full md:h-auto md:p-6 md:shadow-none z-[110]"
|
||||
>
|
||||
{/* Bouton de fermeture */}
|
||||
<button
|
||||
@@ -117,4 +117,4 @@ export default function DeckBuilder({
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ export default function DeckEditor({ deckId, onClose }: DeckEditorProps) {
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-900 text-white p-6 flex items-center justify-center">
|
||||
<div className="relative md:min-h-screen bg-gray-900 text-white p-6 flex items-center justify-center">
|
||||
<div className="animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-blue-500"></div>
|
||||
</div>
|
||||
);
|
||||
@@ -70,7 +70,7 @@ export default function DeckEditor({ deckId, onClose }: DeckEditorProps) {
|
||||
|
||||
if (!deck) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-900 text-white p-6">
|
||||
<div className="relative md:min-h-screen bg-gray-900 text-white p-6">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="bg-red-500/10 border border-red-500 rounded-lg p-4">
|
||||
<h2 className="text-xl font-bold text-red-500">Error</h2>
|
||||
@@ -82,4 +82,4 @@ export default function DeckEditor({ deckId, onClose }: DeckEditorProps) {
|
||||
}
|
||||
|
||||
return <DeckManager initialDeck={deck} onSave={onClose} />;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ export default function DeckManager({ initialDeck, onSave }: DeckManagerProps) {
|
||||
const [currentDeckId, setCurrentDeckId] = useState<string | null>(initialDeck?.id || null);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [searchResults, setSearchResults] = useState<Card[]>([]);
|
||||
const [isSearching, setIsSearching] = useState(false);
|
||||
const [selectedCards, setSelectedCards] = useState<{
|
||||
card: Card;
|
||||
quantity: number;
|
||||
@@ -296,11 +297,16 @@ export default function DeckManager({ initialDeck, onSave }: DeckManagerProps) {
|
||||
e.preventDefault();
|
||||
if (!searchQuery.trim()) return;
|
||||
|
||||
setIsSearching(true);
|
||||
try {
|
||||
const cards = await searchCards(searchQuery);
|
||||
setSearchResults(cards);
|
||||
setSearchResults(cards || []);
|
||||
} catch (error) {
|
||||
console.error('Failed to search cards:', error);
|
||||
setSearchResults([]);
|
||||
setSnackbar({ message: 'Failed to search cards', type: 'error' });
|
||||
} finally {
|
||||
setIsSearching(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -538,7 +544,7 @@ export default function DeckManager({ initialDeck, onSave }: DeckManagerProps) {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-gray-900 text-white p-3 sm:p-6 pt-6 pb-20 md:pt-20 md:pb-6">
|
||||
<div className="relative bg-gray-900 text-white p-3 sm:p-6 pt-6 pb-44 md:pt-20 md:pb-6 md:min-h-screen">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4 sm:gap-6">
|
||||
{/* Card Search Section */}
|
||||
@@ -575,7 +581,17 @@ export default function DeckManager({ initialDeck, onSave }: DeckManagerProps) {
|
||||
|
||||
{/* Vertical Card List for Mobile */}
|
||||
<div className="space-y-2">
|
||||
{searchResults.map(card => {
|
||||
{isSearching ? (
|
||||
<div className="flex items-center justify-center py-12">
|
||||
<Loader2 className="animate-spin text-blue-500" size={48} />
|
||||
</div>
|
||||
) : searchResults.length === 0 && searchQuery ? (
|
||||
<div className="text-center py-12 text-gray-400">
|
||||
<p className="text-lg mb-2">No cards found</p>
|
||||
<p className="text-sm">Try a different search term</p>
|
||||
</div>
|
||||
) : (
|
||||
searchResults.map(card => {
|
||||
const currentFaceIndex = getCurrentFaceIndex(card.id);
|
||||
const isMultiFaced = isDoubleFaced(card);
|
||||
const inCollection = userCollection.get(card.id) || 0;
|
||||
@@ -702,7 +718,8 @@ export default function DeckManager({ initialDeck, onSave }: DeckManagerProps) {
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
})
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -876,10 +893,6 @@ export default function DeckManager({ initialDeck, onSave }: DeckManagerProps) {
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="font-bold text-xl">
|
||||
Total Price: ${totalPrice.toFixed(2)}
|
||||
</div>
|
||||
|
||||
{deckSize > 0 && suggestedLandCountValue > 0 && (
|
||||
<div className="bg-gray-700 rounded-lg p-3">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
@@ -906,49 +919,62 @@ export default function DeckManager({ initialDeck, onSave }: DeckManagerProps) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex gap-2">
|
||||
{!isLoadingCollection && getMissingCards().length > 0 && (
|
||||
<button
|
||||
onClick={handleAddAllMissingCards}
|
||||
disabled={isAddingAll}
|
||||
className="flex-1 px-4 py-2 bg-yellow-600 hover:bg-yellow-700 disabled:bg-gray-600 disabled:cursor-not-allowed rounded-lg flex items-center justify-center gap-2"
|
||||
title="Add missing cards to collection"
|
||||
>
|
||||
{isAddingAll ? (
|
||||
<Loader2 className="animate-spin" size={20} />
|
||||
) : (
|
||||
<>
|
||||
<PackagePlus size={20} />
|
||||
<span className="hidden sm:inline">Add Missing</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={saveDeck}
|
||||
disabled={
|
||||
!deckName.trim() || selectedCards.length === 0 || isSaving
|
||||
}
|
||||
className="flex-1 px-4 py-2 bg-green-600 hover:bg-green-700 disabled:bg-gray-600 disabled:cursor-not-allowed rounded-lg flex items-center justify-center gap-2 relative"
|
||||
>
|
||||
{isSaving ? (
|
||||
<>
|
||||
<Loader2 className="animate-spin text-white absolute left-2 top-1/2 -translate-y-1/2" size={20} />
|
||||
<span className="opacity-0">Save Deck</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Save size={20} />
|
||||
<span>{initialDeck ? 'Update Deck' : 'Save Deck'}</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Fixed Footer with Price and Actions - Mobile First */}
|
||||
<div className="fixed bottom-16 left-0 right-0 md:left-auto md:right-4 md:bottom-4 md:w-80 z-20 bg-gray-800 border-t border-gray-700 md:border md:rounded-lg shadow-2xl">
|
||||
<div className="p-3 space-y-3">
|
||||
{/* Total Price */}
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm font-semibold text-gray-300">Total Price</span>
|
||||
<span className="text-xl font-bold text-green-400">${totalPrice.toFixed(2)}</span>
|
||||
</div>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<div className="flex gap-2">
|
||||
{!isLoadingCollection && getMissingCards().length > 0 && (
|
||||
<button
|
||||
onClick={handleAddAllMissingCards}
|
||||
disabled={isAddingAll}
|
||||
className="flex-1 px-3 py-2 bg-yellow-600 hover:bg-yellow-700 disabled:bg-gray-600 disabled:cursor-not-allowed rounded-lg flex items-center justify-center gap-2 text-sm font-medium transition-colors"
|
||||
title="Add missing cards to collection"
|
||||
>
|
||||
{isAddingAll ? (
|
||||
<Loader2 className="animate-spin" size={18} />
|
||||
) : (
|
||||
<>
|
||||
<PackagePlus size={18} />
|
||||
<span className="hidden sm:inline">Add Missing</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={saveDeck}
|
||||
disabled={
|
||||
!deckName.trim() || selectedCards.length === 0 || isSaving
|
||||
}
|
||||
className="flex-1 px-3 py-2 bg-green-600 hover:bg-green-700 disabled:bg-gray-600 disabled:cursor-not-allowed rounded-lg flex items-center justify-center gap-2 text-sm font-medium relative transition-colors"
|
||||
>
|
||||
{isSaving ? (
|
||||
<>
|
||||
<Loader2 className="animate-spin text-white" size={18} />
|
||||
<span>Saving...</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Save size={18} />
|
||||
<span>{initialDeck ? 'Update' : 'Save'}</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Hover Card Preview - only show if no card is selected */}
|
||||
{hoveredCard && !selectedCard && (() => {
|
||||
const currentFaceIndex = getCurrentFaceIndex(hoveredCard.id);
|
||||
@@ -962,7 +988,7 @@ export default function DeckManager({ initialDeck, onSave }: DeckManagerProps) {
|
||||
const displayOracleText = currentFace?.oracle_text || hoveredCard.oracle_text;
|
||||
|
||||
return (
|
||||
<div className="hidden lg:block fixed top-1/2 right-8 transform -translate-y-1/2 z-40 pointer-events-none">
|
||||
<div className="hidden lg:block fixed top-1/2 right-8 transform -translate-y-1/2 z-30 pointer-events-none">
|
||||
<div className="bg-gray-800 rounded-lg shadow-2xl p-4 max-w-md">
|
||||
<div className="relative">
|
||||
<img
|
||||
@@ -1011,16 +1037,16 @@ export default function DeckManager({ initialDeck, onSave }: DeckManagerProps) {
|
||||
<>
|
||||
{/* Backdrop */}
|
||||
<div
|
||||
className="fixed inset-0 bg-black bg-opacity-50 z-40 transition-opacity duration-300"
|
||||
className="fixed inset-0 bg-black bg-opacity-50 z-[110] transition-opacity duration-300"
|
||||
onClick={() => setSelectedCard(null)}
|
||||
/>
|
||||
|
||||
{/* Sliding Panel */}
|
||||
<div className="fixed top-0 right-0 h-full w-full md:w-96 bg-gray-800 shadow-2xl z-50 overflow-y-auto animate-slide-in-right">
|
||||
<div className="fixed top-0 right-0 h-full w-full md:w-96 bg-gray-800 shadow-2xl z-[120] overflow-y-auto animate-slide-in-right">
|
||||
{/* Close button */}
|
||||
<button
|
||||
onClick={() => setSelectedCard(null)}
|
||||
className="fixed top-4 right-4 bg-gray-700 hover:bg-gray-600 text-white p-2 md:p-1.5 rounded-full transition-colors z-[60] shadow-lg"
|
||||
className="fixed top-4 right-4 bg-gray-700 hover:bg-gray-600 text-white p-2 md:p-1.5 rounded-full transition-colors z-[130] shadow-lg"
|
||||
aria-label="Close"
|
||||
>
|
||||
<X size={24} className="md:w-5 md:h-5" />
|
||||
@@ -1125,7 +1151,7 @@ export default function DeckManager({ initialDeck, onSave }: DeckManagerProps) {
|
||||
|
||||
{snackbar && (
|
||||
<div
|
||||
className={`fixed bottom-4 right-4 bg-green-500 text-white p-4 rounded-lg shadow-lg transition-all duration-300 ${
|
||||
className={`fixed bottom-4 right-4 text-white p-4 rounded-lg shadow-lg transition-all duration-300 z-[140] ${
|
||||
snackbar.type === 'success' ? 'bg-green-500' : 'bg-red-500'
|
||||
}`}
|
||||
>
|
||||
|
||||
@@ -157,11 +157,11 @@ import React, { useState, useEffect } from 'react';
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-900 text-white p-6">
|
||||
<div className="relative md:min-h-screen bg-gray-900 text-white p-6">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<h1 className="text-3xl font-bold mb-6">Life Counter</h1>
|
||||
{!setupComplete ? renderSetupForm() : renderLifeCounters()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,12 +53,12 @@ export default function Modal({
|
||||
<>
|
||||
{/* Backdrop */}
|
||||
<div
|
||||
className="fixed inset-0 bg-black bg-opacity-50 z-50 transition-opacity duration-300 animate-fade-in"
|
||||
className="fixed inset-0 bg-black bg-opacity-50 z-[110] transition-opacity duration-300 animate-fade-in"
|
||||
onClick={onClose}
|
||||
/>
|
||||
|
||||
{/* Modal */}
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 pointer-events-none">
|
||||
<div className="fixed inset-0 z-[120] flex items-center justify-center p-4 pointer-events-none">
|
||||
<div
|
||||
className={`${sizeClasses[size]} w-full bg-gray-800 rounded-lg shadow-2xl pointer-events-auto animate-scale-in`}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
|
||||
@@ -69,7 +69,7 @@ export default function Navigation({ currentPage, setCurrentPage }: NavigationPr
|
||||
return (
|
||||
<>
|
||||
{/* Desktop Navigation - Top */}
|
||||
<nav className="hidden md:block fixed top-0 left-0 right-0 bg-gray-800 border-b border-gray-700 z-50 animate-slide-in-left">
|
||||
<nav className="hidden md:block fixed top-0 left-0 right-0 bg-gray-800 border-b border-gray-700 z-[100] animate-slide-in-left">
|
||||
<div className="max-w-7xl mx-auto px-4">
|
||||
<div className="flex items-center justify-between h-16">
|
||||
<div className="flex items-center space-x-8">
|
||||
@@ -107,7 +107,7 @@ export default function Navigation({ currentPage, setCurrentPage }: NavigationPr
|
||||
</button>
|
||||
|
||||
{showDropdown && (
|
||||
<div className="absolute right-0 mt-2 w-48 bg-gray-800 rounded-md shadow-lg py-1 border border-gray-700 animate-scale-in glass-effect">
|
||||
<div className="absolute right-0 mt-2 w-48 bg-gray-800 rounded-md shadow-lg py-1 border border-gray-700 animate-scale-in glass-effect z-[110]">
|
||||
<button
|
||||
onClick={handleSignOut}
|
||||
className="flex items-center space-x-2 w-full px-4 py-2 text-sm text-gray-300 hover:bg-gray-700 transition-smooth"
|
||||
|
||||
@@ -85,7 +85,7 @@ export default function PWAInstallPrompt() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed bottom-20 md:bottom-4 left-4 right-4 md:left-auto md:right-4 md:max-w-sm z-50 animate-slide-in-bottom">
|
||||
<div className="fixed bottom-20 md:bottom-4 left-4 right-4 md:left-auto md:right-4 md:max-w-sm z-[105] animate-slide-in-bottom">
|
||||
<div className="bg-gradient-to-r from-blue-600 to-purple-600 rounded-lg shadow-2xl p-4 text-white">
|
||||
<button
|
||||
onClick={handleDismiss}
|
||||
|
||||
@@ -340,14 +340,14 @@ export default function TradeCreator({
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black/80 z-50 flex items-center justify-center">
|
||||
<div className="fixed inset-0 bg-black/80 z-[110] flex items-center justify-center">
|
||||
<Loader2 className="animate-spin text-blue-500" size={48} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black/80 z-50 flex items-center justify-center p-0 md:p-4">
|
||||
<div className="fixed inset-0 bg-black/80 z-[110] flex items-center justify-center p-0 md:p-4">
|
||||
<div className="bg-gray-800 w-full h-full md:rounded-lg md:w-full md:max-w-6xl md:max-h-[90vh] overflow-hidden flex flex-col">
|
||||
|
||||
{/* ============ MOBILE VIEW ============ */}
|
||||
|
||||
Reference in New Issue
Block a user