@@ -5,10 +5,151 @@ import Elementary
5
5
import Foundation
6
6
7
7
public struct HomePage : Page {
8
+ @Dependency ( \. activityClient) private var activityClient
9
+
10
+ public init ( ) { }
11
+
12
+ private static let copyrightDateFormatter = {
13
+ let formatter = DateFormatter ( )
14
+ formatter. locale = Locale ( languageCode: . english, languageRegion: . unitedStates)
15
+ formatter. timeZone = TimeZone ( abbreviation: " PST " ) ?? formatter. timeZone
16
+ formatter. dateFormat = " yyyy "
17
+ return formatter
18
+ } ( )
19
+
20
+ let styling = Style ( )
21
+
22
+ public var content : some HTML {
23
+ HTMLRaw ( " <!DOCTYPE html> " )
24
+ html ( . lang( " en " ) , . custom( name: " data-theme " , value: " dark " ) ) {
25
+ head {
26
+ title { " Erik Bautista Santibanez " }
27
+ meta ( . charset( . utf8) )
28
+ meta ( name: . viewport, content: " width=device-width, initial-scale=1.0 " )
29
+ link ( . rel( . stylesheet) , . href( " https://cdnjs.cloudflare.com/ajax/libs/modern-normalize/3.0.1/modern-normalize.min.css " ) )
30
+ style ( self . styling)
31
+ script ( . src( " https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js " ) )
32
+ script ( . src( " https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/swift.min.js " ) )
33
+ script { HTMLRaw ( " hljs.highlightAll(); " ) }
34
+ VueScript ( )
35
+ }
36
+ body {
37
+ header ( . class( " hero " ) , . aria. label ( " About " ) ) {
38
+ hgroup {
39
+ h1 ( . class( " hero-title " ) ) { " Erik Bautista Santibanez " }
40
+ p ( . class( " hero-subtitle " ) ) { " Swift & Web Developer " }
41
+
42
+ let location = self . activityClient. location ( )
43
+ let residency = location? . residency ?? . default
44
+
45
+ p ( . class( " hero-location " ) ) {
46
+ span ( . aria. label ( " Residency " ) ) {
47
+ svg ( . xmlns( ) , . fill( " currentColor " ) , . viewBox( " 0 0 256 256 " ) , . class( " svg-icon " ) , . aria. label ( " Map pin icon " ) ) {
48
+ path (
49
+ . d( " M128,16a88.1,88.1,0,0,0-88,88c0,75.3,80,132.17,83.41,134.55a8,8,0,0,0,9.18,0C136,236.17,216,179.3,216,104A88.1,88.1,0,0,0,128,16Zm0,56a32,32,0,1,1-32,32A32,32,0,0,1,128,72Z " )
50
+ )
51
+ }
52
+ " \( residency) "
53
+ }
54
+
55
+ if let location, location. city != residency. city || location. state != residency. state {
56
+ " \u{2022} "
57
+
58
+ span ( . aria. label ( " Location " ) ) {
59
+ svg ( . xmlns( ) , . fill( " currentColor " ) , . viewBox( " 0 0 256 256 " ) , . class( " svg-icon reversed " ) , . aria. label ( " Navigation icon " ) ) {
60
+ path ( . d( " M234.35,129,152,152,129,234.35a8,8,0,0,1-15.21.27l-65.28-176A8,8,0,0,1,58.63,48.46l176,65.28A8,8,0,0,1,234.35,129Z " ) )
61
+ path ( . d( " M237.33,106.21,61.41,41l-.16-.05A16,16,0,0,0,40.9,61.25a1,1,0,0,0,.05.16l65.26,175.92A15.77,15.77,0,0,0,121.28,248h.3a15.77,15.77,0,0,0,15-11.29l.06-.2,21.84-78,78-21.84.2-.06a16,16,0,0,0,.62-30.38ZM149.84,144.3a8,8,0,0,0-5.54,5.54L121.3,232l-.06-.17L56,56l175.82,65.22.16.06Z " ) )
62
+ }
63
+
64
+ " Currently in "
65
+
66
+ b {
67
+ [ location. city, location. state, location. region == " United States " ? nil : location. region]
68
+ . compactMap ( \. self)
69
+ . joined ( separator: " , " )
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ main ( . v. scope ( " { selection: undefined } " ) ) {
77
+ header {
78
+ hgroup {
79
+ h2 { " Posts " }
80
+ ul ( . class( " post-tabs " ) ) {
81
+ for kind in Post . Kind? . allCases {
82
+ let value = if let kind {
83
+ " ' \( kind. rawValue) ' "
84
+ } else {
85
+ " undefined "
86
+ }
87
+ li {
88
+ button (
89
+ . v. on ( . click, " selection = \( value) " ) ,
90
+ . v. bind ( " aria-selected " , " selection == \( value) " ) ,
91
+ . aria. selected ( kind == nil )
92
+ ) {
93
+ kind? . tabTitle ?? " All "
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
100
+ section {
101
+ for post in Post . allCases {
102
+ article (
103
+ . class( " post " ) ,
104
+ . v. show ( " !selection || selection == ' \( post. kind. rawValue) ' " )
105
+ ) {
106
+ header { post. dateFormatted }
107
+ h3 ( . class( " post-title " ) ) { post. title }
108
+ div ( . class( " post-content " ) ) { post. content }
109
+ }
110
+ }
111
+ }
112
+ }
113
+ footer ( . aria. label ( " Credits " ) ) {
114
+ hr ( )
115
+ p { " © \( Self . copyrightDateFormatter. string ( from: Date . now) ) Erik Bautista Santibanez " }
116
+ p {
117
+ " Made with \u{2764} using "
118
+ a ( . target( . blank) , . rel( " noopener noreferrer " ) , . href( " https://swift.org " ) ) { " Swift " }
119
+ " + "
120
+ a ( . target( . blank) , . rel( " noopener noreferrer " ) , . href( " https://hummingbird.codes " ) ) { " Hummingbird " }
121
+ " . "
122
+ }
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+
129
+ extension HomePage {
8
130
struct Style : @unchecked Sendable , StyleSheet {
9
131
var body : some Rule {
10
132
// TODO: Add Work-Sans font?
11
133
134
+ // Reset components
135
+ " :root " => {
136
+ AnyProperty ( " line-height " , " 1.5 " )
137
+ }
138
+
139
+ " h1, h2, h3, h4, h5, figure, p, ol, ul, pre " => {
140
+ AnyProperty ( " margin " , " 0 " )
141
+ }
142
+
143
+ " ol[role= \" list \" ], ul[role= \" list \" ] " => {
144
+ AnyProperty ( " list-style " , " none " )
145
+ AnyProperty ( " padding-inline " , " 0 " )
146
+ }
147
+
148
+ Element ( . img) => {
149
+ AnyProperty ( " display " , " block " )
150
+ AnyProperty ( " max-inline-size " , " 100% " )
151
+ }
152
+
12
153
// General
13
154
Pseudo ( class: . root) => {
14
155
BackgroundColor ( " #1c1c1c " )
@@ -122,148 +263,4 @@ public struct HomePage: Page {
122
263
}
123
264
}
124
265
}
125
-
126
- @Dependency ( \. activityClient) private var activityClient
127
-
128
- public init ( ) { }
129
-
130
- private static let copyrightDateFormatter = {
131
- let formatter = DateFormatter ( )
132
- formatter. locale = Locale ( languageCode: . english, languageRegion: . unitedStates)
133
- formatter. timeZone = TimeZone ( abbreviation: " PST " ) ?? formatter. timeZone
134
- formatter. dateFormat = " yyyy "
135
- return formatter
136
- } ( )
137
-
138
- let styling = Style ( )
139
-
140
- public var content : some HTML {
141
- HTMLRaw ( " <!DOCTYPE html> " )
142
- html ( . lang( " en " ) , . custom( name: " data-theme " , value: " dark " ) ) {
143
- head {
144
- title { " Erik Bautista Santibanez " }
145
- meta ( . charset( . utf8) )
146
- meta ( name: . viewport, content: " width=device-width, initial-scale=1.0 " )
147
- link ( . rel( . stylesheet) , . href( " https://cdnjs.cloudflare.com/ajax/libs/modern-normalize/3.0.1/modern-normalize.min.css " ) )
148
- style {
149
- /// Reset stylesheet
150
- HTMLRaw (
151
- """
152
- :root {
153
- line-height: 1.5;
154
- }
155
- h1, h2, h3, h4, h5, figure, p, ol, ul, pre {
156
- margin: 0;
157
- }
158
- ol[role= " list " ], ul[role= " list " ] {
159
- list-style: none;
160
- padding-inline: 0;
161
- }
162
- img {
163
- display: block;
164
- max-inline-size: 100%;
165
- }
166
- """
167
- )
168
- }
169
- style ( self . styling)
170
- script ( . src( " https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js " ) )
171
- script ( . src( " https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/swift.min.js " ) )
172
- script { HTMLRaw ( " hljs.highlightAll(); " ) }
173
- VueScript ( )
174
- }
175
- body {
176
- header ( . class( " hero " ) , . ariaLabel( " About " ) ) {
177
- hgroup {
178
- h1 ( . class( " hero-title " ) ) { " Erik Bautista Santibanez " }
179
- p ( . class( " hero-subtitle " ) ) { " Swift & Web Developer " }
180
-
181
- let location = self . activityClient. location ( )
182
- let residency = location? . residency ?? . default
183
-
184
- p ( . class( " hero-location " ) ) {
185
- span ( . ariaLabel( " Residency " ) ) {
186
- svg ( . xmlns( ) , . fill( " currentColor " ) , . viewBox( " 0 0 256 256 " ) , . class( " svg-icon " ) , . ariaLabel( " Map pin icon " ) ) {
187
- path (
188
- . d( " M128,16a88.1,88.1,0,0,0-88,88c0,75.3,80,132.17,83.41,134.55a8,8,0,0,0,9.18,0C136,236.17,216,179.3,216,104A88.1,88.1,0,0,0,128,16Zm0,56a32,32,0,1,1-32,32A32,32,0,0,1,128,72Z " )
189
- )
190
- }
191
- " \( residency) "
192
- }
193
-
194
- if let location, location. city != residency. city || location. state != residency. state {
195
- " \u{2022} "
196
-
197
- span ( . ariaLabel( " Location " ) ) {
198
- svg ( . xmlns( ) , . fill( " currentColor " ) , . viewBox( " 0 0 256 256 " ) , . class( " svg-icon reversed " ) , . ariaLabel( " Navigation icon " ) ) {
199
- path ( . d( " M234.35,129,152,152,129,234.35a8,8,0,0,1-15.21.27l-65.28-176A8,8,0,0,1,58.63,48.46l176,65.28A8,8,0,0,1,234.35,129Z " ) )
200
- path ( . d( " M237.33,106.21,61.41,41l-.16-.05A16,16,0,0,0,40.9,61.25a1,1,0,0,0,.05.16l65.26,175.92A15.77,15.77,0,0,0,121.28,248h.3a15.77,15.77,0,0,0,15-11.29l.06-.2,21.84-78,78-21.84.2-.06a16,16,0,0,0,.62-30.38ZM149.84,144.3a8,8,0,0,0-5.54,5.54L121.3,232l-.06-.17L56,56l175.82,65.22.16.06Z " ) )
201
- }
202
-
203
- " Currently in "
204
-
205
- b {
206
- [ location. city, location. state, location. region == " United States " ? nil : location. region]
207
- . compactMap ( \. self)
208
- . joined ( separator: " , " )
209
- }
210
- }
211
- }
212
- }
213
- }
214
- }
215
- main ( . v. scope ( " { selection: undefined } " ) ) {
216
- header {
217
- hgroup {
218
- h2 { " Posts " }
219
- ul ( . class( " post-tabs " ) ) {
220
- for kind in Post . Kind? . allCases {
221
- let value = if let kind {
222
- " ' \( kind. rawValue) ' "
223
- } else {
224
- " undefined "
225
- }
226
- li {
227
- button (
228
- . v. on ( . click, " selection = \( value) " ) ,
229
- . v. bind ( " aria-selected " , " selection == \( value) " ) ,
230
- . ariaSelected( kind == nil )
231
- ) {
232
- kind? . tabTitle ?? " All "
233
- }
234
- }
235
- }
236
- }
237
- }
238
- // p { "Selected {{ selection }}" }
239
- }
240
- section {
241
- for post in Post . allCases {
242
- article (
243
- . class( " post " ) ,
244
- . v. show ( " !selection || selection == ' \( post. kind. rawValue) ' " )
245
- ) {
246
- header { post. dateFormatted }
247
- h3 ( . class( " post-title " ) ) { post. title }
248
- div ( . class( " post-content " ) ) {
249
- post. content
250
- }
251
- }
252
- }
253
- }
254
- }
255
- footer ( . ariaLabel( " Credits " ) ) {
256
- hr ( )
257
- p { " © \( Self . copyrightDateFormatter. string ( from: Date . now) ) Erik Bautista Santibanez " }
258
- p {
259
- " Made with \u{2764} using "
260
- a ( . target( . blank) , . rel( " noopener noreferrer " ) , . href( " https://swift.org " ) ) { " Swift " }
261
- " + "
262
- a ( . target( . blank) , . rel( " noopener noreferrer " ) , . href( " https://hummingbird.codes " ) ) { " Hummingbird " }
263
- " . "
264
- }
265
- }
266
- }
267
- }
268
- }
269
266
}
0 commit comments