feat: not working download zip file

This commit is contained in:
Mann Patel
2026-02-15 02:22:03 -07:00
parent 30392a7cd9
commit 73f99d59dc
2 changed files with 47 additions and 14 deletions

View File

@@ -41,7 +41,7 @@ class ApiClient {
} }
// ==================== Auth ==================== // ==================== Auth ====================
async register(email, password, displayName = null) { async register(email, password, displayName = null) {
return this.request('/auth/register', { return this.request('/auth/register', {
method: 'POST', method: 'POST',
@@ -58,12 +58,12 @@ class ApiClient {
method: 'POST', method: 'POST',
body: JSON.stringify({ email, password }), body: JSON.stringify({ email, password }),
}); });
// Store user ID for subsequent requests // Store user ID for subsequent requests
if (response.user?.user_id) { if (response.user?.user_id) {
this.setUserId(response.user.user_id); this.setUserId(response.user.user_id);
} }
return response; return response;
} }
@@ -81,7 +81,7 @@ class ApiClient {
async uploadPost(formData) { async uploadPost(formData) {
const url = `${this.baseUrl}/posts/upload`; const url = `${this.baseUrl}/posts/upload`;
try { try {
const response = await fetch(url, { const response = await fetch(url, {
method: 'POST', method: 'POST',
@@ -103,7 +103,7 @@ class ApiClient {
async getPosts(params = {}) { async getPosts(params = {}) {
const queryParams = new URLSearchParams(); const queryParams = new URLSearchParams();
if (params.page) queryParams.append('page', params.page); if (params.page) queryParams.append('page', params.page);
if (params.limit) queryParams.append('limit', params.limit); if (params.limit) queryParams.append('limit', params.limit);
if (params.visibility) queryParams.append('visibility', params.visibility); if (params.visibility) queryParams.append('visibility', params.visibility);
@@ -153,6 +153,12 @@ class ApiClient {
return this.request(`/posts/${postId}/metadata`); return this.request(`/posts/${postId}/metadata`);
} }
async exportPost(postId) {
const response = await fetch(`/api/posts/${postId}/download`, { method: "GET" });
if (!response.ok) throw new Error(`Failed to download post: ${response.statusText}`);
return await response.blob(); // returns proper Blob ready for download
}
// ==================== RAG Search ==================== // ==================== RAG Search ====================
async searchRAG(query, userId, page = 1, limit = 30) { async searchRAG(query, userId, page = 1, limit = 30) {
@@ -174,7 +180,7 @@ class ApiClient {
async getAuditLogs(params = {}) { async getAuditLogs(params = {}) {
const queryParams = new URLSearchParams(); const queryParams = new URLSearchParams();
if (params.post_id) queryParams.append('post_id', params.post_id); if (params.post_id) queryParams.append('post_id', params.post_id);
if (params.user_id) queryParams.append('user_id', params.user_id); if (params.user_id) queryParams.append('user_id', params.user_id);
if (params.page) queryParams.append('page', params.page); if (params.page) queryParams.append('page', params.page);

View File

@@ -24,7 +24,7 @@ export default function AudioPostCard({ post }) {
const now = new Date() const now = new Date()
const diffMs = now - date const diffMs = now - date
const diffMins = Math.floor(diffMs / 60000) const diffMins = Math.floor(diffMs / 60000)
if (diffMins < 60) return `${diffMins}m ago` if (diffMins < 60) return `${diffMins}m ago`
if (diffMins < 1440) return `${Math.floor(diffMins / 60)}h ago` if (diffMins < 1440) return `${Math.floor(diffMins / 60)}h ago`
return `${Math.floor(diffMins / 1440)}d ago` return `${Math.floor(diffMins / 1440)}d ago`
@@ -42,7 +42,7 @@ export default function AudioPostCard({ post }) {
if (post.status === 'ready' && !transcript && !loadingTranscript) { if (post.status === 'ready' && !transcript && !loadingTranscript) {
loadTranscript() loadTranscript()
} }
// Set audio source if available // Set audio source if available
if (post.audio_url && audioRef.current) { if (post.audio_url && audioRef.current) {
console.log('Setting audio src to:', post.audio_url) console.log('Setting audio src to:', post.audio_url)
@@ -75,7 +75,7 @@ export default function AudioPostCard({ post }) {
const togglePlay = () => { const togglePlay = () => {
if (!audioRef.current) return if (!audioRef.current) return
if (isPlaying) { if (isPlaying) {
audioRef.current.pause() audioRef.current.pause()
} else { } else {
@@ -107,7 +107,7 @@ export default function AudioPostCard({ post }) {
const x = e.clientX - rect.left const x = e.clientX - rect.left
const percentage = x / rect.width const percentage = x / rect.width
const newTime = percentage * duration const newTime = percentage * duration
if (audioRef.current) { if (audioRef.current) {
audioRef.current.currentTime = newTime audioRef.current.currentTime = newTime
setCurrentTime(newTime) setCurrentTime(newTime)
@@ -122,6 +122,24 @@ export default function AudioPostCard({ post }) {
} }
} }
const handleDownload = async () => {
try {
const zipBlob = await api.exportPost(post.post_id);
const url = window.URL.createObjectURL(zipBlob);
const a = document.createElement("a");
a.href = url;
a.download = `${post.title.replace(/\s+/g, "_")}.zip`;
document.body.appendChild(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
} catch (err) {
console.error("Failed to download post:", err);
}
}
const handleEnded = () => { const handleEnded = () => {
setIsPlaying(false) setIsPlaying(false)
setCurrentTime(0) setCurrentTime(0)
@@ -156,6 +174,15 @@ export default function AudioPostCard({ post }) {
</span> </span>
</div> </div>
</div> </div>
{post.status === "ready" && (
<button
onClick={handleDownload}
className="mt-2 px-3 py-1 bg-[#f4b840] text-black rounded hover:bg-[#e5a930] transition-colors"
>
Download Post
</button>
)}
<button className="text-gray-500 hover:text-gray-700"> <button className="text-gray-500 hover:text-gray-700">
<MoreVertical size={18} /> <MoreVertical size={18} />
</button> </button>
@@ -185,7 +212,7 @@ export default function AudioPostCard({ post }) {
/> />
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<button <button
onClick={togglePlay} onClick={togglePlay}
className="w-10 h-10 bg-[#f4b840] hover:bg-[#e5a930] rounded-full flex items-center justify-center text-[#1a1a1a] transition-colors" className="w-10 h-10 bg-[#f4b840] hover:bg-[#e5a930] rounded-full flex items-center justify-center text-[#1a1a1a] transition-colors"
> >
@@ -196,11 +223,11 @@ export default function AudioPostCard({ post }) {
)} )}
</button> </button>
<div className="flex-1"> <div className="flex-1">
<div <div
className="h-1.5 bg-gray-300 rounded-full overflow-hidden mb-2 cursor-pointer" className="h-1.5 bg-gray-300 rounded-full overflow-hidden mb-2 cursor-pointer"
onClick={handleSeek} onClick={handleSeek}
> >
<div <div
className="h-full bg-[#f4b840] rounded-full transition-all" className="h-full bg-[#f4b840] rounded-full transition-all"
style={{ width: `${progress}%` }} style={{ width: `${progress}%` }}
></div> ></div>
@@ -241,7 +268,7 @@ export default function AudioPostCard({ post }) {
transcriptExpanded ? <ChevronUp size={18} /> : <ChevronDown size={18} /> transcriptExpanded ? <ChevronUp size={18} /> : <ChevronDown size={18} />
)} )}
</button> </button>
{transcript && ( {transcript && (
<div className={`bg-white transition-all ${transcriptExpanded ? 'max-h-96' : 'max-h-24'} overflow-y-auto`}> <div className={`bg-white transition-all ${transcriptExpanded ? 'max-h-96' : 'max-h-24'} overflow-y-auto`}>
<div className="p-4"> <div className="p-4">