Compare commits

...

11 Commits

Author SHA1 Message Date
Christoph Hagen
5bad3524cf Update Data.swift 2025-01-31 22:17:30 +01:00
Christoph Hagen
7471f06c52 Don't use links until bug is fixed 2023-12-05 14:47:52 +01:00
Christoph Hagen
828162ee36 Create .gitignore 2023-12-03 09:23:55 +01:00
Christoph Hagen
f1f770c859 Update city 2023-12-03 09:23:47 +01:00
Christoph Hagen
abf61463fe Fix button heights 2023-11-10 13:46:43 +01:00
Christoph Hagen
b0f2bdf430 Add links for email, phone and domain 2023-11-10 11:22:49 +01:00
Christoph Hagen
43a1789332 Fix wrong colors in PDF export 2023-09-19 14:50:20 +02:00
Christoph Hagen
d25c8e1207 Update data 2023-09-19 13:51:34 +02:00
Christoph Hagen
cbc1b51e78 Update roles 2023-08-24 15:34:46 +02:00
Christoph Hagen
f7987bd429 Add roadmap 2023-08-23 17:27:31 +02:00
Christoph Hagen
f38ca55e4c Update icon 2023-08-23 17:27:24 +02:00
38 changed files with 186 additions and 49 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.DS_Store

BIN
Icon.key

Binary file not shown.

View File

@@ -14,3 +14,6 @@ Problems:
- The `ImageRenderer` sometimes renders text in the wrong color (seems to be a bug).
- PDF exports are fairly large (> 2 MB) due to included fonts, which is a problem for some applications.
Next steps:
- Create HTML export to use for my website

View File

@@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
880A8C212AFE3B0C000ABBFA /* PhoneNumberKit in Frameworks */ = {isa = PBXBuildFile; productRef = 880A8C202AFE3B0C000ABBFA /* PhoneNumberKit */; };
886AD6452AB9CD9100B1A00D /* ColorScheme+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 886AD6442AB9CD9100B1A00D /* ColorScheme+Extensions.swift */; };
E267D1742A8E0DE80069112B /* ResumeBuilderApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E267D1732A8E0DE80069112B /* ResumeBuilderApp.swift */; };
E267D1762A8E0DE80069112B /* CV.swift in Sources */ = {isa = PBXBuildFile; fileRef = E267D1752A8E0DE80069112B /* CV.swift */; };
E267D1782A8E0DE90069112B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E267D1772A8E0DE90069112B /* Assets.xcassets */; };
@@ -41,6 +43,7 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
886AD6442AB9CD9100B1A00D /* ColorScheme+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ColorScheme+Extensions.swift"; sourceTree = "<group>"; };
E2329BB12A9651E200A1270E /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
E267D1702A8E0DE80069112B /* ResumeBuilder.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ResumeBuilder.app; sourceTree = BUILT_PRODUCTS_DIR; };
E267D1732A8E0DE80069112B /* ResumeBuilderApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResumeBuilderApp.swift; sourceTree = "<group>"; };
@@ -82,6 +85,7 @@
buildActionMask = 2147483647;
files = (
E267D1882A8E12D60069112B /* SFSafeSymbols in Frameworks */,
880A8C212AFE3B0C000ABBFA /* PhoneNumberKit in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -118,6 +122,7 @@
E267D17C2A8E0DE90069112B /* ResumeBuilder.entitlements */,
E267D1792A8E0DE90069112B /* Preview Content */,
E267D1822A8E0F320069112B /* Color+Extension.swift */,
886AD6442AB9CD9100B1A00D /* ColorScheme+Extensions.swift */,
E267D1932A8E38C60069112B /* Data.swift */,
E267D1A52A8EC34B0069112B /* Data */,
E267D1BE2A90095D0069112B /* Language */,
@@ -217,6 +222,7 @@
name = ResumeBuilder;
packageProductDependencies = (
E267D1872A8E12D60069112B /* SFSafeSymbols */,
880A8C202AFE3B0C000ABBFA /* PhoneNumberKit */,
);
productName = ResumeBuilder;
productReference = E267D1702A8E0DE80069112B /* ResumeBuilder.app */;
@@ -230,7 +236,7 @@
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1430;
LastUpgradeCheck = 1430;
LastUpgradeCheck = 1500;
TargetAttributes = {
E267D16F2A8E0DE80069112B = {
CreatedOnToolsVersion = 14.3.1;
@@ -248,6 +254,7 @@
mainGroup = E267D1672A8E0DE80069112B;
packageReferences = (
E267D1862A8E12D60069112B /* XCRemoteSwiftPackageReference "SFSafeSymbols" */,
880A8C1F2AFE3B0C000ABBFA /* XCRemoteSwiftPackageReference "PhoneNumberKit" */,
);
productRefGroup = E267D1712A8E0DE80069112B /* Products */;
projectDirPath = "";
@@ -295,6 +302,7 @@
E267D18C2A8E1A890069112B /* TopViewImage.swift in Sources */,
E267D19C2A8E45470069112B /* CareerStation.swift in Sources */,
E267D1BA2A8F9D9C0069112B /* SkillStyle.swift in Sources */,
886AD6452AB9CD9100B1A00D /* ColorScheme+Extensions.swift in Sources */,
E267D1AD2A8F694A0069112B /* PublicationView.swift in Sources */,
E267D1BC2A8FFF300069112B /* TagView.swift in Sources */,
E267D1A02A8E45620069112B /* CVInfo.swift in Sources */,
@@ -313,6 +321,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
@@ -342,9 +351,11 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@@ -373,6 +384,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
@@ -402,9 +414,11 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -431,6 +445,7 @@
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "\"ResumeBuilder/Preview Content\"";
DEVELOPMENT_TEAM = H8WR4M6QQ4;
ENABLE_HARDENED_RUNTIME = YES;
@@ -460,6 +475,7 @@
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "\"ResumeBuilder/Preview Content\"";
DEVELOPMENT_TEAM = H8WR4M6QQ4;
ENABLE_HARDENED_RUNTIME = YES;
@@ -504,6 +520,14 @@
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
880A8C1F2AFE3B0C000ABBFA /* XCRemoteSwiftPackageReference "PhoneNumberKit" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/marmelroy/PhoneNumberKit";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 3.7.4;
};
};
E267D1862A8E12D60069112B /* XCRemoteSwiftPackageReference "SFSafeSymbols" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/SFSafeSymbols/SFSafeSymbols";
@@ -515,6 +539,11 @@
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
880A8C202AFE3B0C000ABBFA /* PhoneNumberKit */ = {
isa = XCSwiftPackageProductDependency;
package = 880A8C1F2AFE3B0C000ABBFA /* XCRemoteSwiftPackageReference "PhoneNumberKit" */;
productName = PhoneNumberKit;
};
E267D1872A8E12D60069112B /* SFSafeSymbols */ = {
isa = XCSwiftPackageProductDependency;
package = E267D1862A8E12D60069112B /* XCRemoteSwiftPackageReference "SFSafeSymbols" */;

View File

@@ -1,5 +1,14 @@
{
"pins" : [
{
"identity" : "phonenumberkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/marmelroy/PhoneNumberKit",
"state" : {
"revision" : "b456f2f9be10c1d183158220b831afd22697dd68",
"version" : "3.7.4"
}
},
{
"identity" : "sfsafesymbols",
"kind" : "remoteSourceControl",

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>ResumeBuilder.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>

View File

@@ -1,61 +1,61 @@
{
"images" : [
{
"filename" : "icon 9.jpg",
"filename" : "icon 9.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"filename" : "icon 8.jpg",
"filename" : "icon 8.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"filename" : "icon 7.jpg",
"filename" : "icon 7.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"filename" : "icon 6.jpg",
"filename" : "icon 6.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"filename" : "icon 5.jpg",
"filename" : "icon 5.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"filename" : "icon 4.jpg",
"filename" : "icon 4.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"filename" : "icon 3.jpg",
"filename" : "icon 3.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"filename" : "icon 2.jpg",
"filename" : "icon 2.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"filename" : "icon 1.jpg",
"filename" : "icon 1.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"filename" : "icon.jpg",
"filename" : "icon.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 377 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

View File

@@ -2,6 +2,9 @@ import SwiftUI
struct CV: View {
@Environment(\.colorScheme)
var colorScheme: ColorScheme
let info: CVInfo
let style: CVStyle
@@ -61,7 +64,7 @@ struct CV: View {
Spacer(minLength: 0)
Text(info.footer)
.font(.footnote)
.foregroundColor(.secondary)
.foregroundColor(colorScheme.secondaryColor)
}
.padding()
.aspectRatio(1 / sqrt(2), contentMode: .fit)

View File

@@ -13,4 +13,20 @@ extension Color {
init(_ r: Double, _ g: Double, _ b: Double) {
self.init(red: r, green: g, blue: b)
}
static var lightSchemePrimaryColor: Color {
.init(r: 1, g: 1, b: 1)
}
static var darkSchemePrimaryColor: Color {
.init(r: 224, g: 224, b: 224)
}
static var lightSchemeSecondaryColor: Color {
.init(r: 128, g: 128, b: 128)
}
static var darkSchemeSecondaryColor: Color {
.init(r: 161, g: 161, b: 161)
}
}

View File

@@ -0,0 +1,13 @@
import Foundation
import SwiftUI
extension ColorScheme {
var primaryColor: Color {
self == .light ? .lightSchemePrimaryColor : .darkSchemePrimaryColor
}
var secondaryColor: Color {
self == .light ? .lightSchemeSecondaryColor : .darkSchemeSecondaryColor
}
}

View File

@@ -51,6 +51,7 @@ struct ContentView: View {
}) {
Label("Export", systemSymbol: .squareAndArrowDown)
.padding(3)
.frame(maxHeight: 20)
}.confirmationDialog(
"Which format would you like?",
isPresented: $showExportFormatPicker
@@ -65,6 +66,7 @@ struct ContentView: View {
Button(action: importData) {
Label("Import", systemSymbol: .docBadgePlus)
.padding(8)
.frame(maxHeight: 20)
}
Spacer()
Toggle("Dark mode", isOn: $darkModeEnabled)
@@ -205,7 +207,7 @@ struct ContentView: View {
private var renderContent: some View {
CV(info: info, style: style)
.frame(width: style.pageWidth, height: style.pageHeight)
.preferredColorScheme(.dark)
.preferredColorScheme(colorStyle)
}
@MainActor

View File

@@ -32,13 +32,19 @@ let cvInfoEnglish = CVInfo(
imageName: "Cover",
name: "Christoph Hagen",
tagLine: "Problem solver and creative mind with a favour for interdisciplinary work.",
place: "Würzburg, Germany",
ageText: "Age 32",
place: "Munich, Germany",
ageText: "Age 33",
web: "christophhagen.de",
email: "jobs@christophhagen.de",
phone: "Upon Request",
github: "github.com/christophhagen"),
work: .init(title: "Work experience", items: [
CareerStation(
time: "May 2024 - Present",
location: "Oberpfaffenhofen, Germany",
title: "German Aerospace Center",
subtitle: "Software Developer",
text: "Development of the mission control system of the LUNA moon simulator hall for robotic experiments and astronaut training."),
CareerStation(
time: "Jul 2020 - Jul 2023",
location: "Braunschweig, Germany",
@@ -57,12 +63,6 @@ let cvInfoEnglish = CVInfo(
title: "National Institute of Informatics",
subtitle: "Research Intern (Intelligent Robotics)",
text: "Topic: Concept Acquisition through interactions between Humans and Robots"),
CareerStation(
time: "Sep 2014 - Nov 2016",
location: "Würzburg, Germany",
title: "Julius-Maximilians-Universität",
subtitle: "Research & Teaching Assistant",
text: "Teaching exercises and robotics workshops, design of a modular robot arm connector.")
]),
education: .init(title: "Education", items: [
CareerStation(
@@ -124,13 +124,19 @@ let cvInfoGerman = CVInfo(
imageName: "Cover",
name: "Christoph Hagen",
tagLine: "Problemlöser und kreativer Kopf mit einer Vorliebe für interdisziplinäre Arbeit.",
place: "Würzburg",
ageText: "32 Jahre",
place: "München",
ageText: "33 Jahre",
web: "christophhagen.de",
email: "jobs@christophhagen.de",
phone: "Auf Anfrage",
github: "github.com/christophhagen"),
work: .init(title: "Berufserfahrung", items: [
CareerStation(
time: "Mai 2024 - Heute",
location: "Oberpfaffenhofen",
title: "Deutsches Zentrum für Luft- und Raumfahrt",
subtitle: "Softwareentwickler",
text: "Entwicklung des Missionskontrollsystems der LUNA Mondsimulationshalle für robotische Experimente und Astronautentraining."),
CareerStation(
time: "Jul 2020 - Jul 2023",
location: "Braunschweig",
@@ -147,14 +153,8 @@ let cvInfoGerman = CVInfo(
time: "Jul 2017 - Okt 2017",
location: "Tokio, Japan",
title: "National Institute of Informatics",
subtitle: "Research Intern (Intelligent Robotics)",
text: "Thema: Concept Acquisition through interactions between Humans and Robots"),
CareerStation(
time: "Sep 2014 - Nov 2016",
location: "Würzburg",
title: "Julius-Maximilians-Universität",
subtitle: "Research & Teaching Assistant",
text: "Leitung von Übungen und Robotikworkshops, Entwurf einer modularen Verbindung für einen Roboterarm.")
subtitle: "Praktikant (Intelligente Robotik)",
text: "Thema: Concept Acquisition through interactions between Humans and Robots")
]),
education: .init(title: "Bildung", items: [
CareerStation(

View File

@@ -3,6 +3,9 @@ import SFSafeSymbols
struct CareerStationView: View {
@Environment(\.colorScheme)
var colorScheme: ColorScheme
let info: CareerStation
let borderSpacing: CGFloat
@@ -20,7 +23,7 @@ struct CareerStationView: View {
RightImageLabel(info.location, systemSymbol: .house)
}
.font(.caption)
.foregroundColor(.secondary)
.foregroundColor(colorScheme.secondaryColor)
Text(info.title)
.font(.headline)
.fontWeight(.regular)
@@ -32,7 +35,7 @@ struct CareerStationView: View {
if let text = info.text {
Text(text)
.font(.caption)
.foregroundColor(.secondary)
.foregroundColor(colorScheme.secondaryColor)
}
}
}

View File

@@ -2,6 +2,9 @@ import SwiftUI
struct PublicationView: View {
@Environment(\.colorScheme)
var colorScheme: ColorScheme
let info: Publication
let borderSpacing: CGFloat
@@ -15,10 +18,11 @@ struct PublicationView: View {
VStack(alignment: .leading) {
Text(info.venue)
.font(.caption)
.foregroundColor(.secondary)
.foregroundColor(colorScheme.secondaryColor)
Text(info.title)
.font(.subheadline)
.fontWeight(.regular)
.foregroundColor(colorScheme.primaryColor)
}
}
}

View File

@@ -1,20 +1,20 @@
import SwiftUI
import SFSafeSymbols
struct LeftImageLabel: View {
let text: String
struct LeftImageLabel<Content>: View where Content: View {
let systemSymbol: SFSymbol
init(_ text: String, systemSymbol: SFSymbol) {
self.text = text
let content: Content
init(systemSymbol: SFSymbol, @ViewBuilder content: () -> Content) {
self.systemSymbol = systemSymbol
self.content = content()
}
var body: some View {
HStack(alignment: .firstTextBaseline, spacing: 0) {
Text(text)
HStack(alignment: .center, spacing: 0) {
content
Image(systemSymbol: systemSymbol)
.frame(width: 20)
}
@@ -23,6 +23,6 @@ struct LeftImageLabel: View {
struct LeftImageLabel_Previews: PreviewProvider {
static var previews: some View {
LeftImageLabel("Home address", systemSymbol: .house)
LeftImageLabel(systemSymbol: .house) { Text("Home address") }
}
}

View File

@@ -2,12 +2,19 @@ import SwiftUI
struct TitledTextSection: View {
@Environment(\.colorScheme)
var colorScheme: ColorScheme
let content: Titled<String>
let titleSpacing: CGFloat
let paragraphSpacing: CGFloat
private var textColor: Color {
colorScheme == .light ? .lightSchemePrimaryColor : .darkSchemePrimaryColor
}
var body: some View {
TitledSection(title: content.title, spacing: titleSpacing) {
ForEach(content.items) { text in
@@ -15,6 +22,7 @@ struct TitledTextSection: View {
.font(.body)
.fontWeight(.light)
.padding(.bottom, paragraphSpacing)
.foregroundColor(textColor)
}
}
}

View File

@@ -1,5 +1,8 @@
import SwiftUI
import SFSafeSymbols
import PhoneNumberKit
private let emailPattern = #"^\S+@\S+\.\S+$"#
struct TopView: View {
@@ -9,6 +12,21 @@ struct TopView: View {
let accent: Color
private let phoneNumberKit = PhoneNumberKit()
var isValidEmail: Bool {
info.email.range(of: emailPattern, options: .regularExpression) != nil
}
var isValidPhoneNumber: Bool {
do {
_ = try phoneNumberKit.parse(info.phone)
return true
} catch {
return false
}
}
var body: some View {
GeometryReader { geo in
let sideWidth = max(0, (geo.size.width - geo.size.height) / 2)
@@ -34,18 +52,30 @@ struct TopView: View {
shadow: style.imageShadowSize,
lineWidth: style.imageBorderWidth)
VStack(alignment: .trailing) {
LeftImageLabel(info.web, systemSymbol: .globe)
.frame(maxHeight: style.iconHeight)
LeftImageLabel(systemSymbol: .globe) {
Text(info.web)
//Link(info.web, destination: URL(string: "https://" + info.web)!)
}
.frame(maxHeight: style.iconHeight)
Spacer()
LeftImageLabel(info.email, systemSymbol: .envelope)
.frame(maxHeight: style.iconHeight)
LeftImageLabel(systemSymbol: .envelope) {
Text(info.email)
//Link(info.email, destination: URL(string: "mailto:" + info.email)!)
//.disabled(!isValidEmail)
}
.frame(maxHeight: style.iconHeight)
Spacer()
LeftImageLabel(info.phone, systemSymbol: .phone)
.frame(maxHeight: style.iconHeight)
LeftImageLabel(systemSymbol: .phone) {
Text(info.phone)
//Link(info.phone, destination: URL(string: "tel:" + info.phone)!)
//.disabled(!isValidPhoneNumber)
}
.frame(maxHeight: style.iconHeight)
Spacer()
HStack(spacing: 0) {
Spacer()
Text(info.github)
//Link(info.github, destination: URL(string: "https://" + info.github)!)
Image("Github")
.resizable()
.aspectRatio(1.0, contentMode: .fit)
@@ -55,6 +85,7 @@ struct TopView: View {
}
.font(.subheadline)
.frame(width: sideWidth)
.foregroundStyle(.primary)
}
}
}