Før Codex endrer blant annet scorekort
This commit is contained in:
parent
2630e9a9fa
commit
1e2f79e36b
3 changed files with 56 additions and 5 deletions
|
|
@ -117,7 +117,7 @@ def format_row(row):
|
|||
|
||||
for key in [
|
||||
'status_updated_at', 'created_at', 'slope_valid_until',
|
||||
'membership_updated_at', 'greenfee_updated_at', 'vtg_updated_at'
|
||||
'membership_updated_at', 'greenfee_updated_at', 'vtg_updated_at', 'footnote_updated_at'
|
||||
]:
|
||||
if isinstance(d.get(key), (date, datetime)):
|
||||
d[key] = d[key].isoformat()
|
||||
|
|
@ -199,6 +199,14 @@ async def queue_scrape_job(job_type: str, facility_ids: List[int], requested_by:
|
|||
}
|
||||
|
||||
|
||||
async def ensure_facility_columns(conn):
|
||||
"""Legger til nye facility-kolonner ved behov."""
|
||||
await conn.execute("""
|
||||
ALTER TABLE facilities
|
||||
ADD COLUMN IF NOT EXISTS footnote_updated_at TIMESTAMPTZ
|
||||
""")
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
# Opprett database-pool ved start
|
||||
|
|
@ -211,6 +219,7 @@ async def lifespan(app: FastAPI):
|
|||
command_timeout=60
|
||||
)
|
||||
async with app.state.pool.acquire() as conn:
|
||||
await ensure_facility_columns(conn)
|
||||
await ensure_scrape_jobs_table(conn)
|
||||
print("✅ Database tilkoblet og pool opprettet")
|
||||
except Exception as e:
|
||||
|
|
@ -436,7 +445,8 @@ async def update_facility_full(facility_id: int, request: Request):
|
|||
'vtg_presentasjon', 'vtg_lenke', 'vtg_pris', 'vtg_kursdatoer',
|
||||
'guest_requirements', 'scrape_method', 'scrape_status_url',
|
||||
'social_links', 'footnote', 'cooperating_clubs', 'membership_draft', 'membership_updated_at',
|
||||
'greenfee_url', 'greenfee_draft', 'greenfee_updated_at', 'scrape_status_selector', 'vtg_lenke'
|
||||
'greenfee_url', 'greenfee_draft', 'greenfee_updated_at', 'scrape_status_selector', 'vtg_lenke',
|
||||
'footnote_updated_at'
|
||||
]
|
||||
|
||||
update_data = {k: v for k, v in data.items() if k in allowed_fields}
|
||||
|
|
@ -446,11 +456,28 @@ async def update_facility_full(facility_id: int, request: Request):
|
|||
|
||||
# 1. OPPDATER ANLEGG (FACILITIES)
|
||||
if update_data:
|
||||
if 'footnote' in update_data and 'footnote_updated_at' not in update_data:
|
||||
existing_footnote = await conn.fetchval(
|
||||
"SELECT footnote FROM facilities WHERE id = $1",
|
||||
facility_id
|
||||
)
|
||||
incoming_footnote = str(update_data.get('footnote') or '').strip()
|
||||
current_footnote = str(existing_footnote or '').strip()
|
||||
|
||||
if incoming_footnote != current_footnote:
|
||||
update_data['footnote_updated_at'] = datetime.utcnow() if incoming_footnote else None
|
||||
|
||||
set_clauses = []
|
||||
values = []
|
||||
|
||||
# Definer hvilke felt som er datoer i databasen
|
||||
date_fields = ['membership_updated_at', 'greenfee_updated_at', 'vtg_updated_at', 'status_updated_at']
|
||||
date_fields = [
|
||||
'membership_updated_at',
|
||||
'greenfee_updated_at',
|
||||
'vtg_updated_at',
|
||||
'status_updated_at',
|
||||
'footnote_updated_at'
|
||||
]
|
||||
|
||||
for i, (k, v) in enumerate(update_data.items(), 1):
|
||||
if isinstance(v, (dict, list)):
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import { STATUS_MAP } from "@/config/constants";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useMemo, useState, type CSSProperties } from "react";
|
||||
|
||||
type SortMethod = "updated" | "dist" | "alpha";
|
||||
type Variant = "home" | "catalog";
|
||||
|
|
@ -29,6 +29,8 @@ type Facility = {
|
|||
vtg_pris?: number | null;
|
||||
vtg_lenke?: string | null;
|
||||
vtg_beskrivelse?: string | null;
|
||||
footnote?: string | null;
|
||||
footnote_updated_at?: string | null;
|
||||
status_updated_at?: string | null;
|
||||
amenities?: unknown;
|
||||
golfamore_data?: unknown;
|
||||
|
|
@ -237,6 +239,13 @@ const getSearchShellClasses = (variant: Variant) =>
|
|||
? "rounded-[2rem] bg-[#39443B] px-4 py-5 text-white shadow-2xl sm:px-6 sm:py-7"
|
||||
: "surface-card rounded-[2rem] px-4 py-5 text-[#112015] sm:px-6 sm:py-7";
|
||||
|
||||
const noteClampStyle: CSSProperties = {
|
||||
display: "-webkit-box",
|
||||
WebkitBoxOrient: "vertical",
|
||||
WebkitLineClamp: 3,
|
||||
overflow: "hidden",
|
||||
};
|
||||
|
||||
export default function FacilitySearch({
|
||||
initialFacilities,
|
||||
variant = "catalog",
|
||||
|
|
@ -602,6 +611,20 @@ export default function FacilitySearch({
|
|||
)}
|
||||
</div>
|
||||
|
||||
{facility.footnote && (
|
||||
<div className="rounded-[1.35rem] border border-[#FFD9CC] bg-[#FFF7F3] px-4 py-3">
|
||||
<p className="text-[10px] font-extrabold uppercase tracking-[0.18em] text-[#C94F2D]">
|
||||
Viktig beskjed
|
||||
<span className="ml-2 text-[#9A6A5E]">
|
||||
{formatUpdatedDate(facility.footnote_updated_at || facility.status_updated_at)}
|
||||
</span>
|
||||
</p>
|
||||
<p className="mt-2 text-[15px] italic leading-7 text-[#7B3D2C]" style={noteClampStyle}>
|
||||
{facility.footnote}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="grid grid-cols-2 gap-3 rounded-[1.35rem] bg-[#F7F8F3] p-4">
|
||||
<div>
|
||||
<p className="text-[10px] font-extrabold uppercase tracking-[0.18em] text-[#839184]">Oppdatert</p>
|
||||
|
|
|
|||
|
|
@ -125,7 +125,8 @@ export default function HeroSlider({ facilities }: { facilities: Facility[] }) {
|
|||
<span>TeeOff.no gir deg komplett oversikt over </span>
|
||||
<Link
|
||||
href="/golfbaner"
|
||||
className="font-extrabold text-[#FF5722] transition hover:text-white"
|
||||
className="font-extrabold transition hover:text-white"
|
||||
style={{ color: "#FF5722" }}
|
||||
aria-label="Se alle golfbaner"
|
||||
>
|
||||
ALLE
|
||||
|
|
|
|||
Loading…
Reference in a new issue