@extends('admin.layouts.app')
@php
$locale = app()->getLocale();
$nameField = $locale === 'ar' ? 'name_ar' : 'name_en';
$dash = __('admin.startups_admin.unknown') ?: '—';
$optName = function ($option) use ($nameField, $dash) {
if (! $option) return $dash;
return $option->{$nameField} ?: ($option->name_en ?? $dash);
};
$sar = function ($v) use ($dash) {
if ($v === null || $v === '' || (is_numeric($v) && (float) $v === 0.0)) return $dash;
return number_format((float) $v, 2) . ' SAR';
};
$sarCompact = function ($v) use ($dash) {
$n = (float) ($v ?? 0);
if ($n <= 0) return $dash;
if ($n >= 1_000_000_000) return rtrim(rtrim(number_format($n / 1_000_000_000, 1), '0'), '.') . 'B';
if ($n >= 1_000_000) return rtrim(rtrim(number_format($n / 1_000_000, 1), '0'), '.') . 'M';
if ($n >= 1_000) return rtrim(rtrim(number_format($n / 1_000, 1), '0'), '.') . 'K';
return number_format($n, 0);
};
$int = fn ($v) => ($v === null || $v === '') ? $dash : number_format((int) $v);
$pct = function ($v) use ($dash) {
if ($v === null || $v === '') return $dash;
return rtrim(rtrim(number_format((float) $v, 2), '0'), '.') . '%';
};
$text = fn ($v) => ($v === null || $v === '') ? $dash : $v;
$has = fn ($v) => $v !== null && $v !== '' && (! is_numeric($v) || (float) $v !== 0.0);
/**
* Valuation comes from Monday's formula column — it could be:
* - a plain numeric string like "12000000.00"
* - a numeric-with-suffix like "12M" (already compact)
* - free text the user typed in Monday
* We strip everything except digits + the first decimal point, then
* if it parses to a positive number we compact it (`12M`, `1.5M`, …).
* Otherwise return the original string verbatim so a hand-typed
* valuation note still renders unchanged.
*/
$valuationCompact = function ($v) use ($dash) {
if ($v === null || $v === '') return $dash;
$clean = preg_replace('/[^0-9.]/', '', (string) $v);
// Collapse multiple dots; keep only the first.
if (substr_count((string) $clean, '.') > 1) {
$parts = explode('.', (string) $clean, 2);
$clean = $parts[0] . '.' . str_replace('.', '', $parts[1]);
}
if ($clean === '' || $clean === '.') return $v;
$n = (float) $clean;
if ($n <= 0) return $v;
if ($n >= 1_000_000_000) return rtrim(rtrim(number_format($n / 1_000_000_000, 1), '0'), '.') . 'B';
if ($n >= 1_000_000) return rtrim(rtrim(number_format($n / 1_000_000, 1), '0'), '.') . 'M';
if ($n >= 1_000) return rtrim(rtrim(number_format($n / 1_000, 1), '0'), '.') . 'K';
return number_format($n, 0);
};
/**
* Post-Money Valuation with lazy computation (added 2026-06-15).
*
* 1. If `valuation` is filled — return it verbatim (admin may have
* written a manual override that the formula can't reproduce,
* e.g. a Monday-imported display string like "$10M-$50M").
* 2. Otherwise compute `asking_fund_sar / (offered_equity_pct / 100)`
* whenever both inputs are present and positive. This is the SAME
* formula the model's saving() hook + StartupResource use, so the
* view, the API surface, and the next-save persistence all agree.
* 3. Returns null when neither path resolves — let the caller decide
* whether to hide the field or render an em-dash.
*/
$postMoneyValuation = function () use ($startup): ?string {
if ($startup->valuation !== null && $startup->valuation !== '') {
return (string) $startup->valuation;
}
$ask = (float) $startup->asking_fund_sar;
$eq = (float) $startup->offered_equity_pct;
if ($ask > 0 && $eq > 0) {
return number_format($ask / ($eq / 100.0), 2, '.', '');
}
return null;
};
$bytes = function ($n) {
if (! $n) return '—';
$units = ['B','KB','MB','GB'];
$i = 0; $n = (float) $n;
while ($n >= 1024 && $i < count($units) - 1) { $n /= 1024; $i++; }
return number_format($n, $n < 10 ? 1 : 0) . ' ' . $units[$i];
};
$initials = collect(explode(' ', trim((string) $startup->display_name)))
->filter()->take(2)
->map(fn ($p) => mb_strtoupper(mb_substr($p, 0, 1)))
->implode('');
if ($initials === '') $initials = '—';
// Hero avatar: prefer the file explicitly tagged slot='logo' so an
// "other"-slot image never gets mistaken for the company logo. Falls
// back to any image file for legacy rows whose slot was never set
// (pre-2026-06-17 signups / Monday imports — the backfill migration
// also repairs most of those).
$logoFile = $startup->files->firstWhere('slot', 'logo')
?? $startup->files->firstWhere('file_type', \App\Models\File::TYPE_IMAGE);
$logoUrl = $logoFile ? route('admin.files.show', $logoFile) : null;
// Generic Files section = signup-time uploads (logo, pitch deck) +
// any miscellaneous `other` + Monday-synced rows that pre-date the
// slot column (slot=null). Initial DD files (slot=initial_dd) are
// partitioned off to the dedicated section below so a single file
// never appears in both lanes.
//
// 2026-06-17: `slot=null` rows are now included. The rendering code
// already treated them as "other" via `$slot = $file->slot ?: 'other'`
// — but the upstream filter was dropping them, which silently hid
// Monday-imported files on the show page.
$files = $startup->files
->filter(fn ($f) => $f->slot === null || in_array($f->slot, ['logo', 'pitch_deck', 'other'], true))
->values();
$countryName = $startup->country?->{$nameField} ?: $startup->country?->name_en ?: $dash;
$pitchBlocks = array_filter([
'startup_brief' => $startup->startup_brief,
'problem' => $startup->problem,
'solution' => $startup->solution,
'investment_opportunity' => $startup->investment_opportunity,
'kpi_targets' => $startup->kpi_targets,
], fn ($v) => filled($v));
$fundUse = [
'fund_use_operation_sar' => $startup->fund_use_operation_sar,
'fund_use_marketing_sar' => $startup->fund_use_marketing_sar,
'fund_use_development_sar' => $startup->fund_use_development_sar,
'fund_use_salaries_sar' => $startup->fund_use_salaries_sar,
];
$totalFundUse = array_sum(array_map(fn ($v) => (float) $v, array_filter($fundUse, fn ($v) => $v !== null && $v !== '')));
@endphp
@section('title', $startup->display_name . ' — ' . __('admin.startups_admin.show_title'))
@section('page_title', __('admin.startups_admin.show_title'))
@push('styles')
@endpush
@section('content')
{{-- AI activity strip — renders nothing if Claude hasn't touched
this startup yet. Mirrors the investor show-page placement. --}}
@include('admin.ai._entity-badge', ['subject' => $startup])
{{--
{{ \Illuminate\Support\Str::limit($startup->startup_brief, 240) }}
@endif{{ $val }}
{{ __('admin.section_edit.empty_hint') }}
@endif{{ $text($startup->rejection_reason) }}
{{ $m->meeting_notes }}
@endif