dev #1
1 changed files with 149 additions and 143 deletions
|
|
@ -751,7 +751,8 @@ export default function Page() {
|
||||||
}, [categories]);
|
}, [categories]);
|
||||||
|
|
||||||
function formatTrophies(value: number) {
|
function formatTrophies(value: number) {
|
||||||
const sign = value > 0 ? '+' : '';
|
const sign = value > 0 ? '' : '+';
|
||||||
|
|
||||||
return `${sign}${value} trophies`;
|
return `${sign}${value} trophies`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1117,30 +1118,31 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
||||||
<details>
|
<details>
|
||||||
<summary><h3>Existing Categories</h3></summary>
|
<summary><h3>Existing Categories</h3></summary>
|
||||||
<ul className="list compact">
|
<ul className="list compact">
|
||||||
{categories.length ? (
|
{categories.length ? (
|
||||||
categories.map((category) => (
|
categories.map((category) => (
|
||||||
<li key={category.id} className="list-item">
|
<li key={category.id} className="list-item">
|
||||||
<div className="defense-header">
|
<div className="defense-header">
|
||||||
<span>{category.name}</span>
|
<span>{category.name}</span>
|
||||||
<div className="defense-meta">
|
<div className="defense-meta">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="ghost small"
|
className="ghost small"
|
||||||
onClick={() => handleDeleteCategory(category.id)}
|
onClick={() => handleDeleteCategory(category.id)}
|
||||||
>
|
>
|
||||||
Delete
|
Delete
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="defense-meta">
|
||||||
<div className="defense-meta">
|
<span>{new Date(category.createdAt).toLocaleDateString()}</span>
|
||||||
<span>{new Date(category.createdAt).toLocaleDateString()}</span>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
</li>
|
))
|
||||||
))
|
) : (
|
||||||
) : (
|
<li>No categories yet.</li>
|
||||||
<li>No categories yet.</li>
|
)}
|
||||||
)}
|
</ul>
|
||||||
</ul>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="card">
|
<div className="card">
|
||||||
|
|
@ -1202,40 +1204,41 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
||||||
<details>
|
<details>
|
||||||
<summary><h3>Manage Bases</h3></summary>
|
<summary><h3>Manage Bases</h3></summary>
|
||||||
<ul className="list compact">
|
<ul className="list compact">
|
||||||
{bases.length ? (
|
{bases.length ? (
|
||||||
bases.map((base) => (
|
bases.map((base) => (
|
||||||
<li key={base.id} className="list-item">
|
<li key={base.id} className="list-item">
|
||||||
<div className="defense-header">
|
<div className="defense-header">
|
||||||
<div>
|
<div>
|
||||||
<strong>{base.title}</strong>{' '}
|
<strong>{base.title}</strong>{' '}
|
||||||
{base.isPrivate ? <span className="badge muted">Private</span> : null}
|
{base.isPrivate ? <span className="badge muted">Private</span> : null}
|
||||||
|
</div>
|
||||||
|
<div className="defense-meta">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="ghost small"
|
||||||
|
onClick={() => startEditingBase(base.id)}
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="ghost small"
|
||||||
|
onClick={() => handleDeleteBase(base.id)}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="defense-meta">
|
<div className="defense-meta">
|
||||||
<button
|
<span>{new Date(base.createdAt).toLocaleDateString()}</span>
|
||||||
type="button"
|
|
||||||
className="ghost small"
|
|
||||||
onClick={() => startEditingBase(base.id)}
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="ghost small"
|
|
||||||
onClick={() => handleDeleteBase(base.id)}
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
<div className="defense-meta">
|
))
|
||||||
<span>{new Date(base.createdAt).toLocaleDateString()}</span>
|
) : (
|
||||||
</div>
|
<li>No bases yet.</li>
|
||||||
</li>
|
)}
|
||||||
))
|
</ul>
|
||||||
) : (
|
</details>
|
||||||
<li>No bases yet.</li>
|
|
||||||
)}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
{baseBeingEdited && (
|
{baseBeingEdited && (
|
||||||
<div className="subsection">
|
<div className="subsection">
|
||||||
|
|
@ -1396,50 +1399,51 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
||||||
<details>
|
<details>
|
||||||
<summary><h3>Manage Attacks</h3></summary>
|
<summary><h3>Manage Attacks</h3></summary>
|
||||||
<ul className="list compact">
|
<ul className="list compact">
|
||||||
{defenses.length ? (
|
{defenses.length ? (
|
||||||
defenses.slice(0, 10).map((defense) => {
|
defenses.slice(0, 10).map((defense) => {
|
||||||
const categoryName =
|
const categoryName =
|
||||||
categoryNameMap.get(defense.armyCategoryId) || defense.categoryName || '(No category)';
|
categoryNameMap.get(defense.armyCategoryId) || defense.categoryName || '(No category)';
|
||||||
return (
|
return (
|
||||||
<li key={defense.id} className="list-item">
|
<li key={defense.id} className="list-item">
|
||||||
<div className="defense-header">
|
<div className="defense-header">
|
||||||
<div>
|
<div>
|
||||||
<strong>{defense.baseTitle}</strong>{' '}
|
<strong>{defense.baseTitle}</strong>{' '}
|
||||||
<span className="badge">{categoryName}</span>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
<div className="defense-meta">
|
<div className="defense-meta">
|
||||||
<button
|
<span>{defense.stars}★</span>
|
||||||
type="button"
|
<span>{defense.percent}%</span>
|
||||||
className="ghost small"
|
<span>{formatTrophies(defense.trophies)}</span>
|
||||||
onClick={() => startEditingDefense(defense.id)}
|
<span>{new Date(defense.createdAt).toLocaleString()}</span>
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="ghost small"
|
|
||||||
onClick={() => handleDeleteDefense(defense.id)}
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
<div className="defense-meta">
|
);
|
||||||
<span>{defense.stars}★</span>
|
})
|
||||||
<span>{defense.percent}%</span>
|
) : (
|
||||||
<span>{formatTrophies(defense.trophies)}</span>
|
<li>No attacks logged yet.</li>
|
||||||
<span>{new Date(defense.createdAt).toLocaleString()}</span>
|
)}
|
||||||
</div>
|
</ul>
|
||||||
</li>
|
{defenses.length > 10 ? (
|
||||||
);
|
<p className="muted">Showing the latest 10 entries.</p>
|
||||||
})
|
) : null}
|
||||||
) : (
|
</details>
|
||||||
<li>No attacks logged yet.</li>
|
|
||||||
)}
|
|
||||||
</ul>
|
|
||||||
{defenses.length > 10 ? (
|
|
||||||
<p className="muted">Showing the latest 10 entries.</p>
|
|
||||||
) : null}
|
|
||||||
</div>
|
</div>
|
||||||
{defenseBeingEdited && (
|
{defenseBeingEdited && (
|
||||||
<div className="subsection">
|
<div className="subsection">
|
||||||
|
|
@ -1710,28 +1714,29 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
||||||
<details open>
|
<details open>
|
||||||
<summary><h3>Army Categories vs This Base</h3></summary>
|
<summary><h3>Army Categories vs This Base</h3></summary>
|
||||||
<ul id="base-detail-categories" className="list">
|
<ul id="base-detail-categories" className="list">
|
||||||
{baseDetail && baseDetail.categories.length ? (
|
{baseDetail && baseDetail.categories.length ? (
|
||||||
baseDetail.categories.map((category) => (
|
baseDetail.categories.map((category) => (
|
||||||
<li
|
<li
|
||||||
key={category.categoryId}
|
key={category.categoryId}
|
||||||
className="list-item clickable"
|
className="list-item clickable"
|
||||||
onClick={() => openCategoryDetail(category.categoryId)}
|
onClick={() => openCategoryDetail(category.categoryId)}
|
||||||
>
|
>
|
||||||
<div className="defense-header">
|
<div className="defense-header">
|
||||||
<strong>{category.name}</strong>
|
<strong>{category.name}</strong>
|
||||||
<span className="badge">{category.count} attacks</span>
|
<span className="badge">{category.count} attacks</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="defense-meta">
|
<div className="defense-meta">
|
||||||
<span>{category.averageStars}★ avg</span>
|
<span>{category.averageStars}★ avg</span>
|
||||||
<span>{category.averagePercent}% avg</span>
|
<span>{category.averagePercent}% avg</span>
|
||||||
<span>{formatTrophies(category.averageTrophies)} avg</span>
|
<span>{formatTrophies(category.averageTrophies)} avg</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<li>No army categories have attacked this base yet.</li>
|
<li>No army categories have attacked this base yet.</li>
|
||||||
)}
|
)}
|
||||||
</ul>
|
</ul>
|
||||||
|
</details>
|
||||||
</div>
|
</div>
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<details open>
|
<details open>
|
||||||
|
|
@ -1776,30 +1781,31 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
||||||
<details open>
|
<details open>
|
||||||
<summary><h3>Defenses</h3></summary>
|
<summary><h3>Defenses</h3></summary>
|
||||||
<ul id="base-detail-defenses" className="list">
|
<ul id="base-detail-defenses" className="list">
|
||||||
{defenses.filter((defense) => defense.baseId === selectedBaseId).length ? (
|
{defenses.filter((defense) => defense.baseId === selectedBaseId).length ? (
|
||||||
defenses
|
defenses
|
||||||
.filter((defense) => defense.baseId === selectedBaseId)
|
.filter((defense) => defense.baseId === selectedBaseId)
|
||||||
.map((defense) => {
|
.map((defense) => {
|
||||||
const date = new Date(defense.createdAt);
|
const date = new Date(defense.createdAt);
|
||||||
const categoryName = categoryNameMap.get(defense.armyCategoryId) || '(No category)';
|
const categoryName = categoryNameMap.get(defense.armyCategoryId) || '(No category)';
|
||||||
return (
|
return (
|
||||||
<li key={defense.id} className="list-item">
|
<li key={defense.id} className="list-item">
|
||||||
<div className="defense-header">
|
<div className="defense-header">
|
||||||
<strong>{categoryName}</strong>
|
<strong>{categoryName}</strong>
|
||||||
<div>
|
<div>
|
||||||
<strong>{defense.stars}★</strong> • {defense.percent}% • {formatTrophies(defense.trophies)}
|
<strong>{defense.stars}★</strong> • {defense.percent}% • {formatTrophies(defense.trophies)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="defense-meta">
|
||||||
<div className="defense-meta">
|
<span>{date.toLocaleString()}</span>
|
||||||
<span>{date.toLocaleString()}</span>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
</li>
|
);
|
||||||
);
|
})
|
||||||
})
|
) : (
|
||||||
) : (
|
<li>No defenses recorded for this base yet.</li>
|
||||||
<li>No defenses recorded for this base yet.</li>
|
)}
|
||||||
)}
|
</ul>
|
||||||
</ul>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
@ -1888,7 +1894,7 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<details>
|
<details open>
|
||||||
<summary><h3>Recent Resets</h3></summary>
|
<summary><h3>Recent Resets</h3></summary>
|
||||||
<ul className="list compact">
|
<ul className="list compact">
|
||||||
{profileSelectedBase.trophyResets.length ? (
|
{profileSelectedBase.trophyResets.length ? (
|
||||||
|
|
@ -1897,7 +1903,7 @@ function summarizeProfileDefenses(defenses: ProfileDefense[]): Summary {
|
||||||
<div className="defense-header">
|
<div className="defense-header">
|
||||||
<span>{new Date(reset.date).toLocaleDateString()}</span>
|
<span>{new Date(reset.date).toLocaleDateString()}</span>
|
||||||
<div className="defense-meta">
|
<div className="defense-meta">
|
||||||
<span>{reset.trophiesAtStart} trophies </span>
|
<span>{reset.trophiesAtStart} trophies at start</span>
|
||||||
<span>{formatTrophies(reset.trophiesLost)} lost</span>
|
<span>{formatTrophies(reset.trophiesLost)} lost</span>
|
||||||
<span>{reset.numberOfDefenses} defenses</span>
|
<span>{reset.numberOfDefenses} defenses</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue