fitpub/src/main/resources/templates/timeline/public.html
2026-04-07 10:28:10 +02:00

138 lines
6.2 KiB
HTML

<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout}">
<head>
<title>Public Timeline</title>
</head>
<body>
<div layout:fragment="content">
<div class="row">
<div class="col-12">
<div class="mb-4">
<h2 class="mb-3">
<i class="bi bi-globe text-primary"></i>
Public Timeline
</h2>
<div class="btn-group w-100 w-md-auto" role="group" aria-label="Timeline views">
<a th:href="@{/timeline}" class="btn btn-primary active">
<i class="bi bi-globe"></i> Public
</a>
<a th:href="@{/timeline/federated}" class="btn btn-outline-primary" id="federatedLink" style="display: none;">
<i class="bi bi-people"></i> Following
</a>
<a th:href="@{/timeline/user}" class="btn btn-outline-primary" id="userTimelineLink" style="display: none;">
<i class="bi bi-person"></i> My Timeline
</a>
</div>
</div>
<p class="text-muted mb-4">
Discover public fitness activities from the FitPub community
</p>
<!-- Search Bar -->
<div class="card mb-4" id="searchCard">
<div class="card-body">
<div class="row g-3">
<div class="col-md-10">
<div class="input-group">
<span class="input-group-text">
<i class="bi bi-search"></i>
</span>
<input
type="text"
class="form-control"
id="searchInput"
placeholder="Search activities by title or description..."
autocomplete="off"
>
</div>
<small class="form-text text-muted mt-1 d-block" id="searchHint"></small>
</div>
<div class="col-md-2">
<button type="button" class="btn btn-outline-secondary w-100" id="clearSearchBtn">
<i class="bi bi-x-circle"></i> Clear
</button>
</div>
</div>
</div>
</div>
<!-- Active hashtag filter -->
<div id="hashtagFilterBadge" class="alert alert-info d-flex justify-content-between align-items-center d-none" role="alert">
<span>
<i class="bi bi-hash"></i>
Filtering by <strong id="hashtagFilterLabel">#tag</strong>
</span>
<button type="button" class="btn btn-sm btn-outline-secondary"
onclick="FitPubTimeline.clearHashtagFilter(); return false;">
<i class="bi bi-x-lg"></i> Clear
</button>
</div>
<!-- Loading Indicator -->
<div id="loadingIndicator" class="text-center py-5">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-2 text-muted">Loading timeline...</p>
</div>
<!-- Error Alert -->
<div id="errorAlert" class="alert alert-danger d-none" role="alert">
<i class="bi bi-exclamation-triangle-fill"></i>
<span id="errorMessage"></span>
</div>
<!-- Timeline Activities -->
<div id="timelineList" class="d-none">
<!-- Will be populated by JavaScript -->
</div>
<!-- Empty State -->
<div id="emptyState" class="empty-state empty-state-timeline d-none">
<div class="empty-state-icon">
<i class="bi bi-globe"></i>
</div>
<h4 class="empty-state-title">No Activities Yet</h4>
<p class="empty-state-message">Be the first to share your fitness activities with the community!</p>
<div class="empty-state-action">
<a th:href="@{/activities/upload}" class="btn btn-primary" id="uploadLinkEmpty" style="display: none;">
<i class="bi bi-cloud-upload"></i> Upload Activity
</a>
</div>
</div>
<!-- Pagination -->
<nav id="pagination" aria-label="Timeline pagination" class="mt-4 d-none">
<ul class="pagination justify-content-center" id="paginationList">
<!-- Will be populated by JavaScript -->
</ul>
</nav>
</div>
</div>
</div>
<!-- Custom Scripts -->
<th:block layout:fragment="scripts">
<script th:src="@{/js/timeline.js}"></script>
<script th:inline="javascript">
document.addEventListener('DOMContentLoaded', function() {
// Show federated/user timeline links if logged in
if (FitPubAuth.isAuthenticated()) {
document.getElementById('federatedLink').style.display = 'inline-block';
document.getElementById('userTimelineLink').style.display = 'inline-block';
document.getElementById('uploadLinkEmpty').style.display = 'inline-block';
}
// Initialize timeline
FitPubTimeline.init('public');
});
</script>
</th:block>
</body>
</html>