feat: show ZOPK project links on company profiles
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions

Companies matched to ZOPK projects (score >= 40) now see a green
"Zielony Okrąg Przemysłowy Kaszubia" section on their profile with:
- Project name, type icon, and link type badge
- AI-generated collaboration description explaining relevance
- Relevance score percentage
- Links to project detail pages
- Hover effects for interactivity

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-03-15 10:08:23 +01:00
parent 825d40e770
commit 140d70f3e8
2 changed files with 57 additions and 1 deletions

View File

@ -356,6 +356,20 @@ def company_detail(company_id):
for m in company_managers:
_ = m.name, m.email # force-load before session close
# ZOPK project links — powiązania z projektami ZOPK
zopk_links = []
try:
from database import ZOPKCompanyLink, ZOPKProject
zopk_links = db.query(ZOPKCompanyLink).join(ZOPKProject).filter(
ZOPKCompanyLink.company_id == company_id,
ZOPKCompanyLink.relevance_score >= 40
).order_by(ZOPKCompanyLink.relevance_score.desc()).all()
# Eager-load project data
for link in zopk_links:
_ = link.project.name, link.project.slug, link.project.project_type
except Exception:
pass
# For child brands — inherit NIP from parent for display/enrichment
effective_nip = company.nip
if not effective_nip and company.parent_company_id:
@ -385,7 +399,8 @@ def company_detail(company_id):
can_enrich=can_enrich,
can_edit_profile=can_edit_profile,
company_managers=company_managers,
is_admin=current_user.is_authenticated and current_user.is_admin
is_admin=current_user.is_authenticated and current_user.is_admin,
zopk_links=zopk_links
)
finally:
db.close()

View File

@ -1508,6 +1508,47 @@
</div>
{% endif %}
<!-- Powiązania z projektami ZOPK -->
{% if zopk_links %}
<div class="company-section" style="background: linear-gradient(135deg, #f0fdf4 0%, #ecfdf5 100%); border: 1px solid #bbf7d0;">
<h2 class="section-title" style="color: #059669;">Zielony Okr&#281;g Przemys&#322;owy Kaszubia</h2>
<p style="font-size: var(--font-size-sm); color: var(--text-secondary); margin-bottom: var(--spacing-md);">
Projekty strategiczne, w których ta firma może uczestniczyć jako dostawca lub partner
</p>
<div style="display: grid; gap: var(--spacing-md);">
{% for link in zopk_links %}
<a href="{{ url_for('public.zopk_project_detail', slug=link.project.slug) }}" style="display: flex; gap: var(--spacing-md); padding: var(--spacing-md); background: white; border-radius: var(--radius); border: 1px solid #d1fae5; text-decoration: none; color: inherit; transition: box-shadow 0.2s, transform 0.2s;"
onmouseover="this.style.boxShadow='0 4px 12px rgba(5,150,105,0.15)'; this.style.transform='translateY(-1px)';"
onmouseout="this.style.boxShadow='none'; this.style.transform='none';">
<div style="flex-shrink: 0; width: 48px; height: 48px; border-radius: var(--radius); display: flex; align-items: center; justify-content: center; font-size: 1.5rem;
{% if link.project.project_type == 'energy' %}background: #fef3c7;{% elif link.project.project_type == 'technology' %}background: #dbeafe;{% elif link.project.project_type == 'defense' %}background: #fce7f3;{% else %}background: #f3f4f6;{% endif %}">
{% if link.project.project_type == 'energy' %}⚡{% elif link.project.project_type == 'technology' %}💻{% elif link.project.project_type == 'defense' %}🛡️{% else %}🏗️{% endif %}
</div>
<div style="flex: 1; min-width: 0;">
<div style="display: flex; align-items: center; gap: var(--spacing-sm); margin-bottom: 4px;">
<strong style="color: var(--text-primary);">{{ link.project.name }}</strong>
<span style="font-size: 11px; padding: 1px 8px; border-radius: 4px; background: #d1fae5; color: #065f46; font-weight: 600;">
{% if link.link_type == 'potential_supplier' %}potencjalny dostawca{% elif link.link_type == 'partner' %}partner{% elif link.link_type == 'beneficiary' %}beneficjent{% else %}{{ link.link_type }}{% endif %}
</span>
<span style="font-size: 11px; color: var(--text-muted); margin-left: auto;">trafność: {{ link.relevance_score }}%</span>
</div>
{% if link.collaboration_description %}
<p style="font-size: var(--font-size-sm); color: var(--text-secondary); margin: 0; line-height: 1.5;">
{{ link.collaboration_description }}
</p>
{% endif %}
</div>
</a>
{% endfor %}
</div>
<div style="text-align: center; margin-top: var(--spacing-md);">
<a href="{{ url_for('public.zopk_index') }}" style="font-size: var(--font-size-sm); color: #059669; text-decoration: none;">
Dowiedz się więcej o ZOPK &rarr;
</a>
</div>
</div>
{% endif %}
<!-- Osoby kontaktowe w firmie (portal users linked to company) -->
{% set _contacts_hidden = company.is_section_hidden('company_users') %}
{% if company_users and (not _contacts_hidden or can_edit_profile or is_admin) %}