From 33ea6bec01f00aea0b51e326d4adf7cbcfdb74ab Mon Sep 17 00:00:00 2001 From: Akshay Date: Fri, 14 Nov 2025 15:46:34 +0530 Subject: [PATCH] feat(companies): Enhance company asset management and settings page - Refactor asset upload and removal API endpoint for more robust handling - Update logo and banner upload methods to use query parameters - Add new methods for removing logo and banner with improved error handling - Implement page reload after asset changes to ensure UI consistency - Remove unnecessary export button from analytics page - Improve asset management error handling and user feedback - Simplify asset upload and removal process in company settings --- app/api/companies/[slug]/assets/route.ts | 17 ++- .../company/[slug]/analytics/page.tsx | 22 +--- .../company/[slug]/settings/page.tsx | 109 ++++++++++++++++-- 3 files changed, 110 insertions(+), 38 deletions(-) diff --git a/app/api/companies/[slug]/assets/route.ts b/app/api/companies/[slug]/assets/route.ts index 84fe40c2..d45cb3b1 100644 --- a/app/api/companies/[slug]/assets/route.ts +++ b/app/api/companies/[slug]/assets/route.ts @@ -241,11 +241,18 @@ export async function DELETE( // Delete asset from storage await deleteCompanyAsset(assetPath) - // Update company to remove asset URL - const updateData = - assetType === 'logo' ? { logo_url: undefined } : { banner_url: undefined } - - const updatedCompany = await companyService.updateCompany(company.id, updateData) + // Update company to remove asset URL - use direct Supabase update to set null + const columnName = assetType === 'logo' ? 'logo_url' : 'banner_url' + const { data: updatedCompany, error: updateError } = await supabase + .from('companies') + .update({ [columnName]: null }) + .eq('id', company.id) + .select() + .single() + + if (updateError) { + throw new Error(`Failed to update company: ${updateError.message}`) + } // Invalidate cache await UnifiedCache.purgeByTags(['content', 'api']) diff --git a/app/dashboard/company/[slug]/analytics/page.tsx b/app/dashboard/company/[slug]/analytics/page.tsx index 673f57df..9b888c48 100644 --- a/app/dashboard/company/[slug]/analytics/page.tsx +++ b/app/dashboard/company/[slug]/analytics/page.tsx @@ -11,7 +11,7 @@ import { AnalyticsCharts } from '@/components/dashboard/AnalyticsCharts' import { useCompanyContext } from '@/contexts/CompanyContext' import { CompanyAnalytics } from '@/types/company' import { format, subDays, startOfMonth, endOfMonth, subMonths } from 'date-fns' -import { CalendarIcon, Download, AlertCircle, TrendingUp } from 'lucide-react' +import { CalendarIcon, AlertCircle, TrendingUp } from 'lucide-react' import { cn } from '@/lib/utils' type DateRange = { @@ -34,7 +34,6 @@ export default function AnalyticsPage() { to: new Date(), }) const [selectedPreset, setSelectedPreset] = useState('last30days') - const [isExporting, setIsExporting] = useState(false) const fetchAnalytics = useCallback(async () => { try { @@ -97,8 +96,6 @@ export default function AnalyticsPage() { const handleExport = async () => { try { - setIsExporting(true) - const startDate = format(dateRange.from, 'yyyy-MM-dd') const endDate = format(dateRange.to, 'yyyy-MM-dd') @@ -130,8 +127,6 @@ export default function AnalyticsPage() { URL.revokeObjectURL(url) } catch (err) { console.error('Error exporting analytics:', err) - } finally { - setIsExporting(false) } } @@ -287,21 +282,6 @@ export default function AnalyticsPage() { /> )} - {/* Export Button (Alternative placement) */} - {!loading && !error && analytics.length > 0 && ( -
- -
- )} - {/* Empty State */} {!loading && !error && analytics.length === 0 && ( diff --git a/app/dashboard/company/[slug]/settings/page.tsx b/app/dashboard/company/[slug]/settings/page.tsx index b8c0abd7..b8409c7b 100644 --- a/app/dashboard/company/[slug]/settings/page.tsx +++ b/app/dashboard/company/[slug]/settings/page.tsx @@ -129,9 +129,8 @@ export default function CompanySettingsPage() { try { const formData = new FormData() formData.append('file', file) - formData.append('type', 'logo') - const response = await fetch(`/api/companies/${currentCompany.slug}/assets`, { + const response = await fetch(`/api/companies/${currentCompany.slug}/assets?type=logo`, { method: 'POST', body: formData, }) @@ -165,9 +164,8 @@ export default function CompanySettingsPage() { try { const formData = new FormData() formData.append('file', file) - formData.append('type', 'banner') - const response = await fetch(`/api/companies/${currentCompany.slug}/assets`, { + const response = await fetch(`/api/companies/${currentCompany.slug}/assets?type=banner`, { method: 'POST', body: formData, }) @@ -193,6 +191,72 @@ export default function CompanySettingsPage() { } } + const handleLogoRemove = async () => { + if (!currentCompany) return + + setUploadingLogo(true) + try { + const response = await fetch(`/api/companies/${currentCompany.slug}/assets?type=logo`, { + method: 'DELETE', + cache: 'no-store', + }) + + if (!response.ok) { + throw new Error('Failed to remove logo') + } + + // Wait a bit for the database to update + await new Promise(resolve => setTimeout(resolve, 500)) + + // Force refresh the company data + await refreshCompany() + + // Force a page reload to clear any cached images + window.location.reload() + } catch (error) { + console.error('Error removing logo:', error) + toast({ + title: 'Error', + description: 'Failed to remove logo', + variant: 'destructive', + }) + setUploadingLogo(false) + } + } + + const handleBannerRemove = async () => { + if (!currentCompany) return + + setUploadingBanner(true) + try { + const response = await fetch(`/api/companies/${currentCompany.slug}/assets?type=banner`, { + method: 'DELETE', + cache: 'no-store', + }) + + if (!response.ok) { + throw new Error('Failed to remove banner') + } + + // Wait a bit for the database to update + await new Promise(resolve => setTimeout(resolve, 500)) + + // Force refresh the company data + await refreshCompany() + + // Force a page reload to clear any cached images + window.location.reload() + } catch (error) { + console.error('Error removing banner:', error) + toast({ + title: 'Error', + description: 'Failed to remove banner', + variant: 'destructive', + }) + setUploadingBanner(false) + } + } + const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!currentCompany) return @@ -611,12 +675,23 @@ export default function CompanySettingsPage() {
{currentCompany.logo_url ? ( - // eslint-disable-next-line @next/next/no-img-element - {currentCompany.name} +
+ {/* eslint-disable-next-line @next/next/no-img-element */} + {currentCompany.name} + +
) : (
@@ -634,7 +709,7 @@ export default function CompanySettingsPage() { {uploadingLogo && (

- Uploading logo... + {currentCompany.logo_url ? 'Removing' : 'Uploading'} logo...

)}
@@ -659,6 +734,16 @@ export default function CompanySettingsPage() { alt={`${currentCompany.name} banner`} className="w-full h-48 object-cover rounded-lg border-2 border-zinc-700" /> +
) : (
@@ -676,7 +761,7 @@ export default function CompanySettingsPage() { {uploadingBanner && (

- Uploading banner... + {currentCompany.banner_url ? 'Removing' : 'Uploading'} banner...

)}