First version
This commit is contained in:
45
ResumeBuilder/Main Elements/TitledCareerSection.swift
Normal file
45
ResumeBuilder/Main Elements/TitledCareerSection.swift
Normal file
@ -0,0 +1,45 @@
|
||||
import SwiftUI
|
||||
|
||||
struct TitledCareerSection: View {
|
||||
|
||||
let style: CVStyle.Section
|
||||
|
||||
let content: Titled<CareerStation>
|
||||
|
||||
var body: some View {
|
||||
TitledSection(title: content.title, spacing: style.titleSpacing) {
|
||||
ForEach(content.items) { item in
|
||||
CareerStationView(
|
||||
info: item,
|
||||
borderSpacing: style.borderSpacing,
|
||||
borderWidth: style.borderWidth)
|
||||
.padding(.bottom, style.bottomSpacing)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TitledItemSection_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
TitledCareerSection(
|
||||
style: .init(),
|
||||
content: .init(
|
||||
title: "Work experience",
|
||||
items: [
|
||||
.init(
|
||||
time: "Jul 2020 - Jul 2023",
|
||||
location: "Braunschweig, Germany",
|
||||
title: "German Aerospace Center",
|
||||
subtitle: "Systems engineer",
|
||||
text: "Responsible for aircraft systems and avionics of a high-altitude solar drone, safety, and software."),
|
||||
.init(
|
||||
time: "Jul 2020 - Jul 2023",
|
||||
location: "Braunschweig, Germany",
|
||||
title: "German Aerospace Center",
|
||||
subtitle: "Systems engineer",
|
||||
text: "Responsible for aircraft systems and avionics of a high-altitude solar drone, safety, and software.")
|
||||
])
|
||||
)
|
||||
.previewLayout(.fixed(width: 350, height: 400))
|
||||
}
|
||||
}
|
63
ResumeBuilder/Main Elements/TitledIconSection.swift
Normal file
63
ResumeBuilder/Main Elements/TitledIconSection.swift
Normal file
@ -0,0 +1,63 @@
|
||||
import SwiftUI
|
||||
|
||||
extension String: Identifiable {
|
||||
|
||||
public var id: String {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
extension View {
|
||||
public func addBorder<S>(_ content: S, width: CGFloat = 1, cornerRadius: CGFloat) -> some View where S : ShapeStyle {
|
||||
let roundedRect = RoundedRectangle(cornerRadius: cornerRadius)
|
||||
return clipShape(roundedRect)
|
||||
.overlay(roundedRect.strokeBorder(content, lineWidth: width))
|
||||
}
|
||||
}
|
||||
|
||||
struct TitledIconSection: View {
|
||||
|
||||
let content: Titled<SkillsSet>
|
||||
|
||||
let titleSpacing: CGFloat
|
||||
|
||||
let width: CGFloat
|
||||
|
||||
let style: SkillStyle
|
||||
|
||||
var body: some View {
|
||||
TitledSection(title: content.title, spacing: titleSpacing) {
|
||||
VStack(alignment: .leading) {
|
||||
ForEach(content.items) { item in
|
||||
HStack(alignment: .firstTextBaseline) {
|
||||
Image(systemSymbol: item.systemSymbol)
|
||||
.frame(
|
||||
width: style.iconSize,
|
||||
height: style.iconSize)
|
||||
.padding(.leading, style.horizontalGap)
|
||||
FlowLayout(alignment: .leading, spacing: style.verticalTagSpacing) {
|
||||
ForEach(item.entries) { tag in
|
||||
TagView(
|
||||
tag,
|
||||
rounding: style.tagRounding,
|
||||
color: style.tagBackground)
|
||||
}
|
||||
}
|
||||
}.padding(.bottom, style.rowSpacing)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TitledIconSection_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
TitledIconSection(
|
||||
content: .init(title: "Title", items: [
|
||||
.init(systemSymbol: .keyboard, entries: ["Swift", "C", "C++", "Python"])
|
||||
]),
|
||||
titleSpacing: 10,
|
||||
width: 200, style: SkillStyle())
|
||||
.previewLayout(.fixed(width: 230, height: 300))
|
||||
}
|
||||
}
|
32
ResumeBuilder/Main Elements/TitledTextSection.swift
Normal file
32
ResumeBuilder/Main Elements/TitledTextSection.swift
Normal file
@ -0,0 +1,32 @@
|
||||
import SwiftUI
|
||||
|
||||
struct TitledTextSection: View {
|
||||
|
||||
let content: Titled<String>
|
||||
|
||||
let titleSpacing: CGFloat
|
||||
|
||||
let paragraphSpacing: CGFloat
|
||||
|
||||
var body: some View {
|
||||
TitledSection(title: content.title, spacing: titleSpacing) {
|
||||
ForEach(content.items) { text in
|
||||
Text(text)
|
||||
.font(.body)
|
||||
.fontWeight(.light)
|
||||
.padding(.bottom, paragraphSpacing)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TitledTextSection_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
TitledTextSection(
|
||||
content: .init(
|
||||
title: "Title",
|
||||
items: ["Some longer or shorter text to explain some feature."]),
|
||||
titleSpacing: 10,
|
||||
paragraphSpacing: 5)
|
||||
}
|
||||
}
|
76
ResumeBuilder/Main Elements/TopView.swift
Normal file
76
ResumeBuilder/Main Elements/TopView.swift
Normal file
@ -0,0 +1,76 @@
|
||||
import SwiftUI
|
||||
import SFSafeSymbols
|
||||
|
||||
struct TopView: View {
|
||||
|
||||
let info: TopInfo
|
||||
|
||||
let style: HeaderStyle
|
||||
|
||||
var body: some View {
|
||||
GeometryReader { geo in
|
||||
let sideWidth = max(0, (geo.size.width - geo.size.height) / 2)
|
||||
HStack(spacing: 0) {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text(info.name)
|
||||
.font(.title)
|
||||
.foregroundColor(.accentColor)
|
||||
Spacer(minLength: 0)
|
||||
Text(info.tagLine)
|
||||
.font(.subheadline)
|
||||
.padding(.trailing, style.imageShadowSize)
|
||||
Spacer(minLength: 0)
|
||||
HStack {
|
||||
RightImageLabel(info.place, systemSymbol: .house)
|
||||
.padding(.leading, -4)
|
||||
RightImageLabel(info.ageText, systemSymbol: .hourglass)
|
||||
}.font(.subheadline)
|
||||
}
|
||||
.frame(width: sideWidth)
|
||||
TopViewImage(
|
||||
image: info.imageName,
|
||||
shadow: style.imageShadowSize,
|
||||
lineWidth: style.imageBorderWidth)
|
||||
VStack(alignment: .trailing) {
|
||||
LeftImageLabel(info.web, systemSymbol: .globe)
|
||||
.frame(maxHeight: style.iconHeight)
|
||||
Spacer()
|
||||
LeftImageLabel(info.email, systemSymbol: .envelope)
|
||||
.frame(maxHeight: style.iconHeight)
|
||||
Spacer()
|
||||
LeftImageLabel(info.phone, systemSymbol: .phone)
|
||||
.frame(maxHeight: style.iconHeight)
|
||||
Spacer()
|
||||
HStack(spacing: 0) {
|
||||
Spacer()
|
||||
Text(info.github)
|
||||
Image("Github")
|
||||
.resizable()
|
||||
.aspectRatio(1.0, contentMode: .fit)
|
||||
.padding(2)
|
||||
.frame(width: style.iconHeight)
|
||||
}.frame(maxHeight: style.iconHeight)
|
||||
}
|
||||
.font(.subheadline)
|
||||
.frame(width: sideWidth)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TopView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
TopView(info: .init(
|
||||
imageName: "Cover",
|
||||
name: "Christoph Hagen",
|
||||
tagLine: "Problem solver and creative mind with a favour for interdisciplinary work.",
|
||||
place: "Würzburg, Germany",
|
||||
ageText: "Age 32",
|
||||
web: "christophhagen.de",
|
||||
email: "jobs@christophhagen.de",
|
||||
phone: "Upon Request",
|
||||
github: "github.com/christophhagen"),
|
||||
style: HeaderStyle())
|
||||
.previewLayout(.fixed(width: 540, height: 120))
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user