← back to Sdcc Awards
cypressaward/frontend/app/law-firms/page.tsx
192 lines
'use client'
import { useEffect, useState } from 'react'
import { supabase } from '@/lib/supabase'
interface LawFirm {
id: number
name: string
ranking: string
location: string
size: string
practice_areas: string
revenue: string
website: string
source: string
}
export default function LawFirmsPage() {
const [firms, setFirms] = useState<LawFirm[]>([])
const [loading, setLoading] = useState(true)
const [selectedFirm, setSelectedFirm] = useState<LawFirm | null>(null)
const [showModal, setShowModal] = useState(false)
useEffect(() => {
fetchFirms()
}, [])
async function fetchFirms() {
try {
const { data, error } = await supabase
.from('scraped_law_firms')
.select('*')
.order('name', { ascending: true })
.limit(100)
if (error) throw error
setFirms(data || [])
} catch (error) {
console.error('Error fetching firms:', error)
} finally {
setLoading(false)
}
}
function openModal(firm: LawFirm) {
setSelectedFirm(firm)
setShowModal(true)
}
function closeModal() {
setShowModal(false)
setSelectedFirm(null)
}
return (
<div className="min-h-screen bg-gray-50 py-8">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="bg-white shadow-xl rounded-lg">
<div className="px-6 py-4 border-b border-gray-200">
<h1 className="text-3xl font-bold text-gray-900">Law Firms</h1>
<p className="text-gray-600 mt-2">Top law firms and legal service providers</p>
</div>
{loading ? (
<div className="flex justify-center py-12">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
</div>
) : (
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Firm Name
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Location
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Revenue
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Actions
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{firms.map((firm) => (
<tr key={firm.id} className="hover:bg-gray-50">
<td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm font-medium text-gray-900">{firm.name}</div>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{firm.location}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{firm.revenue}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium">
<button
onClick={() => openModal(firm)}
className="text-blue-600 hover:text-blue-900 mr-3"
>
View Details
</button>
{firm.website && (
<a
href={firm.website}
target="_blank"
rel="noopener noreferrer"
className="text-green-600 hover:text-green-900"
>
Cy Pres Case
</a>
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
</div>
{/* Modal */}
{showModal && selectedFirm && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50">
<div className="bg-white rounded-lg max-w-2xl w-full max-h-[90vh] overflow-y-auto">
<div className="p-6">
<div className="flex justify-between items-start mb-4">
<h2 className="text-2xl font-bold text-gray-900">{selectedFirm.name}</h2>
<button
onClick={closeModal}
className="text-gray-400 hover:text-gray-600"
>
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div className="space-y-4">
<div>
<h3 className="font-semibold text-gray-700">Ranking</h3>
<p className="text-gray-900">{selectedFirm.ranking}</p>
</div>
<div>
<h3 className="font-semibold text-gray-700">Location</h3>
<p className="text-gray-900">{selectedFirm.location}</p>
</div>
<div>
<h3 className="font-semibold text-gray-700">Size</h3>
<p className="text-gray-900">{selectedFirm.size}</p>
</div>
<div>
<h3 className="font-semibold text-gray-700">Practice Areas</h3>
<p className="text-gray-900">{selectedFirm.practice_areas}</p>
</div>
<div>
<h3 className="font-semibold text-gray-700">Revenue</h3>
<p className="text-gray-900">{selectedFirm.revenue}</p>
</div>
<div>
<h3 className="font-semibold text-gray-700">Source</h3>
<p className="text-gray-900">{selectedFirm.source}</p>
</div>
</div>
<div className="mt-6 flex gap-3">
{selectedFirm.website && (
<a
href={selectedFirm.website}
target="_blank"
rel="noopener noreferrer"
className="flex-1 px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition text-center font-medium"
>
Visit Website
</a>
)}
<button
onClick={closeModal}
className="flex-1 px-4 py-2 bg-gray-200 text-gray-800 rounded-md hover:bg-gray-300 transition font-medium"
>
Close
</button>
</div>
</div>
</div>
</div>
)}
</div>
)
}