e95490eb72
- Grundriss (FloorPlanSection): PropertyUnit.floorPlanUrl?, Property.floorPlanUrl?; FloorPlanSection in MatchDetail + PropertyDetail; FloorPlanUrlSection in NewListing-Formular - Listenansicht (MatchCardCompact): horizontales Layout mit 120px Bildstreifen, Score-Badge, Asset-Label-Overlay, alle 3 grünen Punkte, Anfrage-Button - Light Industrial → "Gewerbe" überall (NeedInput, NeedCardPreview, CriteriaReviewPanel, newListingConstants, MyListings, propertyHelpers) - "Zum Originalinserat"-Button nur bei Maison-Work-Objekten - Image-Pool: propertyImageResolver mit sequentiellem Pool-Index (keine doppelten Bilder), nur Innenaufnahmen, rotate()-Trick für Sub-Pools - Overlay-Labels (Objekttyp + Stadtteil) in LocationPreview + IntelligenceMatchCard Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
80 lines
2.0 KiB
TypeScript
80 lines
2.0 KiB
TypeScript
import type { IPipelineProvider } from './IPipelineProvider'
|
|
import type { PipelineItem, PipelineStage } from '../domain/pipeline'
|
|
import { mockPipelineItems } from '../mock-data/pipelineItems'
|
|
|
|
const STORAGE_KEY = 'property_match_pipeline_items'
|
|
|
|
const STAGE_MIGRATION: Record<string, PipelineStage> = {
|
|
DISCOVERED: 'CONTACTED',
|
|
QUALIFIED: 'CONTACTED',
|
|
}
|
|
|
|
function migrateStage(stage: string): PipelineStage {
|
|
return (STAGE_MIGRATION[stage] ?? stage) as PipelineStage
|
|
}
|
|
|
|
function load(): PipelineItem[] {
|
|
try {
|
|
const raw = localStorage.getItem(STORAGE_KEY)
|
|
if (raw) {
|
|
const items = JSON.parse(raw) as PipelineItem[]
|
|
return items.map(i => ({ ...i, stage: migrateStage(i.stage) }))
|
|
}
|
|
} catch { /* ignore */ }
|
|
return [...mockPipelineItems]
|
|
}
|
|
|
|
function save(items: PipelineItem[]): void {
|
|
try {
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(items))
|
|
} catch { /* ignore */ }
|
|
}
|
|
|
|
export const MockupPipelineProvider: IPipelineProvider = {
|
|
async getAll() {
|
|
return load()
|
|
},
|
|
|
|
async add(item) {
|
|
const items = load()
|
|
items.push(item)
|
|
save(items)
|
|
},
|
|
|
|
async moveStage(id: string, stage: PipelineStage) {
|
|
const items = load()
|
|
const idx = items.findIndex(i => i.id === id)
|
|
if (idx !== -1) {
|
|
items[idx] = { ...items[idx], stage, updatedAt: new Date().toISOString() }
|
|
save(items)
|
|
}
|
|
},
|
|
|
|
async updateNotes(id: string, notes: string) {
|
|
const items = load()
|
|
const idx = items.findIndex(i => i.id === id)
|
|
if (idx !== -1) {
|
|
items[idx] = { ...items[idx], notes }
|
|
save(items)
|
|
}
|
|
},
|
|
|
|
async loseItem(id: string) {
|
|
const items = load()
|
|
const idx = items.findIndex(i => i.id === id)
|
|
if (idx !== -1) {
|
|
items[idx] = { ...items[idx], stage: 'CLOSED_LOST', updatedAt: new Date().toISOString() }
|
|
save(items)
|
|
}
|
|
},
|
|
|
|
async linkInquiry(id: string, inquiryId: string) {
|
|
const items = load()
|
|
const idx = items.findIndex(i => i.id === id)
|
|
if (idx !== -1) {
|
|
items[idx] = { ...items[idx], inquiryId }
|
|
save(items)
|
|
}
|
|
},
|
|
}
|