Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions app/api/companies/[slug]/assets/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'])
Expand Down
22 changes: 1 addition & 21 deletions app/dashboard/company/[slug]/analytics/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -34,7 +34,6 @@ export default function AnalyticsPage() {
to: new Date(),
})
const [selectedPreset, setSelectedPreset] = useState<PresetRange>('last30days')
const [isExporting, setIsExporting] = useState(false)

const fetchAnalytics = useCallback(async () => {
try {
Expand Down Expand Up @@ -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')

Expand Down Expand Up @@ -130,8 +127,6 @@ export default function AnalyticsPage() {
URL.revokeObjectURL(url)
} catch (err) {
console.error('Error exporting analytics:', err)
} finally {
setIsExporting(false)
}
}

Expand Down Expand Up @@ -287,21 +282,6 @@ export default function AnalyticsPage() {
/>
)}

{/* Export Button (Alternative placement) */}
{!loading && !error && analytics.length > 0 && (
<div className="flex justify-end">
<Button
variant="outline"
onClick={handleExport}
disabled={isExporting}
className="gap-2"
>
<Download className="h-4 w-4" />
{isExporting ? 'Exporting...' : 'Export to CSV'}
</Button>
</div>
)}

{/* Empty State */}
{!loading && !error && analytics.length === 0 && (
<Card className="bg-gradient-to-br from-zinc-900 to-zinc-800 border-zinc-700">
Expand Down
109 changes: 97 additions & 12 deletions app/dashboard/company/[slug]/settings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})
Expand Down Expand Up @@ -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,
})
Expand All @@ -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
Expand Down Expand Up @@ -611,12 +675,23 @@ export default function CompanySettingsPage() {
<div className="flex items-center gap-6">
<div className="flex-shrink-0">
{currentCompany.logo_url ? (
// eslint-disable-next-line @next/next/no-img-element
<img
src={currentCompany.logo_url}
alt={currentCompany.name}
className="w-32 h-32 object-cover rounded-lg border-2 border-zinc-700"
/>
<div className="relative">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={currentCompany.logo_url}
alt={currentCompany.name}
className="w-32 h-32 object-cover rounded-lg border-2 border-zinc-700"
/>
<Button
variant="destructive"
size="icon"
className="absolute -top-2 -right-2 h-6 w-6 rounded-full"
onClick={handleLogoRemove}
disabled={uploadingLogo}
>
<X className="h-3 w-3" />
</Button>
</div>
) : (
<div className="w-32 h-32 bg-zinc-800 rounded-lg border-2 border-zinc-700 flex items-center justify-center">
<Building2 className="h-12 w-12 text-zinc-600" />
Expand All @@ -634,7 +709,7 @@ export default function CompanySettingsPage() {
{uploadingLogo && (
<p className="text-sm text-muted-foreground mt-2">
<Loader2 className="inline h-4 w-4 animate-spin mr-2" />
Uploading logo...
{currentCompany.logo_url ? 'Removing' : 'Uploading'} logo...
</p>
)}
</div>
Expand All @@ -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"
/>
<Button
variant="destructive"
size="sm"
className="absolute top-2 right-2"
onClick={handleBannerRemove}
disabled={uploadingBanner}
>
<X className="h-4 w-4 mr-1" />
Remove
</Button>
</div>
) : (
<div className="w-full h-48 bg-zinc-800 rounded-lg border-2 border-zinc-700 flex items-center justify-center">
Expand All @@ -676,7 +761,7 @@ export default function CompanySettingsPage() {
{uploadingBanner && (
<p className="text-sm text-muted-foreground mt-2">
<Loader2 className="inline h-4 w-4 animate-spin mr-2" />
Uploading banner...
{currentCompany.banner_url ? 'Removing' : 'Uploading'} banner...
</p>
)}
</div>
Expand Down
Loading