Updated look of site.
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 658 KiB |
@@ -10,6 +10,9 @@
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@400;600;700;900&family=EB+Garamond:ital,wght@0,400;0,500;0,600;1,400&display=swap" rel="stylesheet">
|
||||
<title>TTRPG Initiative Tracker</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
+45
-45
@@ -227,7 +227,7 @@ function Modal({ onClose, title, children }) {
|
||||
<div className="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center p-4 z-50">
|
||||
<div className="bg-slate-800 p-6 rounded-lg shadow-xl w-full max-w-md">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<h2 className="text-xl font-semibold text-sky-300">{title}</h2>
|
||||
<h2 className="text-xl font-semibold text-amber-300 font-cinzel tracking-wide">{title}</h2>
|
||||
<button onClick={onClose} className="text-slate-400 hover:text-slate-200">
|
||||
<XCircle size={24} />
|
||||
</button>
|
||||
@@ -271,7 +271,7 @@ function ConfirmationModal({ isOpen, onClose, onConfirm, title, message }) {
|
||||
function LoadingSpinner({ message = "Loading..." }) {
|
||||
return (
|
||||
<div className="min-h-screen bg-slate-900 text-white flex flex-col items-center justify-center p-4">
|
||||
<div className="animate-spin rounded-full h-16 w-16 border-t-4 border-blue-500 border-solid"></div>
|
||||
<div className="animate-spin rounded-full h-16 w-16 border-t-4 border-amber-500 border-solid"></div>
|
||||
<p className="mt-4 text-xl">{message}</p>
|
||||
</div>
|
||||
);
|
||||
@@ -314,7 +314,7 @@ function CreateCampaignForm({ onCreate, onCancel }) {
|
||||
id="campaignName"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
className="mt-1 block 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"
|
||||
className="mt-1 block w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
@@ -328,7 +328,7 @@ function CreateCampaignForm({ onCreate, onCancel }) {
|
||||
value={backgroundUrl}
|
||||
onChange={(e) => setBackgroundUrl(e.target.value)}
|
||||
placeholder="https://example.com/image.jpg"
|
||||
className="mt-1 block 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"
|
||||
className="mt-1 block w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-end space-x-3">
|
||||
@@ -371,7 +371,7 @@ function CreateEncounterForm({ onCreate, onCancel }) {
|
||||
id="encounterName"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
className="mt-1 block 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"
|
||||
className="mt-1 block w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
@@ -421,7 +421,7 @@ function EditParticipantModal({ participant, onClose, onSave }) {
|
||||
type="text"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
className="mt-1 block 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"
|
||||
className="mt-1 block w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -430,7 +430,7 @@ function EditParticipantModal({ participant, onClose, onSave }) {
|
||||
type="number"
|
||||
value={initiative}
|
||||
onChange={(e) => setInitiative(e.target.value)}
|
||||
className="mt-1 block 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"
|
||||
className="mt-1 block w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-4">
|
||||
@@ -440,7 +440,7 @@ function EditParticipantModal({ participant, onClose, onSave }) {
|
||||
type="number"
|
||||
value={currentHp}
|
||||
onChange={(e) => setCurrentHp(e.target.value)}
|
||||
className="mt-1 block 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"
|
||||
className="mt-1 block w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
@@ -449,7 +449,7 @@ function EditParticipantModal({ participant, onClose, onSave }) {
|
||||
type="number"
|
||||
value={maxHp}
|
||||
onChange={(e) => setMaxHp(e.target.value)}
|
||||
className="mt-1 block 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"
|
||||
className="mt-1 block w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -477,7 +477,7 @@ function EditParticipantModal({ participant, onClose, onSave }) {
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="px-4 py-2 text-sm font-medium text-white bg-sky-500 hover:bg-sky-600 rounded-md transition-colors"
|
||||
className="px-4 py-2 text-sm font-medium text-white bg-amber-700 hover:bg-amber-800 rounded-md transition-colors"
|
||||
>
|
||||
<Save size={18} className="mr-1 inline-block" /> Save
|
||||
</button>
|
||||
@@ -592,7 +592,7 @@ function CharacterManager({ campaignId, campaignCharacters }) {
|
||||
<>
|
||||
<div className="p-4 bg-slate-800 rounded-lg shadow">
|
||||
<div className="flex justify-between items-center mb-3">
|
||||
<h3 className="text-xl font-semibold text-sky-300 flex items-center">
|
||||
<h3 className="text-xl font-semibold text-amber-300 font-cinzel tracking-wide flex items-center">
|
||||
<Users size={24} className="mr-2" /> Campaign Characters
|
||||
</h3>
|
||||
<button
|
||||
@@ -617,7 +617,7 @@ function CharacterManager({ campaignId, campaignCharacters }) {
|
||||
value={characterName}
|
||||
onChange={(e) => setCharacterName(e.target.value)}
|
||||
placeholder="Character name"
|
||||
className="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"
|
||||
className="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full sm:w-auto">
|
||||
@@ -629,7 +629,7 @@ function CharacterManager({ campaignId, campaignCharacters }) {
|
||||
id="defaultMaxHp"
|
||||
value={defaultMaxHp}
|
||||
onChange={(e) => setDefaultMaxHp(e.target.value)}
|
||||
className="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"
|
||||
className="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full sm:w-auto">
|
||||
@@ -641,12 +641,12 @@ function CharacterManager({ campaignId, campaignCharacters }) {
|
||||
id="defaultInitMod"
|
||||
value={defaultInitMod}
|
||||
onChange={(e) => setDefaultInitMod(e.target.value)}
|
||||
className="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"
|
||||
className="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="sm:col-span-3 sm:w-auto sm:justify-self-end px-4 py-2 text-sm font-medium text-white bg-sky-500 hover:bg-sky-600 rounded-md transition-colors flex items-center justify-center"
|
||||
className="sm:col-span-3 sm:w-auto sm:justify-self-end px-4 py-2 text-sm font-medium text-white bg-amber-700 hover:bg-amber-800 rounded-md transition-colors flex items-center justify-center"
|
||||
>
|
||||
<PlusCircle size={18} className="mr-1" /> Add Character
|
||||
</button>
|
||||
@@ -1120,7 +1120,7 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) {
|
||||
<>
|
||||
<div className="p-3 bg-slate-800 rounded-md mt-4">
|
||||
<div className="flex justify-between items-center mb-3">
|
||||
<h4 className="text-lg font-medium text-sky-200">Add Participants</h4>
|
||||
<h4 className="text-lg font-medium text-amber-200 font-cinzel tracking-wide">Add Participants</h4>
|
||||
<button
|
||||
onClick={handleAddAllCampaignCharacters}
|
||||
className="px-3 py-1.5 text-xs font-medium text-white bg-indigo-600 hover:bg-indigo-700 rounded-md transition-colors flex items-center"
|
||||
@@ -1179,7 +1179,7 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) {
|
||||
value={participantName}
|
||||
onChange={(e) => setParticipantName(e.target.value)}
|
||||
placeholder="e.g., Dire Wolf"
|
||||
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"
|
||||
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-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
/>
|
||||
</div>
|
||||
<div className="md:col-span-2">
|
||||
@@ -1191,7 +1191,7 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) {
|
||||
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"
|
||||
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-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
/>
|
||||
</div>
|
||||
<div className="md:col-span-2">
|
||||
@@ -1203,7 +1203,7 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) {
|
||||
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"
|
||||
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-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
/>
|
||||
</div>
|
||||
<div className="md:col-span-2 flex items-center pt-5">
|
||||
@@ -1242,7 +1242,7 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) {
|
||||
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"
|
||||
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-amber-600 focus:border-amber-600 sm:text-sm text-white"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
@@ -1275,7 +1275,7 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) {
|
||||
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-[#8e351c]');
|
||||
let bgColor = p.type === 'character' ? 'bg-blue-950' : (p.isNpc ? 'bg-slate-600' : 'bg-[#8e351c]');
|
||||
if (isCurrentTurn && !encounter.isPaused) bgColor = 'bg-green-600';
|
||||
|
||||
const isDead = p.currentHp === 0;
|
||||
@@ -1340,7 +1340,7 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) {
|
||||
placeholder="HP"
|
||||
value={hpChangeValues[p.id] || ''}
|
||||
onChange={(e) => setHpChangeValues(prev => ({ ...prev, [p.id]: e.target.value }))}
|
||||
className="w-16 p-1 text-sm bg-slate-600 border border-slate-500 rounded-md text-white focus:ring-sky-500 focus:border-sky-500"
|
||||
className="w-16 p-1 text-sm bg-slate-600 border border-slate-500 rounded-md text-white focus:ring-amber-600 focus:border-amber-600"
|
||||
aria-label={`HP change for ${p.name}`}
|
||||
/>
|
||||
{!isDead && (
|
||||
@@ -1541,7 +1541,7 @@ function InitiativeControls({ campaignId, encounter, encounterPath }) {
|
||||
return (
|
||||
<>
|
||||
<div className="lg:sticky lg:top-4 p-4 bg-slate-800 rounded-md shadow-lg">
|
||||
<h4 className="text-lg font-medium text-sky-200 mb-4 text-center">Combat Controls</h4>
|
||||
<h4 className="text-lg font-medium text-amber-200 mb-4 text-center font-cinzel tracking-wide">Combat Controls</h4>
|
||||
<div className="flex flex-col gap-3">
|
||||
{!encounter.isStarted ? (
|
||||
<button
|
||||
@@ -1576,7 +1576,7 @@ function InitiativeControls({ campaignId, encounter, encounterPath }) {
|
||||
|
||||
{/* Round Counter */}
|
||||
<div className="mt-2 pt-3 border-t border-slate-600">
|
||||
<p className="text-center text-lg font-semibold text-sky-300">Round: {encounter.round}</p>
|
||||
<p className="text-center text-lg font-semibold text-amber-300 font-cinzel">Round: {encounter.round}</p>
|
||||
{encounter.isPaused && (
|
||||
<p className="text-center text-sm text-yellow-400 font-semibold mt-1">(Paused)</p>
|
||||
)}
|
||||
@@ -1737,7 +1737,7 @@ function EncounterManager({ campaignId, initialActiveEncounterId, campaignCharac
|
||||
<>
|
||||
<div className="mt-6 p-4 bg-slate-800 rounded-lg shadow">
|
||||
<div className="flex justify-between items-center mb-3">
|
||||
<h3 className="text-xl font-semibold text-sky-300 flex items-center">
|
||||
<h3 className="text-xl font-semibold text-amber-300 font-cinzel tracking-wide flex items-center">
|
||||
<Swords size={24} className="mr-2" /> Encounters
|
||||
</h3>
|
||||
<button
|
||||
@@ -1761,7 +1761,7 @@ function EncounterManager({ campaignId, initialActiveEncounterId, campaignCharac
|
||||
return (
|
||||
<div
|
||||
key={encounter.id}
|
||||
className={`p-3 rounded-md shadow transition-all ${selectedEncounterId === encounter.id ? 'bg-sky-600 ring-2 ring-sky-400' : 'bg-slate-700 hover:bg-slate-650'} ${isLive ? 'ring-2 ring-green-500 shadow-md shadow-green-500/30' : ''}`}
|
||||
className={`p-3 rounded-md shadow transition-all ${selectedEncounterId === encounter.id ? 'bg-amber-900 ring-2 ring-amber-500' : 'bg-slate-700 hover:bg-slate-600'} ${isLive ? 'ring-2 ring-green-500 shadow-md shadow-green-500/30' : ''}`}
|
||||
>
|
||||
<div className="flex justify-between items-center">
|
||||
<div onClick={() => setSelectedEncounterId(encounter.id)} className="cursor-pointer flex-grow">
|
||||
@@ -1778,7 +1778,7 @@ function EncounterManager({ campaignId, initialActiveEncounterId, campaignCharac
|
||||
<div className="flex items-center space-x-2">
|
||||
<button
|
||||
onClick={() => handleTogglePlayerDisplay(encounter.id)}
|
||||
className={`p-1 rounded transition-colors ${isLive ? 'bg-red-500 hover:bg-red-600 text-white' : 'text-teal-400 hover:text-teal-300 bg-slate-600 hover:bg-slate-500'}`}
|
||||
className={`p-1 rounded transition-colors ${isLive ? 'bg-red-500 hover:bg-red-600 text-white' : 'text-amber-400 hover:text-amber-300 bg-slate-600 hover:bg-slate-500'}`}
|
||||
title={isLive ? "Deactivate for Player Display" : "Activate for Player Display"}
|
||||
>
|
||||
{isLive ? <EyeOff size={18} /> : <Eye size={18} />}
|
||||
@@ -1810,8 +1810,8 @@ function EncounterManager({ campaignId, initialActiveEncounterId, campaignCharac
|
||||
)}
|
||||
|
||||
{selectedEncounter && (
|
||||
<div className="mt-6 p-4 bg-slate-750 rounded-lg shadow-inner">
|
||||
<h3 className="text-xl font-semibold text-amber-300 mb-3">
|
||||
<div className="mt-6 p-4 bg-slate-800 rounded-lg shadow-inner">
|
||||
<h3 className="text-xl font-semibold text-amber-300 mb-3 font-cinzel tracking-wide">
|
||||
Managing Encounter: {selectedEncounter.name}
|
||||
</h3>
|
||||
<div className="flex flex-col lg:flex-row gap-4">
|
||||
@@ -1991,7 +1991,7 @@ function AdminView({ userId }) {
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<h2 className="text-2xl font-semibold text-sky-300">Campaigns</h2>
|
||||
<h2 className="text-2xl font-semibold text-amber-300 font-cinzel tracking-wide">Campaigns</h2>
|
||||
<button
|
||||
onClick={() => setShowCreateModal(true)}
|
||||
className="bg-green-500 hover:bg-green-600 text-white font-bold py-2 px-4 rounded-lg flex items-center transition-colors"
|
||||
@@ -2010,7 +2010,7 @@ function AdminView({ userId }) {
|
||||
? { backgroundImage: `url(${campaign.playerDisplayBackgroundUrl})` }
|
||||
: {};
|
||||
|
||||
const cardClasses = `h-40 flex flex-col justify-between 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'}`;
|
||||
const cardClasses = `h-40 flex flex-col justify-between rounded-lg shadow-md cursor-pointer transition-all relative overflow-hidden bg-cover bg-center ${selectedCampaignId === campaign.id ? 'ring-4 ring-amber-500' : ''} ${!campaign.playerDisplayBackgroundUrl ? 'bg-slate-700 hover:bg-slate-600' : 'hover:shadow-xl'}`;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -2059,8 +2059,8 @@ function AdminView({ userId }) {
|
||||
)}
|
||||
|
||||
{selectedCampaign && (
|
||||
<div className="mt-6 p-6 bg-slate-750 rounded-lg shadow-xl">
|
||||
<h2 className="text-2xl font-semibold text-amber-300 mb-4">
|
||||
<div className="mt-6 p-6 bg-slate-800 rounded-lg shadow-xl">
|
||||
<h2 className="text-2xl font-semibold text-amber-300 mb-4 font-cinzel tracking-wide">
|
||||
Managing: {selectedCampaign.name}
|
||||
</h2>
|
||||
<CharacterManager
|
||||
@@ -2200,7 +2200,7 @@ function DisplayView() {
|
||||
return (
|
||||
<div className="min-h-screen bg-black text-slate-400 flex flex-col items-center justify-center p-4 text-center">
|
||||
<EyeOff size={64} className="mb-4 text-slate-500" />
|
||||
<h2 className="text-3xl font-semibold">Game Session Paused</h2>
|
||||
<h2 className="text-3xl font-semibold font-cinzel tracking-wide">Game Session Paused</h2>
|
||||
<p className="text-xl mt-2">The Dungeon Master has not activated an encounter for display.</p>
|
||||
</div>
|
||||
);
|
||||
@@ -2230,9 +2230,9 @@ function DisplayView() {
|
||||
style={displayStyles}
|
||||
>
|
||||
<div className={campaignBackgroundUrl ? 'bg-slate-900 bg-opacity-75 p-4 md:p-6 rounded-lg' : ''}>
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-center text-amber-400 mb-2">{name}</h2>
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-center text-amber-400 mb-2 font-cinzel tracking-wide">{name}</h2>
|
||||
|
||||
{isStarted && <p className="text-2xl text-center text-sky-300 mb-1">Round: {round}</p>}
|
||||
{isStarted && <p className="text-2xl text-center text-amber-300 mb-1 font-cinzel">Round: {round}</p>}
|
||||
|
||||
{isStarted && isPaused && (
|
||||
<p className="text-xl text-center text-yellow-400 mb-4 font-semibold">(Combat Paused)</p>
|
||||
@@ -2256,7 +2256,7 @@ function DisplayView() {
|
||||
const isDying = p.isDying || false;
|
||||
let participantBgColor = p.type === 'monster'
|
||||
? (p.isNpc ? 'bg-slate-700' : 'bg-[#8e351c]')
|
||||
: 'bg-sky-700';
|
||||
: 'bg-blue-950';
|
||||
|
||||
const isCurrentTurn = p.id === currentTurnParticipantId && isStarted && !isPaused;
|
||||
|
||||
@@ -2274,7 +2274,7 @@ function DisplayView() {
|
||||
>
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<h3
|
||||
className={`text-2xl md:text-3xl font-bold ${isCurrentTurn ? 'text-white' : (p.type === 'character' ? 'text-sky-100' : (p.isNpc ? 'text-slate-100' : 'text-white'))}`}
|
||||
className={`text-2xl md:text-3xl font-bold font-cinzel ${isCurrentTurn ? 'text-white' : (p.type === 'character' ? 'text-amber-100' : (p.isNpc ? 'text-slate-100' : 'text-white'))}`}
|
||||
>
|
||||
{isDead && <span className="mr-2">☠️</span>}
|
||||
{p.name}
|
||||
@@ -2333,7 +2333,7 @@ function App() {
|
||||
|
||||
useEffect(() => {
|
||||
const queryParams = new URLSearchParams(window.location.search);
|
||||
if (queryParams.get('playerView') === 'true') {
|
||||
if (queryParams.get('playerView') === 'true' || window.location.pathname === '/display') {
|
||||
setIsPlayerViewOnlyMode(true);
|
||||
}
|
||||
|
||||
@@ -2387,13 +2387,13 @@ function App() {
|
||||
}
|
||||
|
||||
const openPlayerWindow = () => {
|
||||
const playerViewUrl = window.location.origin + window.location.pathname + '?playerView=true';
|
||||
const playerViewUrl = window.location.origin + '/display';
|
||||
window.open(playerViewUrl, '_blank', 'noopener,noreferrer,width=1024,height=768');
|
||||
};
|
||||
|
||||
if (isPlayerViewOnlyMode) {
|
||||
return (
|
||||
<div className="min-h-screen bg-slate-800 text-slate-100 font-sans">
|
||||
<div className="min-h-screen bg-slate-900 text-slate-100 font-garamond">
|
||||
{isAuthReady && <DisplayView />}
|
||||
{!isAuthReady && !error && <p>Authenticating for Player Display...</p>}
|
||||
</div>
|
||||
@@ -2401,13 +2401,13 @@ function App() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-slate-800 text-slate-100 font-sans">
|
||||
<header className="bg-slate-900 p-4 shadow-lg">
|
||||
<div className="min-h-screen bg-slate-900 text-slate-100 font-garamond">
|
||||
<header className="bg-slate-900 p-4 shadow-lg border-b border-amber-900">
|
||||
<div className="container mx-auto flex justify-between items-center">
|
||||
<h1 className="text-3xl font-bold text-sky-400">TTRPG Initiative Tracker</h1>
|
||||
<h1 className="text-3xl font-bold text-amber-400 font-cinzel tracking-wide">TTRPG Initiative Tracker</h1>
|
||||
<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"
|
||||
className="px-4 py-2 rounded-md text-sm font-medium transition-colors bg-amber-700 hover:bg-amber-800 text-white flex items-center"
|
||||
>
|
||||
<ExternalLink size={16} className="mr-2" /> Open Player Window
|
||||
</button>
|
||||
|
||||
+1
-6
@@ -7,14 +7,9 @@
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
font-family: 'EB Garamond', Georgia, 'Times New Roman', serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
/* background-color: #1A202C; /* Tailwind Slate 900 */
|
||||
/* color: #E2E8F0; /* Tailwind Slate 200 */
|
||||
/* These will likely be overridden by the App component's Tailwind classes */
|
||||
}
|
||||
|
||||
code {
|
||||
|
||||
+6
-1
@@ -6,7 +6,12 @@ module.exports = {
|
||||
"./public/index.html"
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
extend: {
|
||||
fontFamily: {
|
||||
cinzel: ['Cinzel', 'serif'],
|
||||
garamond: ['"EB Garamond"', 'Georgia', 'serif'],
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
Reference in New Issue
Block a user