// src/data/business.ts // ALLA fakta om Images by Olofsson på ett ställe. Sidor, JSON-LD, llms.txt och // sitemap läser härifrån – skriv aldrig in fakta direkt i en sida. // // Regel: det vi inte vet är `null`. Allt som läser filen hoppar över null-värden // (ingen "TODO", inga påhittade siffror syns på sajten). När Linus lämnar ett // värde: fyll i det här, så dyker det upp på /tjanster, i FAQ och i JSON-LD. export type Genre = { /** Kort id, används som ankare på /tjanster (#portratt osv.) */ id: string; name: string; description: string; }; export type Business = { brand: string; url: string; person: { name: string; jobTitle: string; }; email: string; /** Telefonnummer i format +46... – okänt */ phone: string | null; country: { code: string; name: string }; /** Ort Linus utgår från (hans publika Flickr- och LinkedIn-profil, 2026-10-27) */ city: string | null; /** Län/region (LinkedIn, 2026-10-27) */ region: string | null; /** Område han tar uppdrag i (fritext, t.ex. "Stockholm med omnejd") – okänt */ serviceArea: string | null; /** Lägsta pris i SEK för en fotografering – okänt */ priceFromSek: number | null; /** schema.org priceRange, t.ex. "$$" eller "1500–5000 kr" – okänt */ priceRange: string | null; /** Paket och vad som ingår – okänt */ packages: { name: string; includes: string[]; priceSek: number | null }[] | null; /** Typisk leveranstid, fritext (t.ex. "inom två veckor") – okänt */ deliveryTime: string | null; /** Antal år som fotograf – okänt */ yearsOfExperience: number | null; /** Kundomdömen – inga kända */ testimonials: { name: string; text: string }[] | null; camera: string; lenses: string[]; editing: string; /** Linus egen formulering: "featured by Adobe three times". Inga datum/detaljer. Jag-form för sidtext. */ recognition: string; /** Samma fakta i tredje person (llms.txt, JSON-LD, meta descriptions). */ recognitionThirdPerson: string; portal: { url: string; bookingUrl: string; }; social: { instagram: { handle: string; url: string }; facebook: string; flickr: string; lightroom: string; linkedin: string; github: string; }; genres: Genre[]; bookingSteps: { title: string; text: string }[]; }; export const business: Business = { brand: 'Images by Olofsson', url: 'https://imagesbyolofsson.se', person: { name: 'Linus Olofsson', jobTitle: 'Fotograf', }, email: 'Admin@imagesbyolofsson.se', phone: null, country: { code: 'SE', name: 'Sverige' }, city: 'Örebro', region: 'Örebro län', serviceArea: null, priceFromSek: null, priceRange: null, packages: null, deliveryTime: null, yearsOfExperience: null, testimonials: null, camera: 'Sony A7R V', lenses: ['Sony FE 70-200mm f/4 G OSS', 'Sony FE 20mm f/1.8 G'], editing: 'Adobe Lightroom Classic', recognition: 'Mina bilder har lyfts fram av Adobe tre gånger.', recognitionThirdPerson: 'Hans bilder har lyfts fram av Adobe tre gånger.', portal: { url: 'https://customer.imagesbyolofsson.se', bookingUrl: 'https://customer.imagesbyolofsson.se/boka', }, social: { instagram: { handle: '@imagesbyolofsson', url: 'https://www.instagram.com/imagesbyolofsson/' }, facebook: 'https://www.facebook.com/imagesbyolofsson', flickr: 'https://www.flickr.com/photos/imagesbyolofsson/', lightroom: 'https://lightroom.adobe.com/u/linusolofsson1', linkedin: 'https://www.linkedin.com/in/linus-olofsson-/', github: 'https://github.com/LinusOlofsson-maker', }, // Bara genrer som redan finns i sajtens texter och gamla sidnamn // (/my-people, /animales-and-nature, /celebrations-with-family, /northen-lights). genres: [ { id: 'portratt', name: 'Porträtt och människor', description: 'Porträtt och ögonblick med människor – uttryck som berättar något utan ord.', }, { id: 'natur', name: 'Natur och djur', description: 'Skog, landskap och djur – naturens stillhet och de små detaljerna i den.', }, { id: 'stad', name: 'Stad och arkitektur', description: 'Gator, byggnader, strukturer och kontraster – stadens energi och dess tomma stunder.', }, { id: 'makro', name: 'Makro och detaljer', description: 'Mönster, texturer och små detaljer som de flesta går förbi.', }, { id: 'norrsken', name: 'Norrsken', description: 'Norrskenets ljus och färger över himlen.', }, { id: 'fest', name: 'Fester och familjehögtider', description: 'Bilder från fester och högtider tillsammans med familj och vänner.', }, ], bookingSteps: [ { title: 'Skicka en förfrågan', text: 'Berätta vad du vill ha fotograferat, när och var – via kundportalen.', }, { title: 'Få en offert', text: 'Jag återkommer med ett förslag och en offert för just ditt uppdrag.', }, { title: 'Bokning', text: 'När du har godkänt offerten bokar vi in fotograferingen.', }, { title: 'Leverans i ett privat galleri', text: 'Du får bilderna i ett eget, privat galleri i kundportalen.', }, { title: 'Originalfilerna efter betalning', text: 'När betalningen är klar kan du ladda ner originalfilerna i full upplösning.', }, ], }; /** Genrer som läsbar lista: "a, b, c samt d". */ export function genreList(lowercase = true): string { const names = business.genres.map((g) => (lowercase ? g.name.toLowerCase() : g.name)); if (names.length <= 1) return names.join(''); // "samt" före sista ledet, eftersom genrenamnen själva innehåller "och". return `${names.slice(0, -1).join(', ')} samt ${names[names.length - 1]}`; } /** "Sverige", eller "Ort, Sverige" när orten är känd. */ export function basedIn(): string { return [business.city, business.country.name].filter(Boolean).join(', '); } /** Formaterat pris ("1 500 kr") eller null. */ export function formatSek(value: number | null): string | null { if (value == null) return null; return `${value.toLocaleString('sv-SE')} kr`; } export function absoluteUrl(path: string): string { return new URL(path, business.url).toString(); }