Skip to content

Commit 6f89b76

Browse files
committed
Add location to contact page
1 parent 92661a5 commit 6f89b76

File tree

9 files changed

+202
-168
lines changed

9 files changed

+202
-168
lines changed

src/assets/map.png

1.36 MB
Loading

src/components/ContactForm.astro

Lines changed: 64 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const { t } = useI18n(Astro.url);
55
---
66

77
<section id="contact-section">
8+
<h2>{t("contact.form.title")}</h2>
9+
810
<div class="container">
911
<form
1012
class="contact-form"
@@ -55,64 +57,74 @@ const { t } = useI18n(Astro.url);
5557
</div>
5658
</form>
5759
</div>
58-
</section>
5960

60-
<style>
61-
#contact-section {
62-
padding: 4rem 2rem;
63-
max-width: 64rem;
64-
margin: 0 auto;
65-
}
61+
<style>
62+
#contact-section {
63+
padding: 2rem 2rem 4rem;
64+
max-width: 64rem;
65+
margin: 0 auto;
66+
}
67+
68+
.container {
69+
width: 100%;
70+
}
6671

67-
.container {
68-
width: 100%;
69-
}
72+
.contact-form {
73+
width: 100%;
74+
margin-top: 4rem;
75+
}
7076

71-
.contact-form {
72-
width: 100%;
73-
}
77+
.field {
78+
margin-bottom: 1.5rem;
79+
}
7480

75-
.field {
76-
margin-bottom: 1.5rem;
77-
}
81+
.input,
82+
.textarea {
83+
width: calc(100% - 2rem);
84+
padding: 1rem;
85+
font-size: 1rem;
86+
border: 1px solid #ddd;
87+
border-radius: 4px;
88+
font-family: var(--font-lato);
89+
transition: border-color 0.3s ease;
90+
}
7891

79-
.input,
80-
.textarea {
81-
width: calc(100% - 2rem);
82-
padding: 1rem;
83-
font-size: 1rem;
84-
border: 1px solid #ddd;
85-
border-radius: 4px;
86-
font-family: var(--font-lato);
87-
transition: border-color 0.3s ease;
88-
}
92+
.input:focus,
93+
.textarea:focus {
94+
outline: none;
95+
border-color: var(--color-primary);
96+
}
8997

90-
.input:focus,
91-
.textarea:focus {
92-
outline: none;
93-
border-color: var(--color-primary);
94-
}
98+
.textarea {
99+
resize: vertical;
100+
min-height: 8rem;
101+
}
95102

96-
.textarea {
97-
resize: vertical;
98-
min-height: 8rem;
99-
}
103+
.button {
104+
width: 100%;
105+
padding: 1rem 2rem;
106+
font-size: 1rem;
107+
font-weight: 600;
108+
font-family: var(--font-lato);
109+
color: var(--color-secondary);
110+
background-color: var(--color-primary);
111+
border: none;
112+
border-radius: 4px;
113+
cursor: pointer;
114+
transition: background-color 0.3s ease;
115+
}
100116

101-
.button {
102-
width: 100%;
103-
padding: 1rem 2rem;
104-
font-size: 1rem;
105-
font-weight: 600;
106-
font-family: var(--font-lato);
107-
color: var(--color-secondary);
108-
background-color: var(--color-primary);
109-
border: none;
110-
border-radius: 4px;
111-
cursor: pointer;
112-
transition: background-color 0.3s ease;
113-
}
117+
.button:hover {
118+
background-color: var(--color-background-primary);
119+
}
114120

115-
.button:hover {
116-
background-color: var(--color-background-primary);
117-
}
118-
</style>
121+
.location {
122+
margin-top: 6rem;
123+
}
124+
125+
h2 {
126+
font-size: 2rem;
127+
margin-bottom: var(--spacing-sm);
128+
}
129+
</style>
130+
</section>

src/components/Location.astro

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
import { Image } from "astro:assets";
3+
import map from "../assets/map.png";
4+
import { useI18n } from "../i18n/utils";
5+
6+
const { t } = useI18n(Astro.url);
7+
---
8+
9+
<section id="location-section">
10+
<h2>{t("contact.location.title")}</h2>
11+
<p>
12+
{t("contact.location.mainOffice")}: <strong>Kramgasse 68, 3011 Bern</strong>
13+
</p>
14+
<a
15+
href="https://maps.app.goo.gl/5o1J1VakRfZxfgdN6"
16+
target="_blank"
17+
class="map-link"
18+
>
19+
<Image src={map} alt="Map" class="map" />
20+
</a>
21+
</section>
22+
23+
<style>
24+
#location-section {
25+
padding: 4rem 2rem;
26+
max-width: 64rem;
27+
margin: 0 auto;
28+
}
29+
30+
h2 {
31+
font-size: 2rem;
32+
margin-bottom: var(--spacing-sm);
33+
}
34+
35+
p {
36+
font-size: 1.2rem;
37+
margin-bottom: 2rem;
38+
}
39+
40+
.map {
41+
width: 100%;
42+
height: auto;
43+
border-radius: 1rem;
44+
transition:
45+
transform 0.2s,
46+
box-shadow 0.2s;
47+
}
48+
49+
.map:hover {
50+
transform: translateY(-6px);
51+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.25);
52+
}
53+
</style>

src/i18n/ch.ts

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ const ts = {
7272
"Kontakt- u Rächtsinformatione zu bespinian – Cloud-native Beratig u Software-Entwicklig i dr Schwiiz.",
7373
"imprint.contact": "Kontaktinformatione",
7474
"imprint.email": "E-Mail: [email protected]",
75-
"imprint.headquarters": "Hauptsitz",
75+
"imprint.headquarters": "Houptsitz",
7676
"imprint.headquarters.address":
7777
"bespinian GmbH, Sonnenweg 9, 3073 Gümligen, Schweiz",
7878
"imprint.bern": "Büro Bärn",
@@ -123,7 +123,11 @@ const ts = {
123123
// Contact Page
124124
"contact.title": "Kontakt",
125125
"contact.subtitle":
126-
"Hesch e Frag? Bruchsch es Agebot? Luscht uf e Kafi? Schriib üs e Nachricht – mir mäudenis bi dir.",
126+
"Hesch e Frag? Bruchsch es Agebot? Luscht uf e Kafi? Chum verby oder schrib üs e Nachricht – mir mäudenis bi dir.",
127+
"contact.location.title": "Bsuech Üs",
128+
"contact.location.mainOffice":
129+
"Üses Büro isch ir nechi vom Zytglogge im Härze vor Autstadt vo Bärn",
130+
"contact.form.title": "Schick Üs e Nachricht",
127131
"contact.form.nameplaceholder": "Di Name",
128132
"contact.form.emailplaceholder": "Dini E-Mail",
129133
"contact.form.subjectplaceholder": "Beträff",
@@ -211,34 +215,21 @@ const ts = {
211215
"pricing.title": "Priise",
212216
"pricing.subtitle": "Wähl dr perfekt Plan für dini Bedürfniss",
213217
"pricing.creditExplanation":
214-
"Jede Credit chasch gäg ne Stung Arbeit vo eim vo üsne Experte-Engineers itusche. Stunde hei kes Verfallsdatum.",
218+
"Jede Credit chasch gäg ne Stung Arbeit vo eim vo üsne Experte-Engineers itusche. Credits hei kes Verfallsdatum.",
215219
"pricing.monthly": "Monatlechs Commitment",
216220
"pricing.yearly": "Jährlechs Commitment",
217221
"pricing.yearlyDiscount": "10% spare",
218222
"pricing.perMonth": "/Mt.",
223+
"pricing.perHour": "pro Stung",
219224
"pricing.correspondsTo": "Entspricht",
220-
"pricing.free.name": "Free",
221-
"pricing.free.price": "0",
222-
"pricing.free.credits": "8 Credits",
223-
"pricing.focused.name": "Focused",
224-
"pricing.focused.price": "6'336",
225-
"pricing.focused.credits": "32 Credits/Mt.",
226-
"pricing.focused.hourlyRate": "CHF 198 pro Credit",
227-
"pricing.focused.hourlyRateYearly": "CHF 178 pro Credit",
228-
"pricing.engaged.name": "Engaged",
229-
"pricing.engaged.price": "12'352",
230-
"pricing.engaged.credits": "64 Credits/Mt.",
231-
"pricing.engaged.hourlyRate": "CHF 193 pro Credit",
232-
"pricing.engaged.hourlyRateYearly": "CHF 174 pro Credit",
233-
"pricing.integrated.name": "Integrated",
234-
"pricing.integrated.price": "23'936",
235-
"pricing.integrated.credits": "128 Credits/Mt.",
236-
"pricing.integrated.hourlyRate": "CHF 187 pro Credit",
237-
"pricing.integrated.hourlyRateYearly": "CHF 168 pro Credit",
225+
"pricing.free.credits": "8 Stundä",
226+
"pricing.focused.credits": "1 Tag pro Wuche",
227+
"pricing.engaged.credits": "2 Täg pro Wuche",
228+
"pricing.integrated.credits": "4 Täg pro Wuche",
238229
"pricing.custom.name": "Custom",
239230
"pricing.custom.description": "Flexibli Priise",
240231
"pricing.feature.cloudquest": "CloudQuest",
241-
"pricing.feature.slackChannel": "Diräkte Slack Channel",
232+
"pricing.feature.slackChannel": "Diräkte Chat Channel",
242233
"pricing.feature.exclusiveTeam": "Exklusivs Team",
243234
"pricing.calculator.title": "Custom Priis-Rächner",
244235
"pricing.calculator.description": "Gib d Aazahl Credits i, wode bruuchsch.",
@@ -248,7 +239,6 @@ const ts = {
248239
"pricing.calculator.savings": "Du sparsch",
249240
"pricing.calculator.nextBracket":
250241
"Buech {hours} Credits um dr Priis uf CHF {price} pro Credit z reduziere u CHF {savings} z spare.",
251-
"pricing.calculator.currentBracket": "Aktuellä Tarif: CHF {price} pro Credit",
252242
};
253243

254244
export default ts;

src/i18n/de.ts

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,11 @@ const de = {
125125
// Contact Page
126126
"contact.title": "Kontakt",
127127
"contact.subtitle":
128-
"Du hast eine Frage? Brauchst ein Angebot? Lust auf einen Kaffee? Schreib uns eine Nachricht – wir melden uns bei dir.",
128+
"Du hast eine Frage? Brauchst ein Angebot? Lust auf einen Kaffee? Komm vorbei oder schreib uns eine Nachricht – wir melden uns bei dir.",
129+
"contact.location.title": "Besuch Uns",
130+
"contact.location.mainOffice":
131+
"Unser Büro ist in der Nähe des berühmten Zytglogge im Herzen der Altstadt von Bern",
132+
"contact.form.title": "Schick Uns eine Nachricht",
129133
"contact.form.nameplaceholder": "Dein Name",
130134
"contact.form.emailplaceholder": "Deine E-Mail",
131135
"contact.form.subjectplaceholder": "Betreff",
@@ -222,29 +226,16 @@ const de = {
222226
"pricing.yearly": "Jährliches Commitment",
223227
"pricing.yearlyDiscount": "10% sparen",
224228
"pricing.perMonth": "/Mt.",
229+
"pricing.perHour": "pro Stunde",
225230
"pricing.correspondsTo": "Entspricht",
226-
"pricing.free.name": "Free",
227-
"pricing.free.price": "0",
228-
"pricing.free.credits": "8 Credits",
229-
"pricing.focused.name": "Focused",
230-
"pricing.focused.price": "6'336",
231-
"pricing.focused.credits": "32 Credits/Mt.",
232-
"pricing.focused.hourlyRate": "CHF 198 pro Credit",
233-
"pricing.focused.hourlyRateYearly": "CHF 178 pro Credit",
234-
"pricing.engaged.name": "Engaged",
235-
"pricing.engaged.price": "12'352",
236-
"pricing.engaged.credits": "64 Credits/Mt.",
237-
"pricing.engaged.hourlyRate": "CHF 193 pro Credit",
238-
"pricing.engaged.hourlyRateYearly": "CHF 174 pro Credit",
239-
"pricing.integrated.name": "Integrated",
240-
"pricing.integrated.price": "23'936",
241-
"pricing.integrated.credits": "128 Credits/Mt.",
242-
"pricing.integrated.hourlyRate": "CHF 187 pro Credit",
243-
"pricing.integrated.hourlyRateYearly": "CHF 168 pro Credit",
231+
"pricing.free.credits": "8 Stunden",
232+
"pricing.focused.credits": "1 Tag pro Woche",
233+
"pricing.engaged.credits": "2 Tage pro Woche",
234+
"pricing.integrated.credits": "4 Tage pro Woche",
244235
"pricing.custom.name": "Custom",
245236
"pricing.custom.description": "Flexible Preise",
246237
"pricing.feature.cloudquest": "CloudQuest",
247-
"pricing.feature.slackChannel": "Direkter Slack Channel",
238+
"pricing.feature.slackChannel": "Direkter Chat Channel",
248239
"pricing.feature.exclusiveTeam": "Exklusives Team",
249240
"pricing.calculator.title": "Custom Preis-Rechner",
250241
"pricing.calculator.description":
@@ -255,8 +246,6 @@ const de = {
255246
"pricing.calculator.savings": "Du sparst",
256247
"pricing.calculator.nextBracket":
257248
"Buche {hours} oder mehr um den Preis auf CHF {price} pro Credit zu reduzieren und CHF {savings} zu sparen.",
258-
"pricing.calculator.currentBracket":
259-
"Aktueller Tarif: CHF {price} pro Credit",
260249
};
261250

262251
export default de;

src/i18n/en.ts

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,11 @@ const en = {
123123
// Contact Page
124124
"contact.title": "Contact Us",
125125
"contact.subtitle":
126-
"Have a question? Need a quote? Want to grab a coffee? Send us a message and we'll get back to you.",
126+
"Have a question? Need a quote? Want to grab a coffee? Come by or send us a message and we'll get back to you.",
127+
"contact.location.title": "Visit Us",
128+
"contact.location.mainOffice":
129+
"Our office is near the famous Zytglogge tower in the heart of the old town of Bern",
130+
"contact.form.title": "Send Us a Message",
127131
"contact.form.nameplaceholder": "Your Name",
128132
"contact.form.emailplaceholder": "Your Email",
129133
"contact.form.subjectplaceholder": "Subject",
@@ -215,29 +219,16 @@ const en = {
215219
"pricing.yearly": "Yearly Commitment",
216220
"pricing.yearlyDiscount": "Save 10%",
217221
"pricing.perMonth": "/mo",
222+
"pricing.perHour": "per hour",
218223
"pricing.correspondsTo": "Corresponds to",
219-
"pricing.free.name": "Free",
220-
"pricing.free.price": "0",
221-
"pricing.free.credits": "8 credits",
222-
"pricing.focused.name": "Focused",
223-
"pricing.focused.price": "6,336",
224-
"pricing.focused.credits": "32 credits/mo",
225-
"pricing.focused.hourlyRate": "CHF 198 per credit",
226-
"pricing.focused.hourlyRateYearly": "CHF 178 per credit",
227-
"pricing.engaged.name": "Engaged",
228-
"pricing.engaged.price": "12,352",
229-
"pricing.engaged.credits": "64 credits/mo",
230-
"pricing.engaged.hourlyRate": "CHF 193 per credit",
231-
"pricing.engaged.hourlyRateYearly": "CHF 174 per credit",
232-
"pricing.integrated.name": "Integrated",
233-
"pricing.integrated.price": "23,936",
234-
"pricing.integrated.credits": "128 credits/mo",
235-
"pricing.integrated.hourlyRate": "CHF 187 per credit",
236-
"pricing.integrated.hourlyRateYearly": "CHF 168 per credit",
224+
"pricing.free.credits": "8 hours",
225+
"pricing.focused.credits": "1 day per week",
226+
"pricing.engaged.credits": "2 days per week",
227+
"pricing.integrated.credits": "4 days per week",
237228
"pricing.custom.name": "Custom",
238229
"pricing.custom.description": "Flexible pricing",
239230
"pricing.feature.cloudquest": "CloudQuest",
240-
"pricing.feature.slackChannel": "Direct Slack Channel",
231+
"pricing.feature.slackChannel": "Direct Chat Channel",
241232
"pricing.feature.exclusiveTeam": "Exclusive Team",
242233
"pricing.calculator.title": "Custom Pricing Calculator",
243234
"pricing.calculator.description": "Enter the number of credits you need.",
@@ -247,7 +238,6 @@ const en = {
247238
"pricing.calculator.savings": "You save",
248239
"pricing.calculator.nextBracket":
249240
"Purchase {hours} or more to reduce the price to CHF {price} per credit and save CHF {savings}.",
250-
"pricing.calculator.currentBracket": "Current rate: CHF {price} per credit",
251241
};
252242

253243
export default en;

src/lib/formatters.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ export function formatDate(date: Date, locale: string): string {
1212
});
1313
}
1414

15+
/**
16+
* Formats a number to a localized string
17+
* @param num - The number
18+
* @param locale - The locale to use (default: "en-US")
19+
* @returns Formatted number string (e.g., "1,234")
20+
*/
21+
export function formatNumber(num: number, locale: string): string {
22+
return num.toLocaleString(locale === "en" ? "en-US" : "de-CH");
23+
}
24+
1525
/**
1626
* Sorts an array of items by date in descending order (newest first)
1727
* @param items - Array of items with a data.pubDate property

0 commit comments

Comments
 (0)