Files
mahdium 2fc75eeab1 Sync upstream improvements: new components, layout overhaul, and portfolio enhancements
- Add Services, HireCTA, and ReactExpansion components
- Overhaul Hero with grid layout, badges, CTA buttons, email dialog, and profile card
- Refactor TopNav to use computed navItems loop
- Enhance ProjectsList with nested category accordions and case study details
- Restructure Skills with purpose-grouped stackGroups and row-sync accordion logic
- Add new types: Service, ReactExpansion, CTA, and Project case-study fields
- Update portfolio data with adapted services, stackGroups, and project details
- Add OG/Twitter meta tags for SEO
- Update i18n with new keys for services, hero, buttons, and project labels
- Fix langDir path, update engine constraints, add volta config
- Change default color scheme to lime
- Rename Rider to JetBrains Rider in AI stack
2026-07-06 18:28:26 +03:30

68 lines
2.7 KiB
Vue

<template>
<div class="mx-auto max-w-6xl pt-10 md:pt-20">
<Hero />
<!-- Below-the-fold sections rendered on server for SEO (SSR) -->
<Services />
<Skills />
<ReactExpansion />
<ProjectsList />
<WorkExperience />
<!-- <GitHubActivity username="mmahdium" /> -->
<AIStack />
<SoftSkills />
<LanguageSkills />
<EducationList />
<RecommendationsCarousel />
<HireCTA />
</div>
</template>
<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
import Hero from '@/components/portfolio/Hero.vue'
import { usePortfolio } from '@/composables/usePortfolio'
const Services = defineAsyncComponent(() => import('@/components/portfolio/Services.vue'))
const Skills = defineAsyncComponent(() => import('@/components/portfolio/Skills.vue'))
const ReactExpansion = defineAsyncComponent(() => import('@/components/portfolio/ReactExpansion.vue'))
const ProjectsList = defineAsyncComponent(() => import('@/components/portfolio/ProjectsList.vue'))
const WorkExperience = defineAsyncComponent(() => import('@/components/portfolio/WorkExperience.vue'))
const GitHubActivity = defineAsyncComponent(() => import('@/components/portfolio/GitHubActivity.vue'))
const AIStack = defineAsyncComponent(() => import('@/components/portfolio/AIStack.vue'))
const SoftSkills = defineAsyncComponent(() => import('@/components/portfolio/SoftSkills.vue'))
const LanguageSkills = defineAsyncComponent(() => import('@/components/portfolio/LanguageSkills.vue'))
const EducationList = defineAsyncComponent(() => import('@/components/portfolio/EducationList.vue'))
const RecommendationsCarousel = defineAsyncComponent(() => import('@/components/portfolio/RecommendationsCarousel.vue'))
const HireCTA = defineAsyncComponent(() => import('@/components/portfolio/HireCTA.vue'))
const portfolio = usePortfolio()
const { t, locale } = useI18n()
const siteTitle = computed(() => `${portfolio.value.profile.name} - ${t('meta.portfolioTitleSuffix')}`)
const description = computed(() =>
'Backend and DevOps engineer specializing in Go, .NET, infrastructure automation, observability, and system administration.'
)
const siteUrl = 'https://mahdium.ir'
useHead(() => ({
title: siteTitle.value,
link: [
{ rel: 'icon', type: 'image/svg+xml', href: '/favicon/favicon.png' },
],
}))
useSeoMeta({
title: () => siteTitle.value,
description: () => description.value,
ogTitle: () => siteTitle.value,
ogDescription: () => description.value,
ogUrl: siteUrl,
ogType: 'website',
ogLocale: () => (locale.value === 'fa' ? 'fa_IR' : 'en_US'),
twitterCard: 'summary_large_image',
twitterTitle: () => siteTitle.value,
twitterDescription: () => description.value,
})
</script>