Files
homeproz/wp-content/themes/homeproz/archive-property.php
T
Hanson.xyz Dev acc8ac87a0 wip
2026-01-04 17:50:08 -06:00

197 lines
9.9 KiB
PHP
Executable File

<?php
/**
* Property Archive Template
*
* Displays the properties listing page with optional map view
*
* @package HomeProz
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// Check if viewing a single MLS property
if (isset($_GET['listing']) && !empty($_GET['listing'])) {
$listing_key = sanitize_text_field($_GET['listing']);
set_query_var('mls_listing_key', $listing_key);
get_template_part('template-parts/property/single-property-mls');
exit;
}
get_header();
// Map view is default on desktop, grid view requires ?view=grid
$show_map = !isset($_GET['view']) || $_GET['view'] !== 'grid';
$view_class = $show_map ? 'is-map-view' : 'is-grid-view';
// Near me mode - show location prompt before loading map
$near_me_mode = isset($_GET['near_me']) && $_GET['near_me'] === '1';
if ($near_me_mode) {
$view_class .= ' is-near-me-mode';
}
?>
<main id="primary" class="site-main property-archive-main <?php echo esc_attr($view_class); ?>">
<?php
// Get hero content from Theme Options
$hero_title = get_field('properties_hero_title', 'option') ?: 'Find Your Perfect Property';
$hero_subtitle = get_field('properties_hero_subtitle', 'option') ?: 'Browse our selection of homes, land, and commercial properties in southern Minnesota.';
$hero_bg = get_field('properties_hero_background', 'option');
$has_bg_class = $hero_bg ? 'has-background' : '';
$bg_style = $hero_bg ? 'style="background-image: url(' . esc_url($hero_bg) . ');"' : '';
?>
<!-- Archive Hero -->
<section class="archive-hero <?php echo esc_attr($has_bg_class); ?>" <?php echo $bg_style; ?>>
<?php if ($hero_bg) : ?>
<div class="archive-hero-overlay"></div>
<?php endif; ?>
<div class="container">
<h1 class="archive-hero-title"><?php echo esc_html($hero_title); ?></h1>
<p class="archive-hero-subtitle"><?php echo esc_html($hero_subtitle); ?></p>
</div>
</section>
<?php if ($near_me_mode) : ?>
<!-- Near Me Location Prompt -->
<div id="near-me-overlay" class="near-me-overlay">
<div class="near-me-prompt">
<div class="near-me-icon">
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
<circle cx="12" cy="12" r="3"/>
<path d="M12 2v3M12 19v3M2 12h3M19 12h3"/>
<circle cx="12" cy="12" r="8"/>
</svg>
</div>
<h2 class="near-me-title" id="near-me-title">Finding your location...</h2>
<p class="near-me-message" id="near-me-message">Click "Allow" in your browser when prompted to share your location.</p>
<a href="<?php echo esc_url(home_url('/properties/')); ?>" class="btn btn-primary near-me-fallback">View All Properties</a>
</div>
</div>
<?php endif; ?>
<div class="container">
<!-- Filters -->
<?php get_template_part('template-parts/property/property-filters'); ?>
<!-- Map + List View (hidden below 1024px via CSS) -->
<div class="property-map-layout">
<div class="property-sidebar">
<div class="property-sidebar-content">
<!-- View Toggle -->
<div class="view-toggle">
<a href="<?php echo esc_url(add_query_arg('view', 'grid')); ?>" class="view-toggle-btn view-toggle-grid">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<rect x="3" y="3" width="7" height="7"/>
<rect x="14" y="3" width="7" height="7"/>
<rect x="3" y="14" width="7" height="7"/>
<rect x="14" y="14" width="7" height="7"/>
</svg>
<span>Grid</span>
</a>
<a href="<?php echo esc_url(remove_query_arg('view')); ?>" class="view-toggle-btn view-toggle-map active">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6"/>
<line x1="8" y1="2" x2="8" y2="18"/>
<line x1="16" y1="6" x2="16" y2="22"/>
</svg>
<span>Map</span>
</a>
<a href="<?php echo esc_url(home_url('/properties/?near_me=1')); ?>" class="view-toggle-btn view-toggle-nearme">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<circle cx="12" cy="12" r="3"/>
<path d="M12 2v3M12 19v3M2 12h3M19 12h3"/>
<circle cx="12" cy="12" r="8"/>
</svg>
<span>Near Me</span>
</a>
</div>
<div id="property-map" class="property-map">
<!-- Leaflet map will be initialized here -->
</div>
<!-- Sticky Filters (below map, visible when main filters scroll out of view) -->
<?php get_template_part('template-parts/property/property-filters-sticky'); ?>
</div>
</div>
<div class="property-list-container">
<div id="property-results" class="property-results-map">
<?php get_template_part('template-parts/property/property-results'); ?>
</div>
</div>
</div>
<!-- Grid View (shown below 1024px, or when grid selected above 1024px) -->
<div class="grid-view-container">
<div class="view-toggle">
<a href="<?php echo esc_url(add_query_arg('view', 'grid')); ?>" class="view-toggle-btn view-toggle-grid active">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<rect x="3" y="3" width="7" height="7"/>
<rect x="14" y="3" width="7" height="7"/>
<rect x="3" y="14" width="7" height="7"/>
<rect x="14" y="14" width="7" height="7"/>
</svg>
<span>Grid</span>
</a>
<a href="<?php echo esc_url(remove_query_arg('view')); ?>" class="view-toggle-btn view-toggle-map">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6"/>
<line x1="8" y1="2" x2="8" y2="18"/>
<line x1="16" y1="6" x2="16" y2="22"/>
</svg>
<span>Map</span>
</a>
<a href="<?php echo esc_url(home_url('/properties/?near_me=1')); ?>" class="view-toggle-btn view-toggle-nearme">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<circle cx="12" cy="12" r="3"/>
<path d="M12 2v3M12 19v3M2 12h3M19 12h3"/>
<circle cx="12" cy="12" r="8"/>
</svg>
<span>Near Me</span>
</a>
</div>
<div id="property-results-grid" class="property-results-grid">
<?php get_template_part('template-parts/property/property-results'); ?>
</div>
</div>
</div>
</main>
<?php
// Get initial filter values from URL for map clustering
$initial_filters = array(
'status' => isset($_GET['property_status']) ? sanitize_text_field($_GET['property_status']) : 'Active',
'property_type' => isset($_GET['property_type']) ? sanitize_text_field($_GET['property_type']) : '',
'city' => isset($_GET['city']) ? sanitize_text_field($_GET['city']) : '',
'min_price' => isset($_GET['min_price']) ? intval($_GET['min_price']) : '',
'max_price' => isset($_GET['max_price']) ? intval($_GET['max_price']) : '',
'min_beds' => isset($_GET['beds']) ? intval($_GET['beds']) : '',
'center_lat' => isset($_GET['lat']) ? floatval($_GET['lat']) : '',
'center_lng' => isset($_GET['lng']) ? floatval($_GET['lng']) : '',
'radius' => isset($_GET['radius']) ? intval($_GET['radius']) : 30,
);
// Get total property count with coordinates for display
$total_with_coords = 0;
if (function_exists('mls_get_property_count')) {
$total_with_coords = mls_get_property_count(array('status' => $initial_filters['status'] ?: 'Active'));
}
?>
<!-- Leaflet CSS -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
<!-- Leaflet JS -->
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<script>
var homeprozMapData = {
isMapView: <?php echo $show_map ? 'true' : 'false'; ?>,
isNearMeMode: <?php echo $near_me_mode ? 'true' : 'false'; ?>,
clusterEndpoint: '<?php echo admin_url('admin-ajax.php'); ?>',
initialFilters: <?php echo json_encode($initial_filters); ?>,
totalProperties: <?php echo (int) $total_with_coords; ?>,
propertiesUrl: '<?php echo esc_url(home_url('/properties/')); ?>'
};
</script>
<?php
get_footer();