import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; import { RouterLink } from '@angular/router'; import { PageShellComponent } from '../../core/layout/page-shell.component'; import { SeoService } from '../../core/services/seo.service'; import { MAIN_NAVIGATION, PAGE_INDEX } from '../../shared/config/navigation.config'; type ProfileValue = string | number | readonly string[]; type TokenClass = 'k' | 's' | 'n' | 'p'; interface TerminalToken { readonly cls: TokenClass; readonly text: string; } interface TerminalLine { readonly tokens: readonly TerminalToken[]; } /** The `profile.json` shown in the hero. Order is render order. */ const PROFILE: readonly (readonly [string, ProfileValue])[] = [ ['name', 'Amar Džanan'], ['role', 'Senior Full-Stack Engineer · Product Owner'], ['stack', ['.NET', 'Angular', 'Ionic', 'SQL Server']], ['focus', ['ERP & business systems', 'mobile', 'expert systems', 'safe AI integration']], ['since', 2018], ['location', 'Ljubljana · CET'], ['open_to', ['senior roles', 'consulting']] ]; function toTerminalLines(profile: readonly (readonly [string, ProfileValue])[]): TerminalLine[] { return profile.map(([key, value], index) => { const tokens: TerminalToken[] = [{ cls: 'k', text: `"${key}"` }, { cls: 'p', text: ': ' }]; if (typeof value === 'number') { tokens.push({ cls: 'n', text: String(value) }); } else if (typeof value === 'string') { tokens.push({ cls: 's', text: `"${value}"` }); } else { tokens.push({ cls: 'p', text: '[' }); value.forEach((item, itemIndex) => { if (itemIndex > 0) tokens.push({ cls: 'p', text: ', ' }); tokens.push({ cls: 's', text: `"${item}"` }); }); tokens.push({ cls: 'p', text: ']' }); } if (index < profile.length - 1) tokens.push({ cls: 'p', text: ',' }); return { tokens }; }); } @Component({ selector: 'app-landing-page', standalone: true, imports: [PageShellComponent, RouterLink], changeDetection: ChangeDetectionStrategy.OnPush, template: `

Senior full-stack engineer · product owner

Complex systems, understood before changed.

I build and modernize full-stack business systems — ERP software, offline-first mobile apps for the field, rule-driven expert systems — and connect them to AI through narrow, validated, verified interfaces. The kind you can run in production and sleep at night.

// index

ls ~/

{{ pages.length }} entries
@for (page of pages; track page.path) { {{ page.name }}

{{ page.description }}

}
` }) export class LandingPageComponent { readonly sections = MAIN_NAVIGATION; readonly pages = PAGE_INDEX; readonly terminalLines = toTerminalLines(PROFILE); constructor() { inject(SeoService).update({ title: 'Amar Džanan — Senior Software Engineer & AI Integration', description: 'Senior full-stack engineer building and modernizing ERP, mobile and expert systems — and connecting them safely to AI.', path: '/', structuredData: { '@context': 'https://schema.org', '@type': 'Person', name: 'Amar Džanan', url: 'https://dzanan.net/', email: 'mailto:amar@dzanan.net', jobTitle: 'Senior Software Engineer', sameAs: ['https://www.linkedin.com/in/amardzanan/'], address: { '@type': 'PostalAddress', addressLocality: 'Ljubljana', addressCountry: 'SI' }, knowsAbout: ['.NET', 'Angular', 'TypeScript', 'Ionic', 'ERP software', 'Expert systems', 'Software architecture', 'Model Context Protocol', 'AI integration'] } }); } }