added background to campain pill
This commit is contained in:
parent
e09739fc01
commit
69fd462bf5
78
src/App.js
78
src/App.js
@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef } from 'react';
|
||||
import { initializeApp } from 'firebase/app';
|
||||
import { getAuth, signInAnonymously, onAuthStateChanged, signInWithCustomToken } from 'firebase/auth';
|
||||
import { getFirestore, doc, setDoc, addDoc, getDoc, getDocs, collection, onSnapshot, updateDoc, deleteDoc, query, writeBatch } from 'firebase/firestore';
|
||||
import { PlusCircle, Users, Swords, Shield, Trash2, Eye, Edit3, Save, XCircle, ChevronsUpDown, UserCheck, UserX, HeartCrack, HeartPulse, Zap, Image as ImageIcon, EyeOff, ExternalLink, AlertTriangle } from 'lucide-react'; // Added AlertTriangle
|
||||
import { PlusCircle, Users, Swords, Shield, Trash2, Eye, Edit3, Save, XCircle, ChevronsUpDown, UserCheck, UserX, HeartCrack, HeartPulse, Zap, /* ImageIcon removed */ EyeOff, ExternalLink, AlertTriangle } from 'lucide-react'; // ImageIcon removed
|
||||
|
||||
// --- Firebase Configuration ---
|
||||
const firebaseConfig = {
|
||||
@ -126,7 +126,7 @@ function useFirestoreCollection(collectionPath, queryConstraints = []) {
|
||||
|
||||
// --- Main App Component ---
|
||||
function App() {
|
||||
const [userId, setUserId] = useState(null); // Kept for potential future use, but not displayed
|
||||
const [userId, setUserId] = useState(null);
|
||||
const [isAuthReady, setIsAuthReady] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
@ -218,7 +218,6 @@ function App() {
|
||||
TTRPG Initiative Tracker
|
||||
</h1>
|
||||
<div className="flex items-center space-x-4">
|
||||
{/* UID display removed from header */}
|
||||
<button
|
||||
onClick={openPlayerWindow}
|
||||
className={`px-4 py-2 rounded-md text-sm font-medium transition-colors bg-teal-500 hover:bg-teal-600 text-white flex items-center`}
|
||||
@ -234,7 +233,7 @@ function App() {
|
||||
{!isAuthReady && !error && <p>Authenticating...</p>}
|
||||
</main>
|
||||
<footer className="bg-slate-900 p-4 text-center text-sm text-slate-400 mt-8">
|
||||
TTRPG Initiative Tracker v0.1.23
|
||||
TTRPG Initiative Tracker v0.1.24
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
@ -281,7 +280,7 @@ function AdminView({ userId }) {
|
||||
const [selectedCampaignId, setSelectedCampaignId] = useState(null);
|
||||
const [showCreateCampaignModal, setShowCreateCampaignModal] = useState(false);
|
||||
const [showDeleteCampaignConfirm, setShowDeleteCampaignConfirm] = useState(false);
|
||||
const [itemToDelete, setItemToDelete] = useState(null); // { id, name, type: 'campaign' }
|
||||
const [itemToDelete, setItemToDelete] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (campaignsData) {
|
||||
@ -360,26 +359,35 @@ function AdminView({ userId }) {
|
||||
</div>
|
||||
{campaigns.length === 0 && <p className="text-slate-400">No campaigns yet.</p>}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{campaigns.map(campaign => (
|
||||
<div
|
||||
key={campaign.id}
|
||||
onClick={() => setSelectedCampaignId(campaign.id)}
|
||||
className={`p-4 rounded-lg shadow-md cursor-pointer transition-all ${selectedCampaignId === campaign.id ? 'bg-sky-700 ring-2 ring-sky-400' : 'bg-slate-700 hover:bg-slate-600'}`}
|
||||
>
|
||||
<h3 className="text-xl font-semibold text-white">{campaign.name}</h3>
|
||||
{/* Campaign ID display removed */}
|
||||
{campaign.playerDisplayBackgroundUrl && <ImageIcon size={14} className="inline-block mr-1 text-slate-400" title="Has custom background"/>}
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
requestDeleteCampaign(campaign.id, campaign.name);
|
||||
}}
|
||||
className="mt-2 text-red-400 hover:text-red-300 text-xs flex items-center"
|
||||
{campaigns.map(campaign => {
|
||||
const cardStyle = campaign.playerDisplayBackgroundUrl ? {
|
||||
backgroundImage: `url(${campaign.playerDisplayBackgroundUrl})`,
|
||||
} : {};
|
||||
const cardClasses = `p-4 rounded-lg shadow-md cursor-pointer transition-all relative overflow-hidden bg-cover bg-center ${selectedCampaignId === campaign.id ? 'ring-4 ring-sky-400' : ''} ${!campaign.playerDisplayBackgroundUrl ? 'bg-slate-700 hover:bg-slate-600' : 'hover:shadow-xl'}`;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={campaign.id}
|
||||
onClick={() => setSelectedCampaignId(campaign.id)}
|
||||
className={cardClasses}
|
||||
style={cardStyle}
|
||||
>
|
||||
<Trash2 size={14} className="mr-1" /> Delete
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
{/* Overlay for text readability if background image exists */}
|
||||
<div className={`relative z-10 ${campaign.playerDisplayBackgroundUrl ? 'bg-black bg-opacity-60 p-3 rounded-md' : ''}`}>
|
||||
<h3 className="text-xl font-semibold text-white">{campaign.name}</h3>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
requestDeleteCampaign(campaign.id, campaign.name);
|
||||
}}
|
||||
className="mt-2 text-red-300 hover:text-red-100 text-xs flex items-center bg-black bg-opacity-50 hover:bg-opacity-70 px-2 py-1 rounded"
|
||||
>
|
||||
<Trash2 size={14} className="mr-1" /> Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
{showCreateCampaignModal && <Modal onClose={() => setShowCreateCampaignModal(false)} title="Create New Campaign"><CreateCampaignForm onCreate={handleCreateCampaign} onCancel={() => setShowCreateCampaignModal(false)} /></Modal>}
|
||||
@ -407,7 +415,13 @@ function AdminView({ userId }) {
|
||||
);
|
||||
}
|
||||
|
||||
// ... (CreateCampaignForm remains the same)
|
||||
// ... (CreateCampaignForm, CharacterManager, EncounterManager, CreateEncounterForm, ParticipantManager, EditParticipantModal, InitiativeControls, DisplayView, Modal, Icons remain the same as v0.1.23)
|
||||
// For brevity, only the changed AdminView is shown in full. The rest of the components are identical to the previous version.
|
||||
// The DisplayView, CharacterManager, EncounterManager, etc., and their sub-components
|
||||
// (CreateEncounterForm, ParticipantManager, EditParticipantModal, InitiativeControls)
|
||||
// are not changed from the previous version provided (v0.1.23).
|
||||
// The Modal component and Icon components also remain unchanged.
|
||||
|
||||
function CreateCampaignForm({ onCreate, onCancel }) {
|
||||
const [name, setName] = useState('');
|
||||
const [backgroundUrl, setBackgroundUrl] = useState('');
|
||||
@ -436,12 +450,11 @@ function CreateCampaignForm({ onCreate, onCancel }) {
|
||||
}
|
||||
|
||||
|
||||
// --- CharacterManager ---
|
||||
function CharacterManager({ campaignId, campaignCharacters }) {
|
||||
const [characterName, setCharacterName] = useState('');
|
||||
const [editingCharacter, setEditingCharacter] = useState(null);
|
||||
const [showDeleteCharConfirm, setShowDeleteCharConfirm] = useState(false);
|
||||
const [itemToDelete, setItemToDelete] = useState(null); // { id, name, type: 'character' }
|
||||
const [itemToDelete, setItemToDelete] = useState(null);
|
||||
|
||||
|
||||
const handleAddCharacter = async () => {
|
||||
@ -512,7 +525,6 @@ function CharacterManager({ campaignId, campaignCharacters }) {
|
||||
);
|
||||
}
|
||||
|
||||
// --- EncounterManager ---
|
||||
function EncounterManager({ campaignId, initialActiveEncounterId, campaignCharacters }) {
|
||||
const {data: encountersData, isLoading: isLoadingEncounters } = useFirestoreCollection(campaignId ? getEncountersCollectionPath(campaignId) : null);
|
||||
const {data: activeDisplayInfo } = useFirestoreDocument(getActiveDisplayDocPath());
|
||||
@ -521,7 +533,7 @@ function EncounterManager({ campaignId, initialActiveEncounterId, campaignCharac
|
||||
const [selectedEncounterId, setSelectedEncounterId] = useState(null);
|
||||
const [showCreateEncounterModal, setShowCreateEncounterModal] = useState(false);
|
||||
const [showDeleteEncounterConfirm, setShowDeleteEncounterConfirm] = useState(false);
|
||||
const [itemToDelete, setItemToDelete] = useState(null); // { id, name, type: 'encounter' }
|
||||
const [itemToDelete, setItemToDelete] = useState(null);
|
||||
|
||||
const selectedEncounterIdRef = useRef(selectedEncounterId);
|
||||
|
||||
@ -669,10 +681,6 @@ function EncounterManager({ campaignId, initialActiveEncounterId, campaignCharac
|
||||
);
|
||||
}
|
||||
|
||||
// ... (CreateEncounterForm, ParticipantManager, EditParticipantModal, InitiativeControls, DisplayView, Modal, Icons)
|
||||
// The rest of the components remain the same as in v0.1.22, with the following changes in ParticipantManager and InitiativeControls
|
||||
// to use the ConfirmationModal for delete/end actions.
|
||||
|
||||
function CreateEncounterForm({ onCreate, onCancel }) {
|
||||
const [name, setName] = useState('');
|
||||
return (
|
||||
@ -699,7 +707,7 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) {
|
||||
const [hpChangeValues, setHpChangeValues] = useState({});
|
||||
const [draggedItemId, setDraggedItemId] = useState(null);
|
||||
const [showDeleteParticipantConfirm, setShowDeleteParticipantConfirm] = useState(false);
|
||||
const [itemToDelete, setItemToDelete] = useState(null); // { id, name, type: 'participant' }
|
||||
const [itemToDelete, setItemToDelete] = useState(null);
|
||||
|
||||
|
||||
const participants = encounter.participants || [];
|
||||
@ -1143,7 +1151,7 @@ function DisplayView() {
|
||||
|
||||
const { name, participants, round, currentTurnParticipantId, isStarted } = activeEncounterData;
|
||||
|
||||
let participantsToRender = []; // Renamed from displayParticipants for clarity
|
||||
let participantsToRender = [];
|
||||
if (participants) {
|
||||
if (isStarted && activeEncounterData.turnOrderIds?.length > 0 ) {
|
||||
participantsToRender = activeEncounterData.turnOrderIds
|
||||
|
Loading…
x
Reference in New Issue
Block a user