feat: Inserat erstellen — direct listing flow for units and standalone
- New /supply/new-listing page (Path A: pre-filled from portfolio unit, Path B: standalone blank form); creates EXTERNAL_MARKET + sourceType DIRECT - "+ Inserat" button on available units in PropertyDetailView navigates with prefilled address/area/rent - Nav entry "Neues Inserat" added to supply sidebar - SourceProvenancePanel hidden for DIRECT source listings (no external source) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,7 @@ import {
|
||||
Menu,
|
||||
Kanban,
|
||||
BellRing,
|
||||
Plus,
|
||||
} from 'lucide-react'
|
||||
import type { LucideIcon } from 'lucide-react'
|
||||
import { OrganizationContextBadge } from './OrganizationContextBadge'
|
||||
@@ -88,6 +89,7 @@ const WORKSPACE_CONFIG: Record<WorkspaceType, WorkspaceConfig> = {
|
||||
{ path: '/supply/anfragen', label: 'Anfragencenter', icon: MessageSquare },
|
||||
{ path: '/supply/data-quality', label: 'Datenpflege', icon: CheckSquare },
|
||||
{ path: '/supply/market-intelligence', label: 'Markt Intelligence', icon: Radar },
|
||||
{ path: '/supply/new-listing', label: 'Neues Inserat', icon: Plus },
|
||||
],
|
||||
},
|
||||
[WorkspaceType.DEMAND]: {
|
||||
|
||||
@@ -13,6 +13,7 @@ interface Props {
|
||||
|
||||
export function SourceProvenancePanel({ property }: Props) {
|
||||
if (!property) return null
|
||||
if (property.sourceType === 'DIRECT' || property.sourceMeta?.sourceType === 'DIRECT') return null
|
||||
|
||||
const freshness = property.dataQuality?.freshness
|
||||
const freshnessMeta = freshness ? (FRESHNESS_META[freshness] ?? null) : null
|
||||
|
||||
@@ -106,6 +106,7 @@ function MatchPill({ m }: { m: UnitNeedMatch }) {
|
||||
}
|
||||
|
||||
function UnitStructurePanel({ p }: { p: Property }) {
|
||||
const navigate = useNavigate()
|
||||
const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set())
|
||||
const [expandedUnit, setExpandedUnit] = useState<string | null>(null)
|
||||
|
||||
@@ -204,6 +205,28 @@ function UnitStructurePanel({ p }: { p: Property }) {
|
||||
{u.isFlexible && (
|
||||
<Chip label="Teilfläche möglich" size="small" sx={{ height: 16, fontSize: '0.58rem', bgcolor: '#eff6ff', color: '#1d4ed8', border: '1px solid #bfdbfe' }} />
|
||||
)}
|
||||
<Button
|
||||
size="small"
|
||||
variant="text"
|
||||
sx={{ height: 16, fontSize: '0.58rem', p: 0, minWidth: 0, color: '#7c3aed', textTransform: 'none', lineHeight: 1 }}
|
||||
onClick={() => navigate('/supply/new-listing', {
|
||||
state: {
|
||||
prefill: {
|
||||
assetType: p.assetType,
|
||||
street: p.address?.street,
|
||||
houseNumber: p.address?.houseNumber,
|
||||
postalCode: p.address?.postalCode,
|
||||
city: p.address?.city,
|
||||
areaSqm: u.offeredSqm ?? u.areaSqm,
|
||||
rentPricePerSqm: u.rentPricePerSqm ?? p.rentPricePerSqm,
|
||||
unitLabel: u.unitLabel,
|
||||
propertyId: p.id,
|
||||
},
|
||||
},
|
||||
})}
|
||||
>
|
||||
+ Inserat
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<Typography variant="caption" sx={{ color: '#64748b' }} noWrap>{u.currentTenant ?? 'Vermietet'}</Typography>
|
||||
|
||||
Reference in New Issue
Block a user