@jjlmoya/utils-travel 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/package.json +59 -58
  2. package/src/category/i18n/de.ts +185 -0
  3. package/src/category/i18n/fr.ts +86 -1
  4. package/src/category/i18n/id.ts +185 -0
  5. package/src/category/i18n/it.ts +185 -0
  6. package/src/category/i18n/ja.ts +181 -0
  7. package/src/category/i18n/ko.ts +181 -0
  8. package/src/category/i18n/nl.ts +185 -0
  9. package/src/category/i18n/pl.ts +181 -0
  10. package/src/category/i18n/pt.ts +181 -0
  11. package/src/category/i18n/ru.ts +181 -0
  12. package/src/category/i18n/sv.ts +181 -0
  13. package/src/category/i18n/tr.ts +181 -0
  14. package/src/category/i18n/zh.ts +181 -0
  15. package/src/category/index.ts +13 -1
  16. package/src/tests/i18n_coverage.test.ts +36 -0
  17. package/src/tests/locale_completeness.test.ts +24 -3
  18. package/src/tests/no_h1_in_components.test.ts +42 -2
  19. package/src/tests/schemas_fulfillment.test.ts +23 -0
  20. package/src/tests/slug_uniqueness.test.ts +81 -0
  21. package/src/tests/title_quality.test.ts +55 -0
  22. package/src/tool/luggage-calculator/i18n/de.ts +616 -0
  23. package/src/tool/luggage-calculator/i18n/en.ts +2 -2
  24. package/src/tool/luggage-calculator/i18n/id.ts +616 -0
  25. package/src/tool/luggage-calculator/i18n/it.ts +616 -0
  26. package/src/tool/luggage-calculator/i18n/ja.ts +616 -0
  27. package/src/tool/luggage-calculator/i18n/ko.ts +616 -0
  28. package/src/tool/luggage-calculator/i18n/nl.ts +616 -0
  29. package/src/tool/luggage-calculator/i18n/pl.ts +616 -0
  30. package/src/tool/luggage-calculator/i18n/pt.ts +616 -0
  31. package/src/tool/luggage-calculator/i18n/ru.ts +616 -0
  32. package/src/tool/luggage-calculator/i18n/sv.ts +616 -0
  33. package/src/tool/luggage-calculator/i18n/tr.ts +616 -0
  34. package/src/tool/luggage-calculator/i18n/zh.ts +616 -0
  35. package/src/tool/luggage-calculator/index.ts +13 -1
  36. package/src/tool/mini-adventures/i18n/de.ts +161 -0
  37. package/src/tool/mini-adventures/i18n/en.ts +1 -1
  38. package/src/tool/mini-adventures/i18n/es.ts +1 -1
  39. package/src/tool/mini-adventures/i18n/id.ts +161 -0
  40. package/src/tool/mini-adventures/i18n/it.ts +161 -0
  41. package/src/tool/mini-adventures/i18n/ja.ts +161 -0
  42. package/src/tool/mini-adventures/i18n/ko.ts +161 -0
  43. package/src/tool/mini-adventures/i18n/nl.ts +161 -0
  44. package/src/tool/mini-adventures/i18n/pl.ts +161 -0
  45. package/src/tool/mini-adventures/i18n/pt.ts +161 -0
  46. package/src/tool/mini-adventures/i18n/ru.ts +161 -0
  47. package/src/tool/mini-adventures/i18n/sv.ts +161 -0
  48. package/src/tool/mini-adventures/i18n/tr.ts +161 -0
  49. package/src/tool/mini-adventures/i18n/zh.ts +161 -0
  50. package/src/tool/mini-adventures/index.ts +13 -1
  51. package/src/tool/suitcase-checklist/i18n/de.ts +261 -0
  52. package/src/tool/suitcase-checklist/i18n/en.ts +1 -1
  53. package/src/tool/suitcase-checklist/i18n/es.ts +1 -1
  54. package/src/tool/suitcase-checklist/i18n/fr.ts +1 -1
  55. package/src/tool/suitcase-checklist/i18n/id.ts +261 -0
  56. package/src/tool/suitcase-checklist/i18n/it.ts +261 -0
  57. package/src/tool/suitcase-checklist/i18n/ja.ts +261 -0
  58. package/src/tool/suitcase-checklist/i18n/ko.ts +261 -0
  59. package/src/tool/suitcase-checklist/i18n/nl.ts +261 -0
  60. package/src/tool/suitcase-checklist/i18n/pl.ts +261 -0
  61. package/src/tool/suitcase-checklist/i18n/pt.ts +261 -0
  62. package/src/tool/suitcase-checklist/i18n/ru.ts +261 -0
  63. package/src/tool/suitcase-checklist/i18n/sv.ts +261 -0
  64. package/src/tool/suitcase-checklist/i18n/tr.ts +261 -0
  65. package/src/tool/suitcase-checklist/i18n/zh.ts +261 -0
  66. package/src/tool/suitcase-checklist/index.ts +13 -1
  67. package/src/tool/tip-calculator/i18n/de.ts +264 -0
  68. package/src/tool/tip-calculator/i18n/id.ts +264 -0
  69. package/src/tool/tip-calculator/i18n/it.ts +264 -0
  70. package/src/tool/tip-calculator/i18n/ja.ts +264 -0
  71. package/src/tool/tip-calculator/i18n/ko.ts +264 -0
  72. package/src/tool/tip-calculator/i18n/nl.ts +264 -0
  73. package/src/tool/tip-calculator/i18n/pl.ts +264 -0
  74. package/src/tool/tip-calculator/i18n/pt.ts +264 -0
  75. package/src/tool/tip-calculator/i18n/ru.ts +264 -0
  76. package/src/tool/tip-calculator/i18n/sv.ts +264 -0
  77. package/src/tool/tip-calculator/i18n/tr.ts +264 -0
  78. package/src/tool/tip-calculator/i18n/zh.ts +264 -0
  79. package/src/tool/tip-calculator/index.ts +13 -1
  80. package/src/tool/optimal-routes/bibliography.astro +0 -14
  81. package/src/tool/optimal-routes/component.astro +0 -439
  82. package/src/tool/optimal-routes/i18n/en.ts +0 -42
  83. package/src/tool/optimal-routes/i18n/es.ts +0 -52
  84. package/src/tool/optimal-routes/index.ts +0 -63
  85. package/src/tool/optimal-routes/lib/RouteManager.ts +0 -181
  86. package/src/tool/optimal-routes/seo.astro +0 -14
@@ -0,0 +1,264 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { TipCalculatorUI } from '../index';
4
+
5
+ const slug = 'uluslararasi-bahsis-hesaplayici';
6
+ const title = 'Uluslararası Bahşiş Hesaplayıcı';
7
+ const description = 'Seyahatlerinizde ne kadar bahşiş bırakacağınızı hesaplayın. 50\'den fazla ülke için yüzde kılavuzu ve görgü kurallarını içerir. Ödeme yaparken hata yapmayın!';
8
+
9
+ const ui: TipCalculatorUI = {
10
+ title: "Bahşiş Hesaplayıcı",
11
+ badge: "Uluslararası Bahşiş Aracı",
12
+ billLabel: "Fatura Tutarı",
13
+ countryLabel: "Ülke / Yerel Adetler",
14
+ tipLabel: "Bahşiş Yüzdesi",
15
+ splitLabel: "Hesabı Böl",
16
+ summaryTip: "Toplam Bahşiş",
17
+ summarySubtotal: "Ara Toplam",
18
+ summaryTotalPerson: "Kişi Başı Toplam",
19
+ protocolTitle: "Görgü Kuralları",
20
+ placeholderAmount: "0.00",
21
+ placeholderFilter: "Ülke ara...",
22
+ placeholderSelect: "Bir ülke seçin",
23
+ countries: [
24
+ {
25
+ id: "usa",
26
+ name: "ABD & Kanada",
27
+ min: 18,
28
+ max: 25,
29
+ default: 20,
30
+ culture: "Garson maaşları için bahşiş esastır. %18 ile %25 arası beklenir. Bahşiş bırakmamak, Kuzey Amerika kültüründe ciddi bir saygısızlık olarak kabul edilir.",
31
+ },
32
+ {
33
+ id: "esp",
34
+ name: "İspanya",
35
+ min: 0,
36
+ max: 10,
37
+ default: 5,
38
+ culture: "İsteğe bağlıdır. Genellikle para üstünü yuvarlamak veya hizmet kaliteli ise akşam yemeklerinde %5-10 bırakmak yaygındır.",
39
+ },
40
+ {
41
+ id: "jpn",
42
+ name: "Japonya",
43
+ min: 0,
44
+ max: 0,
45
+ default: 0,
46
+ culture: "Bahşiş verilmez. Profesyonelliğe hakaret olarak kabul edilir. Para bırakırsanız, muhtemelen iade etmek için peşinizden gelirler.",
47
+ },
48
+ {
49
+ id: "ita",
50
+ name: "İtalya",
51
+ min: 0,
52
+ max: 10,
53
+ default: 0,
54
+ culture: "'Coperto', masa servisi, ekmek ve örtü ücretidir, bahşişin kendisi değildir. Ekstra %5-10 bırakmak takdir edilen ancak tamamen isteğe bağlı bir jesttir.",
55
+ },
56
+ {
57
+ id: "fra",
58
+ name: "Fransa",
59
+ min: 0,
60
+ max: 10,
61
+ default: 5,
62
+ culture: "Servis ücreti kanunen dahildir. 'Pourboire'u (küçük ekstra) sadece olağanüstü hizmet için bırakın.",
63
+ },
64
+ {
65
+ id: "gbr",
66
+ name: "Birleşik Krallık",
67
+ min: 0,
68
+ max: 12.5,
69
+ default: 10,
70
+ culture: "Faturaya genellikle %12,5 oranında isteğe bağlı bir servis ücreti eklenir. Eğer eklenmemişse, restoranlarda %10 standarttır.",
71
+ },
72
+ {
73
+ id: "mex",
74
+ name: "Meksika",
75
+ min: 10,
76
+ max: 15,
77
+ default: 12,
78
+ culture: "%10-15 'propina' beklenir. Sektördeki çalışanlar için ekonominin hayati bir parçasıdır.",
79
+ },
80
+ {
81
+ id: "arg",
82
+ name: "Arjantin",
83
+ min: 0,
84
+ max: 10,
85
+ default: 10,
86
+ culture: "Standart %10'dur. Hizmet normal veya iyiyse neredeyse her zaman bırakılır.",
87
+ },
88
+ {
89
+ id: "bra",
90
+ name: "Brezilya",
91
+ min: 0,
92
+ max: 10,
93
+ default: 10,
94
+ culture: "Normalde faturaya 'Serviço' olarak %10 ücret eklenir. İsteğe bağlıdır ancak çoğu kişi öder.",
95
+ },
96
+ {
97
+ id: "deu",
98
+ name: "Almanya",
99
+ min: 5,
100
+ max: 10,
101
+ default: 7,
102
+ culture: "Tutarı yuvarlamak veya %5-10 eklemek yaygındır. Ödeme yaparken garsona bahşiş dahil toplam tutarı söyleyin.",
103
+ },
104
+ {
105
+ id: "tur",
106
+ name: "Türkiye",
107
+ min: 5,
108
+ max: 10,
109
+ default: 10,
110
+ culture: "Turistik bölgelerde nakit olarak %10 beklenir. Genellikle kredi kartına bahşiş eklenemez.",
111
+ },
112
+ {
113
+ id: "aus",
114
+ name: "Avustralya",
115
+ min: 0,
116
+ max: 10,
117
+ default: 0,
118
+ culture: "Beklenmez. Maaşlar yüksektir. Şık restoranlarda %10 bırakılabilir.",
119
+ },
120
+ {
121
+ id: "chn",
122
+ name: "Çin",
123
+ min: 0,
124
+ max: 0,
125
+ default: 0,
126
+ culture: "Tarihsel olarak bahşiş bırakılmaz ve birçok yerde yasaktır veya garip karşılanır.",
127
+ },
128
+ {
129
+ id: "prt",
130
+ name: "Portekiz",
131
+ min: 0,
132
+ max: 10,
133
+ default: 5,
134
+ culture: "Para üstünü bırakmak veya tutarı yuvarlamak adettendir. Turistik bölgelerde %5-10 yaygındır.",
135
+ },
136
+ {
137
+ id: "grc",
138
+ name: "Yunanistan",
139
+ min: 0,
140
+ max: 10,
141
+ default: 5,
142
+ culture: "Faturayı yuvarlamak genellikle yeterlidir. Ekstra %5-10 çok takdir edilir ancak zorunlu değildir.",
143
+ },
144
+ ]
145
+ };
146
+
147
+ const seo: ToolLocaleContent<TipCalculatorUI>['seo'] = [
148
+ {
149
+ type: "title",
150
+ text: "Uluslararası Bahşiş Rehberi: Görgü Kuralları ve Yüzdeler 2026",
151
+ level: 2,
152
+ },
153
+ {
154
+ type: "summary",
155
+ title: "Dünyanın her yerinde yerel biri gibi bahşiş bırakmayı öğrenin",
156
+ items: [
157
+ "Büyük turistik yerlerde beklenen bahşiş yüzdeleri hakkında tam kılavuz.",
158
+ "Ara toplamdan veya vergiler dahil toplamdan bahşişi hızlıca hesaplama yolları.",
159
+ "Servis ücretleri, kuver (coperto) ve gönüllü bahşiş arasındaki fark.",
160
+ "Özel durumlar için görgü kuralları: taksiler, oteller ve tur rehberleri.",
161
+ ],
162
+ },
163
+ {
164
+ type: "paragraph",
165
+ html: "Uluslararası bir seyahatin en stresli anlarından biri, faturanın masaya geldiği andır. <strong>Uluslararası bahşiş hesaplayıcımız</strong> bu belirsizliği ortadan kaldırmak için tasarlanmıştır.",
166
+ }
167
+ ];
168
+
169
+ const faq: ToolLocaleContent<TipCalculatorUI>['faq'] = [
170
+ {
171
+ question: "Amerika Birleşik Devletleri'nde bahşiş bırakmak zorunlu mu?",
172
+ answer: "Yasal olarak hayır, ancak sosyal olarak zorunludur. Garsonlar asgari ücrete ulaşmak için bahşişlere güvenirler. %18 ile %25 arası bırakılması normaldir.",
173
+ },
174
+ {
175
+ question: "Hangi ülkelerde bahşiş bırakmak saldırganlık kabul edilir?",
176
+ answer: "Genellikle Japonya ve Güney Kore'de. İyi hizmet görevin bir parçası olarak kabul edilir ve ekstra ödül gerektirmez.",
177
+ },
178
+ {
179
+ question: "Hizmet kötüyse bahşiş vermeli miyim?",
180
+ answer: "İsteğe bağlı olduğu ülkelerde (Avrupa, Avustralya), en doğrusu hiçbir şey bırakmamaktır.",
181
+ },
182
+ {
183
+ question: "Bahşiş vergiden önce mi yoksa sonra mı hesaplanır?",
184
+ answer: "Kuzey Amerika'da genellikle ara toplam (vergi öncesi) üzerinden hesaplanır. Avrupa ve Latin Amerika'da her zaman faturanın toplamı üzerinden hesaplanır.",
185
+ },
186
+ ];
187
+
188
+ const bibliography: ToolLocaleContent<TipCalculatorUI>['bibliography'] = [
189
+ {
190
+ name: "Condé Nast Traveler: Tipping Etiquette Guide",
191
+ url: "https://www.cntraveler.com/stories/2008-11-11/etiquette-101-tipping-guide",
192
+ },
193
+ {
194
+ name: "Lonely Planet: Tipping and Etiquette in Europe",
195
+ url: "https://www.lonelyplanet.com/articles/tipping-customs-europe",
196
+ },
197
+ {
198
+ name: "Western Union: Global Tipping Guide",
199
+ url: "https://www.westernunion.com/blog/en/global-tipping-guide/",
200
+ },
201
+ ];
202
+
203
+ const howTo: ToolLocaleContent<TipCalculatorUI>['howTo'] = [
204
+ {
205
+ name: "Fatura toplamını girin",
206
+ text: "Bahşişi uygulamadan önce faturanızda görünen toplam tutarı yazın.",
207
+ },
208
+ {
209
+ name: "Ülkeyi seçin",
210
+ text: "Kültürel öneriyi ve standart yüzdeyi otomatik olarak yüklemek için varış noktanızı seçin.",
211
+ },
212
+ {
213
+ name: "Ayarlayın ve bölün",
214
+ text: "Eğer birden fazla kişiyseniz, bahşiş dahil her birinin ne kadar ödemesi gerektiğini öğrenmek için kişi sayısını belirtin.",
215
+ },
216
+ ];
217
+
218
+ const faqSchema: WithContext<FAQPage> = {
219
+ '@context': 'https://schema.org',
220
+ '@type': 'FAQPage',
221
+ mainEntity: faq.map((item) => ({
222
+ '@type': 'Question',
223
+ name: item.question,
224
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
225
+ })),
226
+ };
227
+
228
+ const howToSchema: WithContext<HowTo> = {
229
+ '@context': 'https://schema.org',
230
+ '@type': 'HowTo',
231
+ name: title,
232
+ description: description,
233
+ step: howTo.map((step) => ({
234
+ '@type': 'HowToStep',
235
+ name: step.name,
236
+ text: step.text,
237
+ })),
238
+ };
239
+
240
+ const appSchema: WithContext<SoftwareApplication> = {
241
+ '@context': 'https://schema.org',
242
+ '@type': 'SoftwareApplication',
243
+ name: title,
244
+ description: description,
245
+ applicationCategory: 'FinanceApplication',
246
+ operatingSystem: 'All',
247
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'TRY' },
248
+ inLanguage: 'tr',
249
+ };
250
+
251
+ export const content: ToolLocaleContent<TipCalculatorUI> = {
252
+ slug,
253
+ title,
254
+ description,
255
+ ui,
256
+ seo,
257
+ faq,
258
+ faqTitle: "Sıkça Sorulan Sorular",
259
+ bibliography,
260
+ bibliographyTitle: "Kaynaklar ve Referanslar",
261
+ howTo,
262
+ howToTitle: "Hesaplayıcı nasıl kullanılır",
263
+ schemas: [faqSchema, howToSchema, appSchema],
264
+ };
@@ -0,0 +1,264 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { TipCalculatorUI } from '../index';
4
+
5
+ const slug = 'international-tip-calculator';
6
+ const title = '国际小费计算器';
7
+ const description = '计算您在旅行中应当支付的小费金额。包含针对 50 多个国家的百分比指南和礼仪规则。结账时不再感到困惑!';
8
+
9
+ const ui: TipCalculatorUI = {
10
+ title: "小费计算器",
11
+ badge: "国际小费工具",
12
+ billLabel: "账单金额",
13
+ countryLabel: "国家 / 当地习俗",
14
+ tipLabel: "小费百分比",
15
+ splitLabel: "拆分账单",
16
+ summaryTip: "小费总计",
17
+ summarySubtotal: "不含小费总计",
18
+ summaryTotalPerson: "人均总计",
19
+ protocolTitle: "礼仪说明",
20
+ placeholderAmount: "0.00",
21
+ placeholderFilter: "搜索国家...",
22
+ placeholderSelect: "选择一个国家",
23
+ countries: [
24
+ {
25
+ id: "usa",
26
+ name: "美国与加拿大",
27
+ min: 18,
28
+ max: 25,
29
+ default: 20,
30
+ culture: "小费是服务员薪资的重要组成部分。通常期待 18% 到 25% 的小费。不给小费被视为对北美文化的严重失礼。",
31
+ },
32
+ {
33
+ id: "esp",
34
+ name: "西班牙",
35
+ min: 0,
36
+ max: 10,
37
+ default: 5,
38
+ culture: "可选。通常做法是找零时取整,或者如果服务质量好,在晚餐时留下 5-10% 的小费。",
39
+ },
40
+ {
41
+ id: "jpn",
42
+ name: "日本",
43
+ min: 0,
44
+ max: 0,
45
+ default: 0,
46
+ culture: "不收小费。这被视为是对其专业精神的一种侮辱。如果您留下钱,他们很可能会跟着您并将其归还。",
47
+ },
48
+ {
49
+ id: "ita",
50
+ name: "意大利",
51
+ min: 0,
52
+ max: 10,
53
+ default: 0,
54
+ culture: "“Coperto”是座位费、面包和餐具费,并非小费本身。额外留下 5-10% 会被赞赏,但完全是自愿的。",
55
+ },
56
+ {
57
+ id: "fra",
58
+ name: "法国",
59
+ min: 0,
60
+ max: 10,
61
+ default: 5,
62
+ culture: "服务费已依法包含在内。仅在获得卓越服务时才留下“pourboire”(额外的小额奖励)。",
63
+ },
64
+ {
65
+ id: "gbr",
66
+ name: "英国",
67
+ min: 0,
68
+ max: 12.5,
69
+ default: 10,
70
+ culture: "账单中通常会加入 12.5% 的可选服务费。如果没有加入,餐厅的标准通常是 10%。",
71
+ },
72
+ {
73
+ id: "mex",
74
+ name: "墨西哥",
75
+ min: 10,
76
+ max: 15,
77
+ default: 12,
78
+ culture: "期待 10-15% 的“propina”。这是该行业从业者收入的重要组成部分。",
79
+ },
80
+ {
81
+ id: "arg",
82
+ name: "阿根廷",
83
+ min: 0,
84
+ max: 10,
85
+ default: 10,
86
+ culture: "标准是 10%。如果服务正常或较好,几乎总会留下小费。",
87
+ },
88
+ {
89
+ id: "bra",
90
+ name: "巴西",
91
+ min: 0,
92
+ max: 10,
93
+ default: 10,
94
+ culture: "通常账单中会包含 10% 的“Serviço”费用。这是可选的,但大多数人都会支付。",
95
+ },
96
+ {
97
+ id: "deu",
98
+ name: "德国",
99
+ min: 5,
100
+ max: 10,
101
+ default: 7,
102
+ culture: "通常做法是取整或增加 5-10%。结账时请告知服务员包含小费在内的总金额。",
103
+ },
104
+ {
105
+ id: "tur",
106
+ name: "土耳其",
107
+ min: 5,
108
+ max: 10,
109
+ default: 10,
110
+ culture: "在旅游区,通常期待 10% 的现金。一般无法在信用卡刷卡时添加小费。",
111
+ },
112
+ {
113
+ id: "aus",
114
+ name: "澳大利亚",
115
+ min: 0,
116
+ max: 10,
117
+ default: 0,
118
+ culture: "不期待。由于薪资较高,仅在高级餐饮场所可以留下 10% 的小费。",
119
+ },
120
+ {
121
+ id: "chn",
122
+ name: "中国",
123
+ min: 0,
124
+ max: 0,
125
+ default: 0,
126
+ culture: "历史上没有给小费的习惯,在许多地方这甚至是被禁止的或被认为很奇怪。",
127
+ },
128
+ {
129
+ id: "prt",
130
+ name: "葡萄牙",
131
+ min: 0,
132
+ max: 10,
133
+ default: 5,
134
+ culture: "习惯做法是留下零钱或取整。在旅游区,5-10% 的小费很常见。",
135
+ },
136
+ {
137
+ id: "grc",
138
+ name: "希腊",
139
+ min: 0,
140
+ max: 10,
141
+ default: 5,
142
+ culture: "账单金额取整通常就足够了。额外 5-10% 的小费会很受欢迎,但并非强制性。",
143
+ },
144
+ ]
145
+ };
146
+
147
+ const seo: ToolLocaleContent<TipCalculatorUI>['seo'] = [
148
+ {
149
+ type: "title",
150
+ text: "国际小费指南:2026 年礼仪与百分比",
151
+ level: 2,
152
+ },
153
+ {
154
+ type: "summary",
155
+ title: "学习像当地人一样在全球各地支付小费",
156
+ items: [
157
+ "主要旅游目的地预期小费百分比的完整指南。",
158
+ "如何从小计或含税总额快速计算小费。",
159
+ "服务费、座位费 (coperto) 与自愿小费的区别。",
160
+ "特殊情况下的礼仪规则:出租车、酒店和导游。",
161
+ ],
162
+ },
163
+ {
164
+ type: "paragraph",
165
+ html: "任何国际旅行中最令人紧张的时刻之一就是当账单送到桌上时。我们的<strong>国际小费计算器</strong>旨在消除这种不确定性。",
166
+ }
167
+ ];
168
+
169
+ const faq: ToolLocaleContent<TipCalculatorUI>['faq'] = [
170
+ {
171
+ question: "在美国支付小费是强制性的吗?",
172
+ answer: "法律上并非强制,但社交上是必须的。服务员依靠小费来达到最低工资标准。通常会留下 18% 到 25% 之间的小费。",
173
+ },
174
+ {
175
+ question: "在哪些国家支付小费会被视为冒犯?",
176
+ answer: "主要是在日本和韩国。提供优质服务被视为职责的一部分,不需要额外的补偿。",
177
+ },
178
+ {
179
+ question: "如果服务不好,我还需要给小费吗?",
180
+ answer: "在小费可选的国家(欧洲、澳大利亚),最正确的做法是不给小费。",
181
+ },
182
+ {
183
+ question: "小费是按税前还是税后金额计算的?",
184
+ answer: "在北美,通常按小计(税前)计算。在欧洲和拉丁美洲,始终按账单总额计算。",
185
+ },
186
+ ];
187
+
188
+ const bibliography: ToolLocaleContent<TipCalculatorUI>['bibliography'] = [
189
+ {
190
+ name: "Condé Nast Traveler: Tipping Etiquette Guide",
191
+ url: "https://www.cntraveler.com/stories/2008-11-11/etiquette-101-tipping-guide",
192
+ },
193
+ {
194
+ name: "Lonely Planet: Tipping and Etiquette in Europe",
195
+ url: "https://www.lonelyplanet.com/articles/tipping-customs-europe",
196
+ },
197
+ {
198
+ name: "Western Union: Global Tipping Guide",
199
+ url: "https://www.westernunion.com/blog/en/global-tipping-guide/",
200
+ },
201
+ ];
202
+
203
+ const howTo: ToolLocaleContent<TipCalculatorUI>['howTo'] = [
204
+ {
205
+ name: "输入账单总额",
206
+ text: "在应用小费之前,输入发票上显示的原始总金额。",
207
+ },
208
+ {
209
+ name: "选择国家",
210
+ text: "选择您的目的地,系统将自动加载文化建议和标准百分比。",
211
+ },
212
+ {
213
+ name: "调整与拆分",
214
+ text: "如果有几个人,请指明人数,以便了解每人(包括小费在内)应当支付的金额。",
215
+ },
216
+ ];
217
+
218
+ const faqSchema: WithContext<FAQPage> = {
219
+ '@context': 'https://schema.org',
220
+ '@type': 'FAQPage',
221
+ mainEntity: faq.map((item) => ({
222
+ '@type': 'Question',
223
+ name: item.question,
224
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
225
+ })),
226
+ };
227
+
228
+ const howToSchema: WithContext<HowTo> = {
229
+ '@context': 'https://schema.org',
230
+ '@type': 'HowTo',
231
+ name: title,
232
+ description: description,
233
+ step: howTo.map((step) => ({
234
+ '@type': 'HowToStep',
235
+ name: step.name,
236
+ text: step.text,
237
+ })),
238
+ };
239
+
240
+ const appSchema: WithContext<SoftwareApplication> = {
241
+ '@context': 'https://schema.org',
242
+ '@type': 'SoftwareApplication',
243
+ name: title,
244
+ description: description,
245
+ applicationCategory: 'FinanceApplication',
246
+ operatingSystem: 'All',
247
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'CNY' },
248
+ inLanguage: 'zh',
249
+ };
250
+
251
+ export const content: ToolLocaleContent<TipCalculatorUI> = {
252
+ slug,
253
+ title,
254
+ description,
255
+ ui,
256
+ seo,
257
+ faq,
258
+ faqTitle: "常见问题",
259
+ bibliography,
260
+ bibliographyTitle: "来源与参考文献",
261
+ howTo,
262
+ howToTitle: "如何使用计算器",
263
+ schemas: [faqSchema, howToSchema, appSchema],
264
+ };
@@ -37,9 +37,21 @@ export const tipCalculator: TravelToolEntry<TipCalculatorUI> = {
37
37
  fg: 'mdi:earth',
38
38
  },
39
39
  i18n: {
40
- es: () => import('./i18n/es').then((m) => m.content),
40
+ de: () => import('./i18n/de').then((m) => m.content),
41
41
  en: () => import('./i18n/en').then((m) => m.content),
42
+ es: () => import('./i18n/es').then((m) => m.content),
42
43
  fr: () => import('./i18n/fr').then((m) => m.content),
44
+ id: () => import('./i18n/id').then((m) => m.content),
45
+ it: () => import('./i18n/it').then((m) => m.content),
46
+ ja: () => import('./i18n/ja').then((m) => m.content),
47
+ ko: () => import('./i18n/ko').then((m) => m.content),
48
+ nl: () => import('./i18n/nl').then((m) => m.content),
49
+ pl: () => import('./i18n/pl').then((m) => m.content),
50
+ pt: () => import('./i18n/pt').then((m) => m.content),
51
+ ru: () => import('./i18n/ru').then((m) => m.content),
52
+ sv: () => import('./i18n/sv').then((m) => m.content),
53
+ tr: () => import('./i18n/tr').then((m) => m.content),
54
+ zh: () => import('./i18n/zh').then((m) => m.content),
43
55
  },
44
56
  };
45
57
 
@@ -1,14 +0,0 @@
1
- ---
2
- import { Bibliography as SharedBibliography } from "@jjlmoya/utils-shared";
3
- import { optimalRoutes } from "./index";
4
- import type { KnownLocale } from "../../types";
5
-
6
- interface Props {
7
- locale?: KnownLocale;
8
- }
9
-
10
- const { locale = "es" } = Astro.props;
11
- const content = await optimalRoutes.i18n[locale]?.();
12
- ---
13
-
14
- {content && <SharedBibliography links={content.bibliography} />}