Skip to content

Commit 75db4ae

Browse files
committed
fix(i18n): extract hardcoded strings to locale file
1 parent fe73fea commit 75db4ae

6 files changed

Lines changed: 98 additions & 19 deletions

File tree

app/components/Header/AuthModal.client.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ watch(user, async newUser => {
8484
class="w-full px-4 py-2 font-mono text-sm text-fg-muted bg-bg-subtle border border-border rounded-md transition-colors duration-200 hover:text-fg hover:border-border-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
8585
@click="authModal.close()"
8686
>
87-
Profile
87+
{{ $t('auth.modal.profile') }}
8888
</button>
8989
</NuxtLink>
9090

app/pages/profile/[handle]/index.vue

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ async function updateProfile() {
6666
const { data: likesData, status } = await useProfileLikes(handle)
6767
6868
useSeoMeta({
69-
title: () => `${handle.value} - npmx`,
70-
description: () => `npmx profile by ${handle.value}`,
69+
title: () => $t('profile.seo_title', { handle: handle.value }),
70+
description: () => $t('profile.seo_description', { handle: handle.value }),
7171
})
7272
7373
/**
@@ -86,7 +86,7 @@ defineOgImageComponent('Default', {
8686
<!-- Editing Profile -->
8787
<div v-if="isEditing" class="flex flex-col flex-wrap gap-4">
8888
<label for="displayName" class="text-sm flex flex-col gap-2">
89-
Display Name
89+
{{ $t('profile.display_name') }}
9090
<input
9191
required
9292
name="displayName"
@@ -96,11 +96,11 @@ defineOgImageComponent('Default', {
9696
/>
9797
</label>
9898
<label for="description" class="text-sm flex flex-col gap-2">
99-
Description
99+
{{ $t('profile.description') }}
100100
<input
101101
name="description"
102102
type="text"
103-
placeholder="No description"
103+
:placeholder="$t('profile.no_description')"
104104
v-model="descriptionInput"
105105
class="w-full min-w-25 bg-bg-subtle border border-border rounded-md ps-3 pe-3 py-1.5 font-mono text-sm text-fg placeholder:text-fg-subtle transition-[border-color,outline-color] duration-300 hover:border-fg-subtle outline-2 outline-transparent focus:border-accent focus-visible:(outline-2 outline-accent/70)"
106106
/>
@@ -120,14 +120,14 @@ defineOgImageComponent('Default', {
120120
@click="isEditing = false"
121121
class="hidden sm:inline-flex link-subtle font-mono text-sm items-center gap-2 px-2 py-1.5 hover:bg-bg-subtle focus-visible:outline-accent/70 rounded"
122122
>
123-
Cancel
123+
{{ $t('common.cancel') }}
124124
</button>
125125
<button
126126
@click.prevent="updateProfile"
127127
:disabled="isUpdateProfileActionPending"
128128
class="hidden sm:inline-flex link-subtle font-mono text-sm items-center gap-2 px-2 py-1.5 hover:bg-bg-subtle focus-visible:outline-accent/70 rounded"
129129
>
130-
Save
130+
{{ $t('common.save') }}
131131
</button>
132132
</div>
133133
</div>
@@ -148,7 +148,7 @@ defineOgImageComponent('Default', {
148148
@click="isEditing = true"
149149
class="hidden sm:inline-flex link-subtle font-mono text-sm items-center gap-2 px-2 py-1.5 hover:bg-bg-subtle focus-visible:outline-accent/70 rounded"
150150
>
151-
Edit
151+
{{ $t('common.edit') }}
152152
</button>
153153
</div>
154154
</div>
@@ -157,16 +157,17 @@ defineOgImageComponent('Default', {
157157
<section class="flex flex-col gap-8">
158158
<h2
159159
class="font-mono text-2xl sm:text-3xl font-medium min-w-0 break-words"
160-
title="Likes"
160+
:title="$t('profile.likes')"
161161
dir="ltr"
162162
>
163-
Likes <span v-if="likesData">({{ likesData.likes.records.length ?? 0 }})</span>
163+
{{ $t('profile.likes') }}
164+
<span v-if="likesData">({{ likesData.likes.records.length ?? 0 }})</span>
164165
</h2>
165166
<div v-if="status === 'pending'">
166-
<p>Loading...</p>
167+
<p>{{ $t('common.loading') }}</p>
167168
</div>
168169
<div v-else-if="status === 'error'">
169-
<p>Error</p>
170+
<p>{{ $t('common.error') }}</p>
170171
</div>
171172
<div v-else-if="likesData.likes.records" class="grid grid-cols-1 lg:grid-cols-2 gap-4">
172173
<PackageLikeCard

i18n/locales/en.json

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,19 @@
140140
"role": "role",
141141
"members": "members"
142142
},
143-
"scroll_to_top": "Scroll to top"
143+
"scroll_to_top": "Scroll to top",
144+
"cancel": "Cancel",
145+
"save": "Save",
146+
"edit": "Edit",
147+
"error": "Error"
148+
},
149+
"profile": {
150+
"display_name": "Display Name",
151+
"description": "Description",
152+
"no_description": "No description",
153+
"likes": "Likes",
154+
"seo_title": "{handle} - npmx",
155+
"seo_description": "npmx profile by {handle}"
144156
},
145157
"package": {
146158
"not_found": "Package Not Found",
@@ -909,7 +921,8 @@
909921
"connect_bluesky": "Connect with Bluesky",
910922
"what_is_atmosphere": "What is an Atmosphere account?",
911923
"atmosphere_explanation": "{npmx} uses the {atproto} to power many of its social features, allowing users to own their data and use one account for all compatible applications. Once you create an account, you can use other apps like {bluesky} and {tangled} with the same account.",
912-
"default_input_error": "Please enter a valid handle, DID, or a full PDS URL"
924+
"default_input_error": "Please enter a valid handle, DID, or a full PDS URL",
925+
"profile": "Profile"
913926
}
914927
},
915928
"header": {

i18n/schema.json

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,42 @@
426426
},
427427
"scroll_to_top": {
428428
"type": "string"
429+
},
430+
"cancel": {
431+
"type": "string"
432+
},
433+
"save": {
434+
"type": "string"
435+
},
436+
"edit": {
437+
"type": "string"
438+
},
439+
"error": {
440+
"type": "string"
441+
}
442+
},
443+
"additionalProperties": false
444+
},
445+
"profile": {
446+
"type": "object",
447+
"properties": {
448+
"display_name": {
449+
"type": "string"
450+
},
451+
"description": {
452+
"type": "string"
453+
},
454+
"no_description": {
455+
"type": "string"
456+
},
457+
"likes": {
458+
"type": "string"
459+
},
460+
"seo_title": {
461+
"type": "string"
462+
},
463+
"seo_description": {
464+
"type": "string"
429465
}
430466
},
431467
"additionalProperties": false
@@ -2733,6 +2769,9 @@
27332769
},
27342770
"default_input_error": {
27352771
"type": "string"
2772+
},
2773+
"profile": {
2774+
"type": "string"
27362775
}
27372776
},
27382777
"additionalProperties": false

lunaria/files/en-GB.json

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,19 @@
139139
"role": "role",
140140
"members": "members"
141141
},
142-
"scroll_to_top": "Scroll to top"
142+
"scroll_to_top": "Scroll to top",
143+
"cancel": "Cancel",
144+
"save": "Save",
145+
"edit": "Edit",
146+
"error": "Error"
147+
},
148+
"profile": {
149+
"display_name": "Display Name",
150+
"description": "Description",
151+
"no_description": "No description",
152+
"likes": "Likes",
153+
"seo_title": "{handle} - npmx",
154+
"seo_description": "npmx profile by {handle}"
143155
},
144156
"package": {
145157
"not_found": "Package Not Found",
@@ -908,7 +920,8 @@
908920
"connect_bluesky": "Connect with Bluesky",
909921
"what_is_atmosphere": "What is an Atmosphere account?",
910922
"atmosphere_explanation": "{npmx} uses the {atproto} to power many of its social features, allowing users to own their data and use one account for all compatible applications. Once you create an account, you can use other apps like {bluesky} and {tangled} with the same account.",
911-
"default_input_error": "Please enter a valid handle, DID, or a full PDS URL"
923+
"default_input_error": "Please enter a valid handle, DID, or a full PDS URL",
924+
"profile": "Profile"
912925
}
913926
},
914927
"header": {

lunaria/files/en-US.json

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,19 @@
139139
"role": "role",
140140
"members": "members"
141141
},
142-
"scroll_to_top": "Scroll to top"
142+
"scroll_to_top": "Scroll to top",
143+
"cancel": "Cancel",
144+
"save": "Save",
145+
"edit": "Edit",
146+
"error": "Error"
147+
},
148+
"profile": {
149+
"display_name": "Display Name",
150+
"description": "Description",
151+
"no_description": "No description",
152+
"likes": "Likes",
153+
"seo_title": "{handle} - npmx",
154+
"seo_description": "npmx profile by {handle}"
143155
},
144156
"package": {
145157
"not_found": "Package Not Found",
@@ -908,7 +920,8 @@
908920
"connect_bluesky": "Connect with Bluesky",
909921
"what_is_atmosphere": "What is an Atmosphere account?",
910922
"atmosphere_explanation": "{npmx} uses the {atproto} to power many of its social features, allowing users to own their data and use one account for all compatible applications. Once you create an account, you can use other apps like {bluesky} and {tangled} with the same account.",
911-
"default_input_error": "Please enter a valid handle, DID, or a full PDS URL"
923+
"default_input_error": "Please enter a valid handle, DID, or a full PDS URL",
924+
"profile": "Profile"
912925
}
913926
},
914927
"header": {

0 commit comments

Comments
 (0)