Implement code changes to enhance functionality and improve performance

This commit is contained in:
sha
2025-06-20 16:51:16 +03:00
parent 0546a2f72e
commit 552219d247
3 changed files with 630 additions and 594 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

+119 -83
View File
@@ -1,8 +1,16 @@
<script>
import { onMount } from 'svelte';
import { language } from '../stores.js';
import { t } from '../translations.js';
import { TrendingUp, Building2, TreePine, ShoppingCart, Truck, Users, ExternalLink } from 'lucide-svelte';
import { onMount } from "svelte";
import { language } from "../stores.js";
import { t } from "../translations.js";
import {
TrendingUp,
Building2,
TreePine,
ShoppingCart,
Truck,
Users,
ExternalLink,
} from "lucide-svelte";
let mounted = false;
@@ -10,83 +18,86 @@
mounted = true;
// Intersection Observer for scroll animations
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-in');
entry.target.classList.add("animate-in");
}
});
}, {
},
{
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
});
rootMargin: "0px 0px -50px 0px",
},
);
const sections = document.querySelectorAll('.scroll-animate');
sections.forEach(section => observer.observe(section));
const sections = document.querySelectorAll(".scroll-animate");
sections.forEach((section) => observer.observe(section));
return () => {
sections.forEach(section => observer.unobserve(section));
sections.forEach((section) => observer.unobserve(section));
};
});
const investmentAreas = [
{
icon: TrendingUp,
titleKey: 'energy',
descKey: 'energy_desc',
color: '#059669',
backgroundImage: '/energy-background.jpg'
titleKey: "energy",
descKey: "energy_desc",
color: "#059669",
backgroundImage: "/energy-background.jpg",
},
{
icon: TreePine,
titleKey: 'woodworking',
descKey: 'woodworking_desc',
color: '#7c3aed'
titleKey: "woodworking",
descKey: "woodworking_desc",
color: "#7c3aed",
},
{
icon: ShoppingCart,
titleKey: 'retail',
descKey: 'retail_desc',
color: '#dc2626',
backgroundImage: '/retail-background.jpg'
titleKey: "retail",
descKey: "retail_desc",
color: "#dc2626",
backgroundImage: "/retail-background.jpg",
},
{
icon: Truck,
titleKey: 'wholesale',
descKey: 'wholesale_desc',
color: '#4f46e5'
titleKey: "wholesale",
descKey: "wholesale_desc",
color: "#4f46e5",
},
{
icon: Building2,
titleKey: 'real_estate',
descKey: 'real_estate_desc',
color: '#d97706',
backgroundImage: '/office-background.jpg'
}
titleKey: "real_estate",
descKey: "real_estate_desc",
color: "#d97706",
backgroundImage: "/office-background.jpg",
},
];
const linkUrls = {
energy: 'https://hirsky.windpark.com.ua',
woodworking: 'https://www.slavforest.com.ua/',
retail: 'https://silpo.ua/'
energy: "https://hirsky.windpark.com.ua",
woodworking: "https://www.slavforest.com.ua/",
retail: "https://silpo.ua/",
};
function renderTextWithLinks(text, areaKey) {
if (!text.includes('{link}')) {
if (!text.includes("{link}")) {
return text;
}
return text.split('{link}').map((part, index) => {
return text.split("{link}").map((part, index) => {
if (index === 0) return part;
const [linkText, ...rest] = part.split('{/link}');
const afterLink = rest.join('{/link}');
const [linkText, ...rest] = part.split("{/link}");
const afterLink = rest.join("{/link}");
return {
beforeLink: '',
beforeLink: "",
linkText: linkText,
afterLink: afterLink,
url: linkUrls[areaKey]
url: linkUrls[areaKey],
};
});
}
@@ -98,7 +109,7 @@
<div class="container">
<div class="hero-content">
<h1 class="hero-title">
{t('company_name', $language)}
{t("company_name", $language)}
</h1>
</div>
</div>
@@ -108,7 +119,7 @@
<section class="nav-section scroll-animate">
<div class="container">
<div class="nav-value">
<strong>{t('nav_value', $language)}</strong>
<strong>{t("nav_value", $language)}</strong>
</div>
</div>
</section>
@@ -117,7 +128,7 @@
<section class="description-section scroll-animate">
<div class="container">
<p class="description-text">
{t('description', $language)}
{t("description", $language)}
</p>
</div>
</section>
@@ -127,19 +138,31 @@
<div class="container">
<div class="areas-grid">
{#each investmentAreas as area, index}
<div class="area-card"
<div
class="area-card"
class:has-background={area.backgroundImage}
style="--delay: {index * 0.1}s; {area.backgroundImage ? `--bg-image: url('${area.backgroundImage}')` : ''}">
<div class="area-icon" style="--icon-color: {area.color}">
style="--delay: {index * 0.1}s; {area.backgroundImage
? `--bg-image: url('${area.backgroundImage}')`
: ''}"
>
<div
class="area-icon"
style="--icon-color: {area.color}"
>
<svelte:component this={area.icon} size={32} />
</div>
<h3>{t(area.titleKey, $language)}</h3>
<p>
{#each renderTextWithLinks(t(area.descKey, $language), area.titleKey) as part}
{#if typeof part === 'string'}
{#if typeof part === "string"}
{part}
{:else}
{part.beforeLink}<a href={part.url} target="_blank" rel="noopener noreferrer" class="external-link">
{part.beforeLink}<a
href={part.url}
target="_blank"
rel="noopener noreferrer"
class="external-link"
>
{part.linkText}
<ExternalLink size={14} />
</a>{part.afterLink}
@@ -155,17 +178,17 @@
<!-- Mission & Vision -->
<section class="mission-vision scroll-animate">
<div class="container">
<h2 class="section-title">{t('mission_title', $language)}</h2>
<h2 class="section-title">{t("mission_title", $language)}</h2>
<div class="mv-grid">
<div class="mv-card">
<h3>{t('mission', $language)}</h3>
<p>{t('mission_desc', $language)}</p>
<h3>{t("mission", $language)}</h3>
<p>{t("mission_desc", $language)}</p>
</div>
<div class="mv-card">
<h3>{t('vision', $language)}</h3>
<p>{t('vision_desc', $language)}</p>
<h3>{t("vision", $language)}</h3>
<p>{t("vision_desc", $language)}</p>
</div>
</div>
</div>
@@ -174,16 +197,16 @@
<!-- Team -->
<section class="team scroll-animate">
<div class="container">
<h2 class="section-title">{t('team_title', $language)}</h2>
<p class="team-description">{t('team_desc', $language)}</p>
<h2 class="section-title">{t("team_title", $language)}</h2>
<p class="team-description">{t("team_desc", $language)}</p>
<div class="team-card">
<div class="team-icon">
<Users size={32} />
</div>
<div class="team-info">
<h4>{t('fund_manager', $language)}</h4>
<p>{t('manager_name', $language)}</p>
<h4>{t("fund_manager", $language)}</h4>
<p>{t("manager_name", $language)}</p>
</div>
</div>
</div>
@@ -192,35 +215,35 @@
<!-- Partners -->
<section class="partners scroll-animate">
<div class="container">
<h2 class="section-title">{t('partners_title', $language)}</h2>
<h2 class="section-title">{t("partners_title", $language)}</h2>
<div class="partners-grid">
<div class="partner-card">
<h4>{t('auditing_firm', $language)}</h4>
<p><strong>{t('auditing_name', $language)}</strong></p>
<p>{t('auditing_address', $language)}</p>
<p>{t('auditing_code', $language)}</p>
<h4>{t("auditing_firm", $language)}</h4>
<p><strong>{t("auditing_name", $language)}</strong></p>
<p>{t("auditing_address", $language)}</p>
<p>{t("auditing_code", $language)}</p>
</div>
<div class="partner-card">
<h4>{t('depository', $language)}</h4>
<p><strong>{t('depository_name', $language)}</strong></p>
<p>{t('depository_address', $language)}</p>
<p>{t('depository_code', $language)}</p>
<h4>{t("depository", $language)}</h4>
<p><strong>{t("depository_name", $language)}</strong></p>
<p>{t("depository_address", $language)}</p>
<p>{t("depository_code", $language)}</p>
</div>
<div class="partner-card">
<h4>{t('custodian', $language)}</h4>
<p><strong>{t('custodian_name', $language)}</strong></p>
<p>{t('custodian_address', $language)}</p>
<p>{t('custodian_code', $language)}</p>
<h4>{t("custodian", $language)}</h4>
<p><strong>{t("custodian_name", $language)}</strong></p>
<p>{t("custodian_address", $language)}</p>
<p>{t("custodian_code", $language)}</p>
</div>
<div class="partner-card">
<h4>{t('valuer', $language)}</h4>
<p><strong>{t('valuer_name', $language)}</strong></p>
<p>{t('valuer_address', $language)}</p>
<p>{t('valuer_code', $language)}</p>
<h4>{t("valuer", $language)}</h4>
<p><strong>{t("valuer_name", $language)}</strong></p>
<p>{t("valuer_address", $language)}</p>
<p>{t("valuer_code", $language)}</p>
</div>
</div>
</div>
@@ -258,28 +281,35 @@
/* Hero Section */
.hero {
padding: 6rem 0;
background-image: url('/hero-background.svg');
background-image: url("/hero-background.jpg");
background-size: cover;
background-position: center;
background-repeat: no-repeat;
position: relative;
min-height: 500px;
display: flex;
align-items: center;
align-items: start;
text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.8);
}
:global([data-theme="dark"]) .hero {
background-image: url('/hero-background-dark.svg');
/* background-image: url('/hero-background-dark.svg'); */
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
}
.hero::before {
content: '';
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, var(--bg-color) 0%, transparent 50%, var(--bg-secondary) 100%);
background: linear-gradient(
135deg,
var(--bg-color) 0%,
transparent 50%,
var(--bg-secondary) 100%
);
opacity: 0.8;
z-index: 1;
}
@@ -308,14 +338,20 @@
.nav-value {
text-align: center;
padding: 2rem;
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-hover) 100%);
background: linear-gradient(
135deg,
var(--primary-color) 0%,
var(--primary-hover) 100%
);
border-radius: 1rem;
font-size: 1.25rem;
color: white;
max-width: 700px;
margin: 0 auto;
box-shadow: var(--shadow);
transition: transform 0.3s ease, box-shadow 0.3s ease;
transition:
transform 0.3s ease,
box-shadow 0.3s ease;
}
.nav-value:hover {
@@ -375,7 +411,7 @@
}
.area-card.has-background::before {
content: '';
content: "";
position: absolute;
top: 0;
left: 0;
+3 -3
View File
@@ -22,7 +22,7 @@ export const translations = {
team_title: 'Team',
team_desc: 'Key persons responsible for the Fund\'s operations:',
fund_manager: 'Fund Manager:',
manager_name: 'Oleksandr Viktorovych Svynar — an experienced finance and investment manager responsible for the overall strategy and asset management.',
manager_name: 'Oleksandr Svynar — an experienced finance and investment manager responsible for the overall strategy and asset management.',
partners_title: 'Fund Partners',
auditing_firm: 'Auditing firm:',
auditing_name: 'LLC "AUDITING CENTER "INFORM-PLUS"',
@@ -41,7 +41,7 @@ export const translations = {
valuer_address: 'Kyiv, 25 Lva Tolstoho St.',
valuer_code: 'EDRPOU Code: 34289017',
contact_title: 'Contact Information',
manager_title: 'Oleksandr Viktorovych Svynar',
manager_title: 'Oleksandr Svynar',
office_address: 'Office Address:',
address: '01033, Ukraine, Kyiv, 48, 50A Zhylianska St., Office 13',
phone: 'Phone: +38 050 465 46 18'
@@ -88,7 +88,7 @@ export const translations = {
valuer_address: 'м. Київ, вул. Льва Толстого, 25',
valuer_code: 'Код ЄДРПОУ: 34289017',
contact_title: 'Контактна інформація',
manager_title: 'Свинар Олександр Вікторович',
manager_title: 'Свинар Олександр',
office_address: 'Адреса офісу:',
address: '01033, Україна, м. Київ, вул. Жилянська, 48, 50А, офіс 13',
phone: 'Телефон: +38 050 465 46 18'