changed red color for monster display.

This commit is contained in:
Robert Johnson 2025-05-27 11:15:32 -04:00
parent 788e3cd1a2
commit 5f8602cd73

View File

@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef, useMemo } from 'react';
import { initializeApp } from 'firebase/app';
import { getAuth, signInAnonymously, onAuthStateChanged, signInWithCustomToken } from 'firebase/auth';
import { getFirestore, doc, setDoc, getDoc, getDocs, collection, onSnapshot, updateDoc, deleteDoc, query, writeBatch } from 'firebase/firestore';
import { PlusCircle, Users, Swords, Trash2, Eye, Edit3, Save, XCircle, ChevronsUpDown, UserCheck, UserX, HeartCrack, HeartPulse, Zap, EyeOff, ExternalLink, AlertTriangle, Play as PlayIcon, Pause as PauseIcon, SkipForward as SkipForwardIcon, StopCircle as StopCircleIcon, Users2, Dices } from 'lucide-react'; // ImageIcon removed
import { PlusCircle, Users, Swords, Trash2, Eye, Edit3, Save, XCircle, ChevronsUpDown, UserCheck, UserX, HeartCrack, HeartPulse, Zap, EyeOff, ExternalLink, AlertTriangle, Play as PlayIcon, Pause as PauseIcon, SkipForward as SkipForwardIcon, StopCircle as StopCircleIcon, Users2, Dices } from 'lucide-react';
// --- Firebase Configuration ---
const firebaseConfig = {
@ -214,7 +214,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.30
TTRPG Initiative Tracker v0.1.32
</footer>
</div>
);
@ -354,7 +354,8 @@ function AdminView({ userId }) {
}
// --- CreateCampaignForm, CharacterManager, EncounterManager, CreateEncounterForm, ParticipantManager, EditParticipantModal, InitiativeControls, DisplayView, Modal, Icons ---
// These components are identical to the previous version (v0.1.28) and are included below for completeness.
// The rest of the components are identical to the previous version (v0.1.28) and are included below for completeness.
// Only ParticipantManager and DisplayView have minor changes for monster color.
function CreateCampaignForm({ onCreate, onCancel }) {
const [name, setName] = useState('');
@ -733,10 +734,10 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) {
<input type="number" id="monsterInitMod" value={monsterInitMod} onChange={(e) => setMonsterInitMod(e.target.value)} className="mt-1 w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-sky-500 focus:border-sky-500 sm:text-sm text-white" />
</div>
<div className="md:col-span-2">
<label className="block text-sm font-medium text-slate-300">Max HP</label>
<input type="number" value={maxHp} onChange={(e) => setMaxHp(e.target.value)} className="mt-1 w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-sky-500 focus:border-sky-500 sm:text-sm text-white" />
<label htmlFor="monsterMaxHp" className="block text-sm font-medium text-slate-300">Max HP</label>
<input type="number" id="monsterMaxHp" value={maxHp} onChange={(e) => setMaxHp(e.target.value)} className="mt-1 w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-sky-500 focus:border-sky-500 sm:text-sm text-white" />
</div>
<div className="md:col-span-2 flex items-center pt-5">
<div className="md:col-span-2 flex items-center pt-5"> {/* Aligned with input bottom */}
<input type="checkbox" id="isNpc" checked={isNpc} onChange={(e) => setIsNpc(e.target.checked)} className="h-4 w-4 text-indigo-600 border-gray-300 rounded focus:ring-indigo-500" />
<label htmlFor="isNpc" className="ml-2 block text-sm text-slate-300">Is NPC?</label>
</div>
@ -751,7 +752,7 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) {
{campaignCharacters.map(c => <option key={c.id} value={c.id}>{c.name} (HP: {c.defaultMaxHp || 'N/A'}, Mod: {c.defaultInitMod >=0 ? `+${c.defaultInitMod}` : c.defaultInitMod})</option>)}
</select>
</div>
<div className="md:col-span-2">
<div className="md:col-span-2"> {/* Spans 2 cols to align with monster layout's 2nd row if needed */}
<label className="block text-sm font-medium text-slate-300">Max HP (Encounter)</label>
<input type="number" value={maxHp} onChange={(e) => setMaxHp(e.target.value)} className="mt-1 w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-sky-500 focus:border-sky-500 sm:text-sm text-white" />
</div>
@ -775,7 +776,7 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) {
const isCurrentTurn = encounter.isStarted && p.id === encounter.currentTurnParticipantId;
const isDraggable = (!encounter.isStarted || encounter.isPaused) && tiedInitiatives.includes(Number(p.initiative));
const participantDisplayType = p.type === 'monster' ? (p.isNpc ? 'NPC' : 'Monster') : 'Character';
let bgColor = p.type === 'character' ? 'bg-sky-800' : (p.isNpc ? 'bg-slate-600' : 'bg-red-800');
let bgColor = p.type === 'character' ? 'bg-sky-800' : (p.isNpc ? 'bg-slate-600' : 'bg-[#8e351c]'); // Custom hex for monster
if (isCurrentTurn && !encounter.isPaused) bgColor = 'bg-green-600';
return (
@ -982,12 +983,7 @@ function DisplayView() {
{participantsToRender.length === 0 && isStarted && <p className="text-xl text-slate-400">No active participants.</p>}
<div className="space-y-4 max-w-3xl mx-auto">
{participantsToRender.map(p => {
let participantBgColor = 'bg-red-700'; // Default for monster
if (p.type === 'character') {
participantBgColor = 'bg-sky-700';
} else if (p.isNpc) { // Monster that is an NPC
participantBgColor = 'bg-slate-700'; // Muted gray for NPC
}
let participantBgColor = p.type === 'monster' ? (p.isNpc ? 'bg-slate-700' : 'bg-[#8e351c]') : 'bg-sky-700';
if (p.id === currentTurnParticipantId && isStarted && !isPaused) {
participantBgColor = 'bg-green-700 ring-4 ring-green-400 scale-105';
} else if (isPaused && p.id === currentTurnParticipantId) {
@ -997,7 +993,7 @@ function DisplayView() {
return (
<div key={p.id} className={`p-4 md:p-6 rounded-lg shadow-lg transition-all ${participantBgColor} ${!p.isActive ? 'opacity-40 grayscale' : ''}`}>
<div className="flex justify-between items-center mb-2">
<h3 className={`text-2xl md:text-3xl font-bold ${p.id === currentTurnParticipantId && isStarted && !isPaused ? 'text-white' : (p.type === 'character' ? 'text-sky-100' : (p.isNpc ? 'text-slate-100' : 'text-red-100'))}`}>{p.name}{p.id === currentTurnParticipantId && isStarted && !isPaused && <span className="text-yellow-300 animate-pulse ml-2">(Current)</span>}</h3>
<h3 className={`text-2xl md:text-3xl font-bold ${p.id === currentTurnParticipantId && isStarted && !isPaused ? 'text-white' : (p.type === 'character' ? 'text-sky-100' : (p.isNpc ? 'text-slate-100' : 'text-white'))}`}>{p.name}{p.id === currentTurnParticipantId && isStarted && !isPaused && <span className="text-yellow-300 animate-pulse ml-2">(Current)</span>}</h3> {/* Ensure monster text is white with new bg */}
<span className={`text-xl md:text-2xl font-semibold ${p.id === currentTurnParticipantId && isStarted && !isPaused ? 'text-green-200' : 'text-slate-200'}`}>Init: {p.initiative}</span>
</div>
<div className="flex justify-between items-center">