mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 18:31:12 -05:00
Refactor code to address issues
This commit is contained in:
@@ -9,6 +9,7 @@ import { Skeleton } from '@/components/ui/skeleton';
|
|||||||
import { Header } from '@/components/layout/Header';
|
import { Header } from '@/components/layout/Header';
|
||||||
import { Footer } from '@/components/layout/Footer';
|
import { Footer } from '@/components/layout/Footer';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
const POSTS_PER_PAGE = 9;
|
const POSTS_PER_PAGE = 9;
|
||||||
|
|
||||||
@@ -39,6 +40,17 @@ export default function BlogIndex() {
|
|||||||
|
|
||||||
const totalPages = Math.ceil((data?.totalCount || 0) / POSTS_PER_PAGE);
|
const totalPages = Math.ceil((data?.totalCount || 0) / POSTS_PER_PAGE);
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: 'Blog - ThrillWiki',
|
||||||
|
description: searchQuery
|
||||||
|
? `Search results for "${searchQuery}" in ThrillWiki Blog`
|
||||||
|
: 'News, updates, and stories from the world of theme parks and roller coasters',
|
||||||
|
imageUrl: data?.posts?.[0]?.featured_image_url,
|
||||||
|
imageId: data?.posts?.[0]?.featured_image_id,
|
||||||
|
type: 'website',
|
||||||
|
enabled: !isLoading
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
<Header />
|
<Header />
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { useAuth } from '@/hooks/useAuth';
|
|||||||
import { toast } from '@/hooks/use-toast';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
export default function DesignerRides() {
|
export default function DesignerRides() {
|
||||||
const { designerSlug } = useParams<{ designerSlug: string }>();
|
const { designerSlug } = useParams<{ designerSlug: string }>();
|
||||||
@@ -104,6 +105,17 @@ export default function DesignerRides() {
|
|||||||
ride.park?.name?.toLowerCase().includes(searchQuery.toLowerCase())
|
ride.park?.name?.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: designer ? `${designer.name} - Rides` : 'Designer Rides',
|
||||||
|
description: designer
|
||||||
|
? `Explore ${filteredRides.length} rides designed by ${designer.name}`
|
||||||
|
: undefined,
|
||||||
|
imageUrl: designer?.banner_image_url || filteredRides[0]?.banner_image_url,
|
||||||
|
imageId: designer?.banner_image_id || filteredRides[0]?.banner_image_id,
|
||||||
|
type: 'website',
|
||||||
|
enabled: !!designer && !loading
|
||||||
|
});
|
||||||
|
|
||||||
const handleCreateSubmit = async (data: any) => {
|
const handleCreateSubmit = async (data: any) => {
|
||||||
try {
|
try {
|
||||||
if (!designer) {
|
if (!designer) {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import { submitCompanyCreation } from '@/lib/companyHelpers';
|
|||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { getErrorMessage } from '@/lib/errorHandler';
|
import { getErrorMessage } from '@/lib/errorHandler';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
export default function Designers() {
|
export default function Designers() {
|
||||||
useDocumentTitle('Designers');
|
useDocumentTitle('Designers');
|
||||||
@@ -164,6 +165,15 @@ export default function Designers() {
|
|||||||
});
|
});
|
||||||
}, [companies, searchQuery, filters]);
|
}, [companies, searchQuery, filters]);
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: 'Ride Designers - ThrillWiki',
|
||||||
|
description: `Browse ${filteredCompanies.length} ride designers worldwide`,
|
||||||
|
imageUrl: filteredCompanies[0]?.banner_image_url,
|
||||||
|
imageId: filteredCompanies[0]?.banner_image_id,
|
||||||
|
type: 'website',
|
||||||
|
enabled: !loading
|
||||||
|
});
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
|
|||||||
@@ -2,10 +2,17 @@ import { Header } from '@/components/layout/Header';
|
|||||||
import { SimpleHeroSearch } from '@/components/homepage/SimpleHeroSearch';
|
import { SimpleHeroSearch } from '@/components/homepage/SimpleHeroSearch';
|
||||||
import { ContentTabs } from '@/components/homepage/ContentTabs';
|
import { ContentTabs } from '@/components/homepage/ContentTabs';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
const Index = () => {
|
const Index = () => {
|
||||||
useDocumentTitle('Home');
|
useDocumentTitle('Home');
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: 'ThrillWiki - Theme Park & Roller Coaster Database',
|
||||||
|
description: 'Explore theme parks and roller coasters worldwide with ThrillWiki - the comprehensive database for enthusiasts',
|
||||||
|
type: 'website'
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
<Header />
|
<Header />
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { useAuth } from '@/hooks/useAuth';
|
|||||||
import { toast } from '@/hooks/use-toast';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
interface RideModelWithCount extends RideModel {
|
interface RideModelWithCount extends RideModel {
|
||||||
ride_count: number;
|
ride_count: number;
|
||||||
@@ -101,6 +102,17 @@ export default function ManufacturerModels() {
|
|||||||
model.description?.toLowerCase().includes(searchQuery.toLowerCase())
|
model.description?.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: manufacturer ? `${manufacturer.name} - Ride Models` : 'Manufacturer Models',
|
||||||
|
description: manufacturer
|
||||||
|
? `Browse ${filteredModels.length} ride models by ${manufacturer.name}`
|
||||||
|
: undefined,
|
||||||
|
imageUrl: manufacturer?.banner_image_url || filteredModels[0]?.banner_image_url,
|
||||||
|
imageId: manufacturer?.banner_image_id || filteredModels[0]?.banner_image_id,
|
||||||
|
type: 'website',
|
||||||
|
enabled: !!manufacturer && !loading
|
||||||
|
});
|
||||||
|
|
||||||
const handleCreateSubmit = async (data: any) => {
|
const handleCreateSubmit = async (data: any) => {
|
||||||
try {
|
try {
|
||||||
if (!manufacturer) {
|
if (!manufacturer) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { useAuth } from '@/hooks/useAuth';
|
|||||||
import { toast } from '@/hooks/use-toast';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
export default function ManufacturerRides() {
|
export default function ManufacturerRides() {
|
||||||
const { manufacturerSlug } = useParams<{ manufacturerSlug: string }>();
|
const { manufacturerSlug } = useParams<{ manufacturerSlug: string }>();
|
||||||
@@ -104,6 +105,17 @@ export default function ManufacturerRides() {
|
|||||||
ride.park?.name?.toLowerCase().includes(searchQuery.toLowerCase())
|
ride.park?.name?.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: manufacturer ? `${manufacturer.name} - Rides` : 'Manufacturer Rides',
|
||||||
|
description: manufacturer
|
||||||
|
? `Explore ${filteredRides.length} rides manufactured by ${manufacturer.name}`
|
||||||
|
: undefined,
|
||||||
|
imageUrl: manufacturer?.banner_image_url || filteredRides[0]?.banner_image_url,
|
||||||
|
imageId: manufacturer?.banner_image_id || filteredRides[0]?.banner_image_id,
|
||||||
|
type: 'website',
|
||||||
|
enabled: !!manufacturer && !loading
|
||||||
|
});
|
||||||
|
|
||||||
const handleCreateSubmit = async (data: any) => {
|
const handleCreateSubmit = async (data: any) => {
|
||||||
try {
|
try {
|
||||||
if (!manufacturer) {
|
if (!manufacturer) {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import { submitCompanyCreation } from '@/lib/companyHelpers';
|
|||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { getErrorMessage } from '@/lib/errorHandler';
|
import { getErrorMessage } from '@/lib/errorHandler';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
export default function Manufacturers() {
|
export default function Manufacturers() {
|
||||||
useDocumentTitle('Manufacturers');
|
useDocumentTitle('Manufacturers');
|
||||||
@@ -151,6 +152,15 @@ export default function Manufacturers() {
|
|||||||
});
|
});
|
||||||
}, [companies, searchQuery, filters]);
|
}, [companies, searchQuery, filters]);
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: 'Ride Manufacturers - ThrillWiki',
|
||||||
|
description: `Browse ${filteredCompanies.length} ride manufacturers worldwide`,
|
||||||
|
imageUrl: filteredCompanies[0]?.banner_image_url,
|
||||||
|
imageId: filteredCompanies[0]?.banner_image_id,
|
||||||
|
type: 'website',
|
||||||
|
enabled: !loading
|
||||||
|
});
|
||||||
|
|
||||||
const handleCreateSubmit = async (data: any) => {
|
const handleCreateSubmit = async (data: any) => {
|
||||||
try {
|
try {
|
||||||
await submitCompanyCreation(
|
await submitCompanyCreation(
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
|||||||
import { Grid3X3, List } from 'lucide-react';
|
import { Grid3X3, List } from 'lucide-react';
|
||||||
import { FilterState, SortState } from './Parks';
|
import { FilterState, SortState } from './Parks';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
const initialFilters: FilterState = {
|
const initialFilters: FilterState = {
|
||||||
search: '',
|
search: '',
|
||||||
@@ -145,6 +146,17 @@ export default function OperatorParks() {
|
|||||||
return filtered;
|
return filtered;
|
||||||
}, [parks, filters, sort]);
|
}, [parks, filters, sort]);
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: operator ? `Parks by ${operator.name} - ThrillWiki` : 'Operator Parks',
|
||||||
|
description: operator
|
||||||
|
? `Explore ${filteredAndSortedParks.length} theme parks operated by ${operator.name}`
|
||||||
|
: undefined,
|
||||||
|
imageUrl: operator?.banner_image_url || filteredAndSortedParks[0]?.banner_image_url,
|
||||||
|
imageId: operator?.banner_image_id || filteredAndSortedParks[0]?.banner_image_id,
|
||||||
|
type: 'website',
|
||||||
|
enabled: !!operator && !loading
|
||||||
|
});
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import { submitCompanyCreation } from '@/lib/companyHelpers';
|
|||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { getErrorMessage } from '@/lib/errorHandler';
|
import { getErrorMessage } from '@/lib/errorHandler';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
const Operators = () => {
|
const Operators = () => {
|
||||||
useDocumentTitle('Operators');
|
useDocumentTitle('Operators');
|
||||||
@@ -182,6 +183,15 @@ const Operators = () => {
|
|||||||
return filtered;
|
return filtered;
|
||||||
}, [operators, searchTerm, sortBy, filters]);
|
}, [operators, searchTerm, sortBy, filters]);
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: 'Park Operators - ThrillWiki',
|
||||||
|
description: `Browse ${filteredAndSortedOperators.length} theme park operators worldwide`,
|
||||||
|
imageUrl: filteredAndSortedOperators[0]?.banner_image_url,
|
||||||
|
imageId: filteredAndSortedOperators[0]?.banner_image_id,
|
||||||
|
type: 'website',
|
||||||
|
enabled: !isLoading
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
<Header />
|
<Header />
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
|||||||
import { Grid3X3, List } from 'lucide-react';
|
import { Grid3X3, List } from 'lucide-react';
|
||||||
import { FilterState, SortState } from './Parks';
|
import { FilterState, SortState } from './Parks';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
const initialFilters: FilterState = {
|
const initialFilters: FilterState = {
|
||||||
search: '',
|
search: '',
|
||||||
@@ -145,6 +146,17 @@ export default function OwnerParks() {
|
|||||||
return filtered;
|
return filtered;
|
||||||
}, [parks, filters, sort]);
|
}, [parks, filters, sort]);
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: owner ? `Parks by ${owner.name} - ThrillWiki` : 'Owner Parks',
|
||||||
|
description: owner
|
||||||
|
? `Explore ${filteredAndSortedParks.length} theme parks owned by ${owner.name}`
|
||||||
|
: undefined,
|
||||||
|
imageUrl: owner?.banner_image_url || filteredAndSortedParks[0]?.banner_image_url,
|
||||||
|
imageId: owner?.banner_image_id || filteredAndSortedParks[0]?.banner_image_id,
|
||||||
|
type: 'website',
|
||||||
|
enabled: !!owner && !loading
|
||||||
|
});
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { submitCompanyCreation } from '@/lib/companyHelpers';
|
|||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { getErrorMessage } from '@/lib/errorHandler';
|
import { getErrorMessage } from '@/lib/errorHandler';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
const ParkOwners = () => {
|
const ParkOwners = () => {
|
||||||
useDocumentTitle('Property Owners');
|
useDocumentTitle('Property Owners');
|
||||||
@@ -119,6 +120,15 @@ const ParkOwners = () => {
|
|||||||
return filtered;
|
return filtered;
|
||||||
}, [parkOwners, searchTerm, sortBy, filterBy]);
|
}, [parkOwners, searchTerm, sortBy, filterBy]);
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: 'Property Owners - ThrillWiki',
|
||||||
|
description: `Browse ${filteredAndSortedOwners.length} theme park property owners worldwide`,
|
||||||
|
imageUrl: filteredAndSortedOwners[0]?.banner_image_url,
|
||||||
|
imageId: filteredAndSortedOwners[0]?.banner_image_id,
|
||||||
|
type: 'website',
|
||||||
|
enabled: !isLoading
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
<Header />
|
<Header />
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { toast } from '@/hooks/use-toast';
|
|||||||
import { getErrorMessage } from '@/lib/errorHandler';
|
import { getErrorMessage } from '@/lib/errorHandler';
|
||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
export default function ParkRides() {
|
export default function ParkRides() {
|
||||||
const { parkSlug } = useParams<{ parkSlug: string }>();
|
const { parkSlug } = useParams<{ parkSlug: string }>();
|
||||||
@@ -150,6 +151,17 @@ export default function ParkRides() {
|
|||||||
ride.manufacturer?.name?.toLowerCase().includes(searchQuery.toLowerCase())
|
ride.manufacturer?.name?.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: park ? `${park.name} - Rides & Attractions` : 'Park Rides',
|
||||||
|
description: park
|
||||||
|
? `Explore ${filteredRides.length} rides and attractions at ${park.name}`
|
||||||
|
: undefined,
|
||||||
|
imageUrl: park?.banner_image_url || filteredRides[0]?.banner_image_url,
|
||||||
|
imageId: park?.banner_image_id || filteredRides[0]?.banner_image_id,
|
||||||
|
type: 'website',
|
||||||
|
enabled: !!park && !loading
|
||||||
|
});
|
||||||
|
|
||||||
const categories = [
|
const categories = [
|
||||||
{ value: 'all', label: 'All Categories' },
|
{ value: 'all', label: 'All Categories' },
|
||||||
{ value: 'roller_coaster', label: 'Roller Coasters' },
|
{ value: 'roller_coaster', label: 'Roller Coasters' },
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import { ParkForm } from '@/components/admin/ParkForm';
|
|||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
import { useUserRole } from '@/hooks/useUserRole';
|
import { useUserRole } from '@/hooks/useUserRole';
|
||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
export interface FilterState {
|
export interface FilterState {
|
||||||
search: string;
|
search: string;
|
||||||
@@ -288,6 +289,30 @@ export default function Parks() {
|
|||||||
return filtered;
|
return filtered;
|
||||||
}, [parks, filters, sort]);
|
}, [parks, filters, sort]);
|
||||||
|
|
||||||
|
const generateDescription = () => {
|
||||||
|
if (!parks.length) return 'Browse theme parks worldwide on ThrillWiki';
|
||||||
|
|
||||||
|
const activeFilters = [];
|
||||||
|
if (filters.country.length === 1) activeFilters.push(`in ${filters.country[0]}`);
|
||||||
|
if (filters.parkType.length > 0) activeFilters.push(filters.parkType.join(', '));
|
||||||
|
if (filters.status.length > 0) activeFilters.push(filters.status.join(', '));
|
||||||
|
|
||||||
|
if (activeFilters.length > 0) {
|
||||||
|
return `Browse ${filteredAndSortedParks.length} ${activeFilters.join(' ')} theme parks`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `Browse ${parks.length} theme parks worldwide`;
|
||||||
|
};
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: 'Theme Parks - ThrillWiki',
|
||||||
|
description: generateDescription(),
|
||||||
|
imageUrl: filteredAndSortedParks[0]?.banner_image_url,
|
||||||
|
imageId: filteredAndSortedParks[0]?.banner_image_id,
|
||||||
|
type: 'website',
|
||||||
|
enabled: !loading
|
||||||
|
});
|
||||||
|
|
||||||
const activeFilterCount = useMemo(() => {
|
const activeFilterCount = useMemo(() => {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
if (filters.search) count++;
|
if (filters.search) count++;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import { UserBlockButton } from '@/components/profile/UserBlockButton';
|
|||||||
import { PersonalLocationDisplay } from '@/components/profile/PersonalLocationDisplay';
|
import { PersonalLocationDisplay } from '@/components/profile/PersonalLocationDisplay';
|
||||||
import { useUserRole } from '@/hooks/useUserRole';
|
import { useUserRole } from '@/hooks/useUserRole';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
// Activity type definitions
|
// Activity type definitions
|
||||||
interface SubmissionActivity {
|
interface SubmissionActivity {
|
||||||
@@ -160,6 +161,15 @@ export default function Profile() {
|
|||||||
// Update document title when profile changes
|
// Update document title when profile changes
|
||||||
useDocumentTitle(profile?.username ? `${profile.username}'s Profile` : 'Profile');
|
useDocumentTitle(profile?.username ? `${profile.username}'s Profile` : 'Profile');
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: profile ? `${profile.display_name || profile.username} - ThrillWiki` : 'User Profile',
|
||||||
|
description: profile?.bio || (profile ? `${profile.display_name || profile.username}'s profile on ThrillWiki` : undefined),
|
||||||
|
imageUrl: profile?.avatar_url,
|
||||||
|
imageId: profile?.avatar_image_id,
|
||||||
|
type: 'profile',
|
||||||
|
enabled: !!profile
|
||||||
|
});
|
||||||
|
|
||||||
// Username validation
|
// Username validation
|
||||||
const usernameValidation = useUsernameValidation(editForm.username, profile?.username);
|
const usernameValidation = useUsernameValidation(editForm.username, profile?.username);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import { toast } from '@/hooks/use-toast';
|
|||||||
import { getErrorMessage } from '@/lib/errorHandler';
|
import { getErrorMessage } from '@/lib/errorHandler';
|
||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
export default function Rides() {
|
export default function Rides() {
|
||||||
useDocumentTitle('Rides & Attractions');
|
useDocumentTitle('Rides & Attractions');
|
||||||
@@ -266,6 +267,28 @@ export default function Rides() {
|
|||||||
return filtered;
|
return filtered;
|
||||||
}, [rides, searchQuery, sortBy, filters]);
|
}, [rides, searchQuery, sortBy, filters]);
|
||||||
|
|
||||||
|
const generateDescription = () => {
|
||||||
|
if (!filteredAndSortedRides.length) return 'Discover thrilling rides and roller coasters worldwide';
|
||||||
|
|
||||||
|
const activeFilters = [];
|
||||||
|
if (filters.categories.length > 0) activeFilters.push(filters.categories.join(', '));
|
||||||
|
if (filters.status !== 'all') activeFilters.push(filters.status);
|
||||||
|
|
||||||
|
if (activeFilters.length > 0) {
|
||||||
|
return `Explore ${filteredAndSortedRides.length} ${activeFilters.join(' ')} rides and attractions`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `Explore ${filteredAndSortedRides.length} rides and roller coasters worldwide`;
|
||||||
|
};
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: 'Rides & Attractions - ThrillWiki',
|
||||||
|
description: generateDescription(),
|
||||||
|
imageUrl: filteredAndSortedRides[0]?.banner_image_url,
|
||||||
|
imageId: filteredAndSortedRides[0]?.banner_image_id,
|
||||||
|
type: 'website',
|
||||||
|
enabled: !loading
|
||||||
|
});
|
||||||
|
|
||||||
const categories = [
|
const categories = [
|
||||||
{ value: 'all', label: 'All Categories' },
|
{ value: 'all', label: 'All Categories' },
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { SearchFiltersComponent, SearchFilters } from '@/components/search/Searc
|
|||||||
import { SearchSortOptions, SortOption } from '@/components/search/SearchSortOptions';
|
import { SearchSortOptions, SortOption } from '@/components/search/SearchSortOptions';
|
||||||
import { EnhancedSearchResults } from '@/components/search/EnhancedSearchResults';
|
import { EnhancedSearchResults } from '@/components/search/EnhancedSearchResults';
|
||||||
import { useSearch, SearchResult } from '@/hooks/useSearch';
|
import { useSearch, SearchResult } from '@/hooks/useSearch';
|
||||||
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
|
||||||
export default function SearchPage() {
|
export default function SearchPage() {
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
@@ -121,6 +122,15 @@ export default function SearchPage() {
|
|||||||
company: results.filter(r => r.type === 'company').length
|
company: results.filter(r => r.type === 'company').length
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useOpenGraph({
|
||||||
|
title: query ? `Search: "${query}" - ThrillWiki` : 'Search - ThrillWiki',
|
||||||
|
description: query
|
||||||
|
? `Found ${filteredAndSortedResults.length} results for "${query}"`
|
||||||
|
: 'Search theme parks, rides, and more on ThrillWiki',
|
||||||
|
type: 'website',
|
||||||
|
enabled: !loading
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
<Header />
|
<Header />
|
||||||
|
|||||||
Reference in New Issue
Block a user