Files
Mann Patel b21e76eed0 Update: Few issues to resolve see readme
this push will conclude the majority of pulls. this repos will now, not be actively be managed or any further code pushes will not be frequent.
2025-09-11 16:54:30 -06:00

345 lines
13 KiB
HTML

{{ define "content" }}
<div class="min-h-screen bg-gray-100">
<div class="max-w-2xl mx-auto">
<!-- Create Post Form -->
<div class="bg-white border-b border-gray-200 p-6">
<form
action="/posts"
method="POST"
enctype="multipart/form-data"
class="space-y-4"
>
<div class="flex items-start space-x-4">
<div class="flex-shrink-0">
<div
class="w-10 h-10 bg-blue-500 flex items-center justify-center text-white font-semibold"
>
You
</div>
</div>
<div class="flex-1">
<textarea
id="content"
name="content"
placeholder="What's on your mind?"
class="w-full px-0 py-2 text-gray-900 placeholder-gray-500 border-0 resize-none focus:outline-none focus:ring-0"
rows="3"
required
></textarea>
</div>
</div>
<div
class="flex items-center justify-between pt-4 border-t border-gray-100"
>
<div class="flex items-center">
<label
for="image"
class="cursor-pointer flex items-center space-x-2 text-blue-500 hover:text-blue-600"
>
<svg
class="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
></path>
</svg>
<span class="text-sm font-medium">Photo</span>
</label>
<input
id="image"
type="file"
name="image"
accept="image/*"
class="hidden"
/>
</div>
<button
type="submit"
class="bg-blue-500 hover:bg-blue-600 text-white px-6 py-2 text-sm font-semibold transition-colors disabled:opacity-50"
>
Post
</button>
</div>
<!-- Image preview -->
<div id="imagePreview" class="hidden">
<img
id="previewImg"
class="w-full h-64 object-cover border"
alt="Preview"
/>
<button
type="button"
id="removeImage"
class="mt-2 text-red-500 text-sm hover:text-red-600"
>
Remove image
</button>
</div>
</form>
</div>
<!-- Posts Feed -->
<div class="space-y-0">
{{range .Posts}}
<article class="bg-white border-b border-gray-200">
<!-- Post Header -->
<div class="flex items-center px-6 py-4">
<div class="flex-shrink-0">
<div
class="w-10 h-10 bg-blue-500 flex items-center justify-center text-white font-semibold"
>
{{slice .AuthorName 0 1}}
</div>
</div>
<div class="ml-4">
<p class="text-sm font-semibold text-gray-900">
{{.AuthorName}}
</p>
<p class="text-xs text-gray-500">
{{.CreatedAt.Format "Jan 2, 2006"}}
</p>
</div>
</div>
<!-- Post Image -->
{{if .ImageURL}}
<div class="w-full">
<img
src="{{.ImageURL}}"
alt="Post image"
class="w-full max-h-96 object-cover"
onerror="this.parentElement.style.display='none'"
/>
</div>
{{end}}
<!-- Post Content -->
{{if .Content}}
<div class="px-6 pt-2 pb-4">
<p class="text-gray-900 leading-relaxed">
<span class="font-semibold">{{.AuthorName}}</span>
{{.Content}}
</p>
</div>
{{end}}
</article>
{{else}}
<div class="bg-white p-12 text-center">
<div class="max-w-sm mx-auto">
<svg
class="w-16 h-16 mx-auto text-gray-300 mb-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
></path>
</svg>
<h3 class="text-lg font-medium text-gray-900 mb-2">
No posts yet
</h3>
<p class="text-gray-500">
Be the first to share something with the community!
</p>
</div>
</div>
{{end}}
</div>
</div>
</div>
<style>
/* Custom styles for Instagram-like feel */
.reaction-btn.active {
color: #3b82f6 !important;
}
.reaction-btn.active svg {
fill: currentColor;
}
.reaction-btn.dislike-active {
color: #ef4444 !important;
}
/* Smooth transitions */
.reaction-btn {
transition: all 0.2s ease-in-out;
}
.reaction-btn:hover {
transform: scale(1.05);
}
/* Focus styles */
button:focus {
outline: 2px solid #3b82f6;
outline-offset: 2px;
}
input:focus,
textarea:focus {
outline: 2px solid #3b82f6;
outline-offset: 2px;
}
</style>
<script>
document.addEventListener("DOMContentLoaded", function () {
const fileInput = document.getElementById("image");
const imagePreview = document.getElementById("imagePreview");
const previewImg = document.getElementById("previewImg");
const removeImageBtn = document.getElementById("removeImage");
const form = document.querySelector("form");
// Image upload preview
if (fileInput) {
fileInput.addEventListener("change", function (e) {
const file = e.target.files[0];
if (file) {
console.log(
"Selected file:",
file.name,
"Size:",
file.size,
"Type:",
file.type,
);
// Validate file size (10MB max)
if (file.size > 10 * 1024 * 1024) {
alert("File is too large. Maximum size is 10MB.");
this.value = "";
return;
}
// Validate file type
const allowedTypes = [
"image/jpeg",
"image/jpg",
"image/png",
"image/gif",
"image/webp",
];
if (!allowedTypes.includes(file.type)) {
alert(
"Invalid file type. Please select a valid image file.",
);
this.value = "";
return;
}
// Show preview
const reader = new FileReader();
reader.onload = function (e) {
previewImg.src = e.target.result;
imagePreview.classList.remove("hidden");
};
reader.readAsDataURL(file);
}
});
}
// Remove image preview
if (removeImageBtn) {
removeImageBtn.addEventListener("click", function () {
fileInput.value = "";
imagePreview.classList.add("hidden");
previewImg.src = "";
});
}
// Reaction buttons
const reactionBtns = document.querySelectorAll(".reaction-btn");
reactionBtns.forEach(function (btn) {
btn.addEventListener("click", function (e) {
e.preventDefault();
const postId = this.dataset.postId;
const reaction = this.dataset.reaction;
// Toggle active state
if (reaction === "like") {
this.classList.toggle("active");
// Remove dislike active state from sibling
const dislikeBtn = this.parentElement.querySelector(
'[data-reaction="dislike"]',
);
dislikeBtn.classList.remove("dislike-active");
} else {
this.classList.toggle("dislike-active");
// Remove like active state from sibling
const likeBtn = this.parentElement.querySelector(
'[data-reaction="like"]',
);
likeBtn.classList.remove("active");
}
// Update count (mock implementation)
const countSpan = this.querySelector("span");
const currentCount = parseInt(countSpan.textContent);
const isActive =
this.classList.contains("active") ||
this.classList.contains("dislike-active");
countSpan.textContent = isActive
? currentCount + 1
: Math.max(0, currentCount - 1);
console.log(`${reaction} clicked for post ${postId}`);
// Here you would typically send an AJAX request to update the backend
// fetch(`/posts/${postId}/react`, {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify({ reaction: reaction })
// });
});
});
// Form submission
if (form) {
form.addEventListener("submit", function (e) {
const content = document.getElementById("content").value.trim();
const hasImage = fileInput.files.length > 0;
if (!content && !hasImage) {
e.preventDefault();
alert("Please add some content or an image to your post.");
return;
}
console.log("Form being submitted...");
});
}
// Auto-resize textarea
const textarea = document.getElementById("content");
if (textarea) {
textarea.addEventListener("input", function () {
this.style.height = "auto";
this.style.height = this.scrollHeight + "px";
});
}
// Smooth scroll to top when clicking header
const header = document.querySelector("h1");
if (header) {
header.addEventListener("click", function () {
window.scrollTo({ top: 0, behavior: "smooth" });
});
}
});
</script>
{{ end }}