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