dev #1
1 changed files with 95 additions and 93 deletions
|
|
@ -752,8 +752,10 @@ export default function Page() {
|
|||
|
||||
function formatTrophies(value: number) {
|
||||
const sign = value > 0 ? '' : '+';
|
||||
|
||||
return `${sign}${value} trophies`;
|
||||
let gained = false;
|
||||
if(sign === '+') gained = true;
|
||||
let suffix = gained ? 'gained' : 'lost';
|
||||
return `${sign}${value} trophies ${suffix}`;
|
||||
}
|
||||
|
||||
function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
||||
|
|
@ -1399,50 +1401,50 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
|||
<details>
|
||||
<summary><h3>Manage Attacks</h3></summary>
|
||||
<ul className="list compact">
|
||||
{defenses.length ? (
|
||||
defenses.slice(0, 10).map((defense) => {
|
||||
const categoryName =
|
||||
categoryNameMap.get(defense.armyCategoryId) || defense.categoryName || '(No category)';
|
||||
return (
|
||||
<li key={defense.id} className="list-item">
|
||||
<div className="defense-header">
|
||||
<div>
|
||||
<strong>{defense.baseTitle}</strong>{' '}
|
||||
<span className="badge">{categoryName}</span>
|
||||
</div>
|
||||
<div className="defense-meta">
|
||||
<button
|
||||
type="button"
|
||||
className="ghost small"
|
||||
onClick={() => startEditingDefense(defense.id)}
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="ghost small"
|
||||
onClick={() => handleDeleteDefense(defense.id)}
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
{defenses.length ? (
|
||||
defenses.slice(0, 10).map((defense) => {
|
||||
const categoryName =
|
||||
categoryNameMap.get(defense.armyCategoryId) || defense.categoryName || '(No category)';
|
||||
return (
|
||||
<li key={defense.id} className="list-item">
|
||||
<div className="defense-header">
|
||||
<div>
|
||||
<strong>{defense.baseTitle}</strong>{' '}
|
||||
<span className="badge">{categoryName}</span>
|
||||
</div>
|
||||
<div className="defense-meta">
|
||||
<span>{defense.stars}★</span>
|
||||
<span>{defense.percent}%</span>
|
||||
<span>{formatTrophies(defense.trophies)}</span>
|
||||
<span>{new Date(defense.createdAt).toLocaleString()}</span>
|
||||
<button
|
||||
type="button"
|
||||
className="ghost small"
|
||||
onClick={() => startEditingDefense(defense.id)}
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="ghost small"
|
||||
onClick={() => handleDeleteDefense(defense.id)}
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<li>No attacks logged yet.</li>
|
||||
)}
|
||||
</ul>
|
||||
{defenses.length > 10 ? (
|
||||
<p className="muted">Showing the latest 10 entries.</p>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="defense-meta">
|
||||
<span>{defense.stars}★</span>
|
||||
<span>{defense.percent}%</span>
|
||||
<span>{formatTrophies(defense.trophies)}</span>
|
||||
<span>{new Date(defense.createdAt).toLocaleString()}</span>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<li>No attacks logged yet.</li>
|
||||
)}
|
||||
</ul>
|
||||
{defenses.length > 10 ? (
|
||||
<p className="muted">Showing the latest 10 entries.</p>
|
||||
) : null}
|
||||
</details>
|
||||
</div>
|
||||
{defenseBeingEdited && (
|
||||
|
|
@ -1555,7 +1557,7 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
|||
<input type="number" name="trophiesAtStart" min={0} step={1} required className="styled-number" />
|
||||
</label>
|
||||
<label>
|
||||
Trophies Lost
|
||||
Trophies Gained/Lost
|
||||
<input type="number" name="trophiesLost" step={1} required className="styled-number" />
|
||||
</label>
|
||||
<label>
|
||||
|
|
@ -1600,7 +1602,7 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
|||
</div>
|
||||
<div className="defense-meta">
|
||||
<span>{reset.trophiesAtStart} trophies</span>
|
||||
<span>{formatTrophies(reset.trophiesLost)} lost</span>
|
||||
<span>{formatTrophies(reset.trophiesLost)}</span>
|
||||
<span>{reset.numberOfDefenses} defenses</span>
|
||||
</div>
|
||||
</li>
|
||||
|
|
@ -1638,7 +1640,7 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
|||
<input type="number" name="trophiesAtStart" min={0} step={1} required className="styled-number" defaultValue={trophyResetBeingEdited.trophiesAtStart} />
|
||||
</label>
|
||||
<label>
|
||||
Trophies Lost
|
||||
Trophies Gained/Lost
|
||||
<input type="number" name="trophiesLost" step={1} required className="styled-number" defaultValue={trophyResetBeingEdited.trophiesLost} />
|
||||
</label>
|
||||
<label>
|
||||
|
|
@ -1714,28 +1716,28 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
|||
<details open>
|
||||
<summary><h3>Army Categories vs This Base</h3></summary>
|
||||
<ul id="base-detail-categories" className="list">
|
||||
{baseDetail && baseDetail.categories.length ? (
|
||||
baseDetail.categories.map((category) => (
|
||||
<li
|
||||
key={category.categoryId}
|
||||
className="list-item clickable"
|
||||
onClick={() => openCategoryDetail(category.categoryId)}
|
||||
>
|
||||
<div className="defense-header">
|
||||
<strong>{category.name}</strong>
|
||||
<span className="badge">{category.count} attacks</span>
|
||||
</div>
|
||||
<div className="defense-meta">
|
||||
<span>{category.averageStars}★ avg</span>
|
||||
<span>{category.averagePercent}% avg</span>
|
||||
<span>{formatTrophies(category.averageTrophies)} avg</span>
|
||||
</div>
|
||||
</li>
|
||||
))
|
||||
) : (
|
||||
<li>No army categories have attacked this base yet.</li>
|
||||
)}
|
||||
</ul>
|
||||
{baseDetail && baseDetail.categories.length ? (
|
||||
baseDetail.categories.map((category) => (
|
||||
<li
|
||||
key={category.categoryId}
|
||||
className="list-item clickable"
|
||||
onClick={() => openCategoryDetail(category.categoryId)}
|
||||
>
|
||||
<div className="defense-header">
|
||||
<strong>{category.name}</strong>
|
||||
<span className="badge">{category.count} attacks</span>
|
||||
</div>
|
||||
<div className="defense-meta">
|
||||
<span>{category.averageStars}★ avg</span>
|
||||
<span>{category.averagePercent}% avg</span>
|
||||
<span>{formatTrophies(category.averageTrophies)} avg</span>
|
||||
</div>
|
||||
</li>
|
||||
))
|
||||
) : (
|
||||
<li>No army categories have attacked this base yet.</li>
|
||||
)}
|
||||
</ul>
|
||||
</details>
|
||||
</div>
|
||||
<div className="card">
|
||||
|
|
@ -1765,8 +1767,8 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
|||
</div>
|
||||
</div>
|
||||
<div className="defense-meta">
|
||||
<span>{reset.trophiesAtStart} trophies at start</span>
|
||||
<span>{formatTrophies(reset.trophiesLost)} lost</span>
|
||||
<span>{reset.trophiesAtStart} trophies</span>
|
||||
<span>{formatTrophies(reset.trophiesLost)}</span>
|
||||
<span>{reset.numberOfDefenses} defenses</span>
|
||||
</div>
|
||||
</li>
|
||||
|
|
@ -1781,30 +1783,30 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
|||
<details open>
|
||||
<summary><h3>Defenses</h3></summary>
|
||||
<ul id="base-detail-defenses" className="list">
|
||||
{defenses.filter((defense) => defense.baseId === selectedBaseId).length ? (
|
||||
defenses
|
||||
.filter((defense) => defense.baseId === selectedBaseId)
|
||||
.map((defense) => {
|
||||
const date = new Date(defense.createdAt);
|
||||
const categoryName = categoryNameMap.get(defense.armyCategoryId) || '(No category)';
|
||||
return (
|
||||
<li key={defense.id} className="list-item">
|
||||
<div className="defense-header">
|
||||
<strong>{categoryName}</strong>
|
||||
<div>
|
||||
<strong>{defense.stars}★</strong> • {defense.percent}% • {formatTrophies(defense.trophies)}
|
||||
</div>
|
||||
{defenses.filter((defense) => defense.baseId === selectedBaseId).length ? (
|
||||
defenses
|
||||
.filter((defense) => defense.baseId === selectedBaseId)
|
||||
.map((defense) => {
|
||||
const date = new Date(defense.createdAt);
|
||||
const categoryName = categoryNameMap.get(defense.armyCategoryId) || '(No category)';
|
||||
return (
|
||||
<li key={defense.id} className="list-item">
|
||||
<div className="defense-header">
|
||||
<strong>{categoryName}</strong>
|
||||
<div>
|
||||
<strong>{defense.stars}★</strong> • {defense.percent}% • {formatTrophies(defense.trophies)}
|
||||
</div>
|
||||
<div className="defense-meta">
|
||||
<span>{date.toLocaleString()}</span>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<li>No defenses recorded for this base yet.</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="defense-meta">
|
||||
<span>{date.toLocaleString()}</span>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<li>No defenses recorded for this base yet.</li>
|
||||
)}
|
||||
</ul>
|
||||
</details>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue