2023-08-18 22:47:24 +02:00
|
|
|
import SwiftUI
|
|
|
|
|
|
|
|
struct CV: View {
|
2023-09-19 14:50:20 +02:00
|
|
|
|
|
|
|
@Environment(\.colorScheme)
|
|
|
|
var colorScheme: ColorScheme
|
2023-08-18 22:47:24 +02:00
|
|
|
|
|
|
|
let info: CVInfo
|
|
|
|
|
|
|
|
let style: CVStyle
|
|
|
|
|
|
|
|
private var twoColumnSpacing: CGFloat {
|
|
|
|
style.columnSpacing
|
|
|
|
}
|
|
|
|
|
|
|
|
var body: some View {
|
2023-08-20 13:11:13 +02:00
|
|
|
VStack {
|
2023-08-23 16:17:34 +02:00
|
|
|
TopView(
|
|
|
|
info: info.top,
|
|
|
|
style: style.header,
|
|
|
|
accent: style.accentColor)
|
2023-08-18 22:47:24 +02:00
|
|
|
.frame(height: style.header.height)
|
|
|
|
Rectangle()
|
2023-08-23 16:17:34 +02:00
|
|
|
.fill(style.accentColor)
|
2023-08-18 22:47:24 +02:00
|
|
|
.frame(height: style.header.lineWidth)
|
|
|
|
GeometryReader { geo in
|
|
|
|
let columnWidth = max(0, (geo.size.width - twoColumnSpacing)) / 2
|
|
|
|
HStack(alignment: .top, spacing: twoColumnSpacing) {
|
|
|
|
VStack(alignment: .leading) {
|
|
|
|
TitledCareerSection(
|
|
|
|
style: style.section,
|
2023-08-23 16:17:34 +02:00
|
|
|
accent: style.accentColor,
|
2023-08-18 22:47:24 +02:00
|
|
|
content: info.work)
|
|
|
|
TitledCareerSection(
|
|
|
|
style: style.section,
|
2023-08-23 16:17:34 +02:00
|
|
|
accent: style.accentColor,
|
2023-08-18 22:47:24 +02:00
|
|
|
content: info.education)
|
|
|
|
}.frame(width: columnWidth)
|
|
|
|
VStack(alignment: .leading) {
|
|
|
|
TitledSection(
|
|
|
|
title: info.publications.title,
|
|
|
|
spacing: style.section.titleSpacing) {
|
|
|
|
ForEach(info.publications.items) { item in
|
|
|
|
PublicationView(
|
|
|
|
info: item,
|
|
|
|
borderSpacing: style.section.borderSpacing,
|
2023-08-23 16:17:34 +02:00
|
|
|
borderWidth: style.section.borderWidth,
|
|
|
|
accent: style.accentColor)
|
2023-08-18 22:47:24 +02:00
|
|
|
.padding(.bottom, style.section.bottomSpacing)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TitledIconSection(
|
|
|
|
content: info.skills,
|
|
|
|
titleSpacing: style.section.titleSpacing,
|
|
|
|
width: columnWidth,
|
|
|
|
style: style.skillStyle)
|
|
|
|
TitledTextSection(
|
|
|
|
content: info.about,
|
|
|
|
titleSpacing: style.section.titleSpacing,
|
|
|
|
paragraphSpacing: style.section.paragraphSpacing)
|
|
|
|
}.frame(width: columnWidth)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Spacer(minLength: 0)
|
2023-08-20 13:11:13 +02:00
|
|
|
Text(info.footer)
|
2023-08-18 22:47:24 +02:00
|
|
|
.font(.footnote)
|
2023-09-19 14:50:20 +02:00
|
|
|
.foregroundColor(colorScheme.secondaryColor)
|
2023-08-18 22:47:24 +02:00
|
|
|
}
|
|
|
|
.padding()
|
|
|
|
.aspectRatio(1 / sqrt(2), contentMode: .fit)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct CV_Previews: PreviewProvider {
|
|
|
|
static var previews: some View {
|
2023-08-20 13:11:13 +02:00
|
|
|
CV(info: cvInfoEnglish, style: cvStyle)
|
2023-08-18 22:47:24 +02:00
|
|
|
.previewLayout(.fixed(width: 600, height: 600 * sqrt(2)))
|
|
|
|
}
|
|
|
|
}
|