admin.ejs

1<!doctype html>
2<html lang="en">
3	<head>
4		<meta charset="UTF-8" />
5		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6		<title>User Profile - <%= user.Username.replace(/_/g, ' ') %></title>
7		<!-- Icon -->
8		<link
9			rel="icon"
10			href="/avatars/<%= user.ProfilePicture %>"
11			type="image/<%= avatarType %>"
12		/>
13
14		<!-- Bootstrap CSS -->
15		<link
16			href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
17			rel="stylesheet"
18			integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
19			crossorigin="anonymous"
20		/>
21
22		<!-- Custom CSS for additional styling -->
23		<style>
24			.profile-header {
25				text-align: center;
26				margin: 20px 0;
27			}
28			.profile-picture {
29				width: 150px;
30				height: 150px;
31				object-fit: cover;
32				border-radius: 50%;
33				margin-bottom: 15px;
34			}
35			.social-icons a {
36				margin: 0 10px;
37				font-size: 24px;
38			}
39			.recent-uploads img,
40			.recent-uploads video {
41				width: 100%;
42				height: auto;
43				border-radius: 8px;
44			}
45		</style>
46
47		<meta
48			property="og:title"
49			content="User Profile - <%= user.Username.replace(/_/g, ' ') %>"
50		/>
51		<meta property="og:url" content="<%= link %>" />
52		<meta
53			property="og:site_name"
54			content="Media Uploader by x.com/stellerDev"
55		/>
56		<meta property="og:locale" content="en_US" />
57		<meta property="twitter:card" content="summary" />
58		<meta property="twitter:site" content="@x.com/stellerDev" />
59		<meta property="twitter:creator" content="@x.com/stellerDev" />
60		<meta
61			property="twitter:title"
62			content="User Profile - <%= user.Username.replace(/_/g, ' ') %>"
63		/>
64		<meta property="twitter:description" content="<%= user.Bio %>" />
65		<meta
66			property="twitter:image"
67			content="/avatars/<%= user.ProfilePicture %>"
68		/>
69	</head>
70	<body>
71		<%- include('_partials/header') %>
72		<div class="container mt-5">
73			<!-- Profile Header -->
74			<div class="profile-header">
75				<img
76					src="/avatars/<%= user.ProfilePicture %>"
77					alt="Profile Picture"
78					class="profile-picture"
79				/>
80				<h2>
81					<%= user.Username.replace(/_/g, ' ') %>
82					<% if (user.IsBot) { %>
83					<img src="/assets/images/bot.png" alt="Bot" width="48" height="48" />
84					<% } %>
85				</h2>
86				<small class="text-muted">UID: <%= user.Id %></small>
87				<p><%= user.Bio %></p>
88			</div>
89
90			<!-- Recent Uploads -->
91			<div class="recent-uploads mt-4">
92				<h4>Recent Uploads</h4>
93				<% if (recentUploads.length === 0) { %>
94				<div class="alert alert-danger" role="alert">No uploads found.</div>
95
96				<% } %>
97				<div class="row">
98					<% recentUploads.forEach(upload => { %>
99					<div class="col-md-4">
100						<div class="card mb-4 shadow-sm">
101							<% if (upload.ContentType.includes("image")) { %>
102							<img
103								src="/view/<%= upload.Id %>?raw=true"
104								class="bd-placeholder-img card-img-top"
105								width="100%"
106								height="225"
107								loading="lazy"
108							/>
109							<% } else { %>
110							<video
111								src="/view/<%= upload.Id %>?raw=true"
112								class="bd-placeholder-img card-img-top card-video"
113								width="100%"
114								height="225"
115							></video>
116							<% } %>
117							<div class="card-body">
118								<p class="card-text"><%= upload.Caption %></p>
119								<div class="d-flex justify-content-between align-items-center">
120									<div class="btn-group">
121										<a
122											href="/view/<%= upload.Id %>"
123											class="btn btn-sm btn-outline-secondary"
124											>View</a
125										>
126									</div>
127									<small class="text-muted"
128										><%= new Date(upload.UploadedAt).toLocaleDateString() %>
129										(<%= timeDifference(new Date(upload.UploadedAt)) %>)</small
130									>
131								</div>
132							</div>
133						</div>
134					</div>
135					<% }) %>
136				</div>
137			</div>
138
139			<!-- All uploads -->
140
141			<div class="all-uploads mt-4">
142				<h4>All Uploads</h4>
143				<% if (allUploads.length === 0) { %>
144				<div class="alert alert-danger" role="alert">No uploads found.</div>
145				<% } %>
146				<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3">
147					<% allUploads.forEach(upload => { %>
148					<div class="col-md-4">
149						<div class="card mb-4 shadow-sm">
150							<% if (upload.ContentType.includes("image")) { %>
151							<img
152								src="/view/<%= upload.Id %>?raw=true"
153								class="bd-placeholder-img card-img-top"
154								width="100%"
155								height="225"
156								loading="lazy"
157							/>
158							<% } else { %>
159							<video
160								src="/view/<%= upload.Id %>?raw=true"
161								class="bd-placeholder-img card-img-top card-video"
162								width="100%"
163								height="225"
164							></video>
165							<% } %>
166							<div class="card-body">
167								<p class="card-text"><%= upload.Caption %></p>
168								<div class="d-flex justify-content-between align-items-center">
169									<div class="btn-group">
170										<a
171											href="/view/<%= upload.Id %>"
172											class="btn btn-sm btn-outline-secondary"
173											>View</a
174										>
175									</div>
176									<small class="text-muted"
177										><%= new Date(upload.UploadedAt).toLocaleDateString() %>
178										(<%= timeDifference(new Date(upload.UploadedAt)) %>)</small
179									>
180								</div>
181							</div>
182						</div>
183					</div>
184					<% }) %>
185				</div>
186			</div>
187		</div>
188
189		<!-- Bootstrap JS and Popper.js -->
190		<script
191			src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"
192			integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r"
193			crossorigin="anonymous"
194			defer
195		></script>
196		<script
197			src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"
198			integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy"
199			crossorigin="anonymous"
200			defer
201		></script>
202
203		<script>
204			// Clean up the URL
205			const url = window.location.href;
206			const cleanUrl = url.split('?')[0];
207			window.history.replaceState({}, document.title, cleanUrl);
208
209			const cardVideos = document.querySelectorAll('.card-video');
210
211			cardVideos.forEach((video) => {
212				let lastCurrentTime = 0;
213				let isPlaying = false;
214
215				video.addEventListener('mouseover', () => {
216					if (isPlaying) return; // Avoid multiple hover events
217
218					lastCurrentTime = video.currentTime;
219					video.currentTime = 0; // Start from the beginning
220					video.play();
221					video.muted = true;
222					isPlaying = true;
223
224					// Stop previewing after 4 seconds
225					setTimeout(() => {
226						video.pause();
227						video.currentTime = lastCurrentTime; // Resume where it was
228						isPlaying = false;
229					}, 4000);
230				});
231
232				// Ensure the video is stopped if the mouse leaves
233				video.addEventListener('mouseout', () => {
234					if (isPlaying) {
235						video.pause();
236						video.currentTime = lastCurrentTime;
237						isPlaying = false;
238					}
239				});
240			});
241		</script>
242	</body>
243</html>
244