@aws505/sheetsite 1.0.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.
- package/README.md +105 -0
- package/dist/components/index.js +1696 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +1630 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/config/index.js +1840 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/index.mjs +1793 -0
- package/dist/config/index.mjs.map +1 -0
- package/dist/data/index.js +1296 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data/index.mjs +1220 -0
- package/dist/data/index.mjs.map +1 -0
- package/dist/index.js +5433 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +5285 -0
- package/dist/index.mjs.map +1 -0
- package/dist/seo/index.js +187 -0
- package/dist/seo/index.js.map +1 -0
- package/dist/seo/index.mjs +155 -0
- package/dist/seo/index.mjs.map +1 -0
- package/dist/theme/index.js +552 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/index.mjs +526 -0
- package/dist/theme/index.mjs.map +1 -0
- package/package.json +96 -0
- package/src/components/index.ts +41 -0
- package/src/components/layout/Footer.tsx +234 -0
- package/src/components/layout/Header.tsx +134 -0
- package/src/components/sections/FAQ.tsx +178 -0
- package/src/components/sections/Gallery.tsx +107 -0
- package/src/components/sections/Hero.tsx +202 -0
- package/src/components/sections/Hours.tsx +225 -0
- package/src/components/sections/Services.tsx +216 -0
- package/src/components/sections/Testimonials.tsx +184 -0
- package/src/components/ui/Button.tsx +158 -0
- package/src/components/ui/Card.tsx +162 -0
- package/src/components/ui/Icons.tsx +508 -0
- package/src/config/index.ts +207 -0
- package/src/config/presets/generic.ts +153 -0
- package/src/config/presets/home-kitchen.ts +154 -0
- package/src/config/presets/index.ts +708 -0
- package/src/config/presets/professional.ts +165 -0
- package/src/config/presets/repair.ts +160 -0
- package/src/config/presets/restaurant.ts +162 -0
- package/src/config/presets/salon.ts +178 -0
- package/src/config/presets/tailor.ts +159 -0
- package/src/config/types.ts +314 -0
- package/src/data/csv-parser.ts +154 -0
- package/src/data/defaults.ts +202 -0
- package/src/data/google-drive.ts +148 -0
- package/src/data/index.ts +535 -0
- package/src/data/sheets.ts +709 -0
- package/src/data/types.ts +379 -0
- package/src/seo/index.ts +272 -0
- package/src/theme/colors.ts +351 -0
- package/src/theme/index.ts +249 -0
|
@@ -0,0 +1,708 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Business Type Presets
|
|
3
|
+
*
|
|
4
|
+
* Pre-configured setups for different business types.
|
|
5
|
+
* Each preset includes theme, pages, SEO, and default content.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { BusinessPreset, BusinessType } from '../types';
|
|
9
|
+
import { tailorPreset } from './tailor';
|
|
10
|
+
import { restaurantPreset } from './restaurant';
|
|
11
|
+
import { homeKitchenPreset } from './home-kitchen';
|
|
12
|
+
import { salonPreset } from './salon';
|
|
13
|
+
import { repairPreset } from './repair';
|
|
14
|
+
import { professionalPreset } from './professional';
|
|
15
|
+
import { genericPreset } from './generic';
|
|
16
|
+
|
|
17
|
+
// Re-export individual presets
|
|
18
|
+
export { tailorPreset } from './tailor';
|
|
19
|
+
export { restaurantPreset } from './restaurant';
|
|
20
|
+
export { homeKitchenPreset } from './home-kitchen';
|
|
21
|
+
export { salonPreset } from './salon';
|
|
22
|
+
export { repairPreset } from './repair';
|
|
23
|
+
export { professionalPreset } from './professional';
|
|
24
|
+
export { genericPreset } from './generic';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Map of all available presets by business type.
|
|
28
|
+
*/
|
|
29
|
+
export const presets: Record<string, BusinessPreset> = {
|
|
30
|
+
// Direct mappings
|
|
31
|
+
'tailor': tailorPreset,
|
|
32
|
+
'restaurant': restaurantPreset,
|
|
33
|
+
'home-kitchen': homeKitchenPreset,
|
|
34
|
+
'salon': salonPreset,
|
|
35
|
+
'shoe-repair': repairPreset,
|
|
36
|
+
'accountant': professionalPreset,
|
|
37
|
+
'generic': genericPreset,
|
|
38
|
+
|
|
39
|
+
// Aliases - map similar business types to their closest preset
|
|
40
|
+
'alterations': tailorPreset,
|
|
41
|
+
'seamstress': tailorPreset,
|
|
42
|
+
'dry-cleaner': tailorPreset,
|
|
43
|
+
|
|
44
|
+
'cafe': restaurantPreset,
|
|
45
|
+
'bakery': homeKitchenPreset,
|
|
46
|
+
'food-truck': restaurantPreset,
|
|
47
|
+
'catering': restaurantPreset,
|
|
48
|
+
|
|
49
|
+
'barbershop': salonPreset,
|
|
50
|
+
'spa': salonPreset,
|
|
51
|
+
'nail-salon': salonPreset,
|
|
52
|
+
'pet-grooming': salonPreset,
|
|
53
|
+
|
|
54
|
+
'craft-seller': homeKitchenPreset,
|
|
55
|
+
'boutique': genericPreset,
|
|
56
|
+
'florist': genericPreset,
|
|
57
|
+
'gift-shop': genericPreset,
|
|
58
|
+
|
|
59
|
+
'cleaning': repairPreset,
|
|
60
|
+
'landscaping': repairPreset,
|
|
61
|
+
'handyman': repairPreset,
|
|
62
|
+
'plumber': repairPreset,
|
|
63
|
+
'electrician': repairPreset,
|
|
64
|
+
'hvac': repairPreset,
|
|
65
|
+
'moving': repairPreset,
|
|
66
|
+
'pest-control': repairPreset,
|
|
67
|
+
|
|
68
|
+
'auto-repair': repairPreset,
|
|
69
|
+
'auto-detail': repairPreset,
|
|
70
|
+
'tire-shop': repairPreset,
|
|
71
|
+
|
|
72
|
+
'lawyer': professionalPreset,
|
|
73
|
+
'real-estate': professionalPreset,
|
|
74
|
+
'insurance': professionalPreset,
|
|
75
|
+
'consulting': professionalPreset,
|
|
76
|
+
|
|
77
|
+
'personal-trainer': genericPreset,
|
|
78
|
+
'yoga-studio': genericPreset,
|
|
79
|
+
'martial-arts': genericPreset,
|
|
80
|
+
'chiropractor': professionalPreset,
|
|
81
|
+
'massage': salonPreset,
|
|
82
|
+
|
|
83
|
+
'tutoring': professionalPreset,
|
|
84
|
+
'music-lessons': genericPreset,
|
|
85
|
+
'photography': genericPreset,
|
|
86
|
+
'videography': genericPreset,
|
|
87
|
+
'event-planning': genericPreset,
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get a preset by business type.
|
|
92
|
+
* Falls back to generic preset if type is not found.
|
|
93
|
+
*/
|
|
94
|
+
export function getPreset(type: BusinessType | string): BusinessPreset {
|
|
95
|
+
return presets[type] || genericPreset;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get a list of all supported business types with their display names.
|
|
100
|
+
*/
|
|
101
|
+
export function getSupportedBusinessTypes(): Array<{ type: BusinessType; name: string; description: string }> {
|
|
102
|
+
const uniquePresets = new Map<string, BusinessPreset>();
|
|
103
|
+
|
|
104
|
+
// Get unique presets (avoid duplicates from aliases)
|
|
105
|
+
for (const preset of Object.values(presets)) {
|
|
106
|
+
if (!uniquePresets.has(preset.type)) {
|
|
107
|
+
uniquePresets.set(preset.type, preset);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return Array.from(uniquePresets.values()).map((preset) => ({
|
|
112
|
+
type: preset.type,
|
|
113
|
+
name: preset.name,
|
|
114
|
+
description: preset.description,
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Business type categories for organization.
|
|
120
|
+
*/
|
|
121
|
+
export const businessCategories = {
|
|
122
|
+
'Service Businesses': [
|
|
123
|
+
'tailor',
|
|
124
|
+
'shoe-repair',
|
|
125
|
+
'dry-cleaner',
|
|
126
|
+
'salon',
|
|
127
|
+
'barbershop',
|
|
128
|
+
'spa',
|
|
129
|
+
'nail-salon',
|
|
130
|
+
'pet-grooming',
|
|
131
|
+
],
|
|
132
|
+
'Food & Beverage': [
|
|
133
|
+
'restaurant',
|
|
134
|
+
'cafe',
|
|
135
|
+
'bakery',
|
|
136
|
+
'food-truck',
|
|
137
|
+
'home-kitchen',
|
|
138
|
+
'catering',
|
|
139
|
+
],
|
|
140
|
+
'Retail': [
|
|
141
|
+
'craft-seller',
|
|
142
|
+
'boutique',
|
|
143
|
+
'florist',
|
|
144
|
+
'gift-shop',
|
|
145
|
+
],
|
|
146
|
+
'Home Services': [
|
|
147
|
+
'cleaning',
|
|
148
|
+
'landscaping',
|
|
149
|
+
'handyman',
|
|
150
|
+
'plumber',
|
|
151
|
+
'electrician',
|
|
152
|
+
'hvac',
|
|
153
|
+
'moving',
|
|
154
|
+
'pest-control',
|
|
155
|
+
],
|
|
156
|
+
'Auto Services': [
|
|
157
|
+
'auto-repair',
|
|
158
|
+
'auto-detail',
|
|
159
|
+
'tire-shop',
|
|
160
|
+
],
|
|
161
|
+
'Professional Services': [
|
|
162
|
+
'accountant',
|
|
163
|
+
'lawyer',
|
|
164
|
+
'real-estate',
|
|
165
|
+
'insurance',
|
|
166
|
+
'consulting',
|
|
167
|
+
],
|
|
168
|
+
'Health & Wellness': [
|
|
169
|
+
'personal-trainer',
|
|
170
|
+
'yoga-studio',
|
|
171
|
+
'martial-arts',
|
|
172
|
+
'chiropractor',
|
|
173
|
+
'massage',
|
|
174
|
+
],
|
|
175
|
+
'Education & Creative': [
|
|
176
|
+
'tutoring',
|
|
177
|
+
'music-lessons',
|
|
178
|
+
'photography',
|
|
179
|
+
'videography',
|
|
180
|
+
'event-planning',
|
|
181
|
+
],
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Recommend a business type based on keywords.
|
|
186
|
+
* Enhanced with comprehensive keyword mappings for common Google Maps categories
|
|
187
|
+
* and variations found in scraped lead data.
|
|
188
|
+
*
|
|
189
|
+
* @param keywords - Array of keywords (business name, category, description)
|
|
190
|
+
* @returns The recommended BusinessType
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```ts
|
|
194
|
+
* recommendBusinessType(['tailor', 'alterations']) // => 'tailor'
|
|
195
|
+
* recommendBusinessType(['Pizza Restaurant']) // => 'restaurant'
|
|
196
|
+
* recommendBusinessType(["Maria's Hair Salon"]) // => 'salon'
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
export function recommendBusinessType(keywords: string[]): BusinessType {
|
|
200
|
+
const lowerKeywords = keywords.map((k) => k.toLowerCase());
|
|
201
|
+
|
|
202
|
+
// Comprehensive keyword mapping - ordered by specificity
|
|
203
|
+
// More specific matches should come first
|
|
204
|
+
const keywordMap: Record<string, BusinessType> = {
|
|
205
|
+
// ==========================================================================
|
|
206
|
+
// TAILOR / ALTERATIONS
|
|
207
|
+
// ==========================================================================
|
|
208
|
+
'tailor': 'tailor',
|
|
209
|
+
'tailor shop': 'tailor',
|
|
210
|
+
'tailoring': 'tailor',
|
|
211
|
+
'alterations': 'tailor',
|
|
212
|
+
'alteration': 'tailor',
|
|
213
|
+
'seamstress': 'tailor',
|
|
214
|
+
'sewing': 'tailor',
|
|
215
|
+
'hemming': 'tailor',
|
|
216
|
+
'clothing repair': 'tailor',
|
|
217
|
+
'suit alterations': 'tailor',
|
|
218
|
+
'dress alterations': 'tailor',
|
|
219
|
+
'wedding dress': 'tailor',
|
|
220
|
+
'bridal alterations': 'tailor',
|
|
221
|
+
'custom suits': 'tailor',
|
|
222
|
+
'bespoke': 'tailor',
|
|
223
|
+
|
|
224
|
+
// Dry cleaning (maps to tailor preset)
|
|
225
|
+
'dry cleaner': 'dry-cleaner',
|
|
226
|
+
'dry cleaning': 'dry-cleaner',
|
|
227
|
+
'laundry': 'dry-cleaner',
|
|
228
|
+
'laundromat': 'dry-cleaner',
|
|
229
|
+
'cleaners': 'dry-cleaner',
|
|
230
|
+
|
|
231
|
+
// ==========================================================================
|
|
232
|
+
// RESTAURANT / FOOD SERVICE
|
|
233
|
+
// ==========================================================================
|
|
234
|
+
'restaurant': 'restaurant',
|
|
235
|
+
'dining': 'restaurant',
|
|
236
|
+
'eatery': 'restaurant',
|
|
237
|
+
'bistro': 'restaurant',
|
|
238
|
+
'brasserie': 'restaurant',
|
|
239
|
+
'trattoria': 'restaurant',
|
|
240
|
+
'pizzeria': 'restaurant',
|
|
241
|
+
'pizza': 'restaurant',
|
|
242
|
+
'mexican restaurant': 'restaurant',
|
|
243
|
+
'italian restaurant': 'restaurant',
|
|
244
|
+
'chinese restaurant': 'restaurant',
|
|
245
|
+
'thai restaurant': 'restaurant',
|
|
246
|
+
'indian restaurant': 'restaurant',
|
|
247
|
+
'japanese restaurant': 'restaurant',
|
|
248
|
+
'sushi': 'restaurant',
|
|
249
|
+
'ramen': 'restaurant',
|
|
250
|
+
'pho': 'restaurant',
|
|
251
|
+
'taqueria': 'restaurant',
|
|
252
|
+
'burrito': 'restaurant',
|
|
253
|
+
'burger': 'restaurant',
|
|
254
|
+
'steakhouse': 'restaurant',
|
|
255
|
+
'seafood': 'restaurant',
|
|
256
|
+
'grill': 'restaurant',
|
|
257
|
+
'bbq': 'restaurant',
|
|
258
|
+
'barbecue': 'restaurant',
|
|
259
|
+
'diner': 'restaurant',
|
|
260
|
+
'deli': 'restaurant',
|
|
261
|
+
'sandwich': 'restaurant',
|
|
262
|
+
'sub shop': 'restaurant',
|
|
263
|
+
|
|
264
|
+
// Cafe / Coffee
|
|
265
|
+
'cafe': 'cafe',
|
|
266
|
+
'café': 'cafe',
|
|
267
|
+
'coffee shop': 'cafe',
|
|
268
|
+
'coffee house': 'cafe',
|
|
269
|
+
'coffeehouse': 'cafe',
|
|
270
|
+
'espresso': 'cafe',
|
|
271
|
+
'tea house': 'cafe',
|
|
272
|
+
'tea room': 'cafe',
|
|
273
|
+
'juice bar': 'cafe',
|
|
274
|
+
'smoothie': 'cafe',
|
|
275
|
+
|
|
276
|
+
// Food truck
|
|
277
|
+
'food truck': 'food-truck',
|
|
278
|
+
'food cart': 'food-truck',
|
|
279
|
+
'mobile food': 'food-truck',
|
|
280
|
+
|
|
281
|
+
// Catering
|
|
282
|
+
'catering': 'catering',
|
|
283
|
+
'caterer': 'catering',
|
|
284
|
+
'event catering': 'catering',
|
|
285
|
+
|
|
286
|
+
// ==========================================================================
|
|
287
|
+
// BAKERY / HOME KITCHEN
|
|
288
|
+
// ==========================================================================
|
|
289
|
+
'bakery': 'bakery',
|
|
290
|
+
'baker': 'bakery',
|
|
291
|
+
'baking': 'bakery',
|
|
292
|
+
'bread': 'bakery',
|
|
293
|
+
'pastry': 'bakery',
|
|
294
|
+
'pastries': 'bakery',
|
|
295
|
+
'patisserie': 'bakery',
|
|
296
|
+
'donut': 'bakery',
|
|
297
|
+
'doughnut': 'bakery',
|
|
298
|
+
'bagel': 'bakery',
|
|
299
|
+
|
|
300
|
+
// Home kitchen / Cottage food
|
|
301
|
+
'home kitchen': 'home-kitchen',
|
|
302
|
+
'cottage food': 'home-kitchen',
|
|
303
|
+
'homemade': 'home-kitchen',
|
|
304
|
+
'home baked': 'home-kitchen',
|
|
305
|
+
'cookies': 'home-kitchen',
|
|
306
|
+
'cakes': 'home-kitchen',
|
|
307
|
+
'cupcakes': 'home-kitchen',
|
|
308
|
+
'custom cakes': 'home-kitchen',
|
|
309
|
+
'wedding cakes': 'home-kitchen',
|
|
310
|
+
'desserts': 'home-kitchen',
|
|
311
|
+
'tamales': 'home-kitchen',
|
|
312
|
+
'empanadas': 'home-kitchen',
|
|
313
|
+
'meal prep': 'home-kitchen',
|
|
314
|
+
|
|
315
|
+
// ==========================================================================
|
|
316
|
+
// SALON / BEAUTY
|
|
317
|
+
// ==========================================================================
|
|
318
|
+
'salon': 'salon',
|
|
319
|
+
'hair salon': 'salon',
|
|
320
|
+
'hair stylist': 'salon',
|
|
321
|
+
'hairdresser': 'salon',
|
|
322
|
+
'hairstylist': 'salon',
|
|
323
|
+
'beauty salon': 'salon',
|
|
324
|
+
'beauty parlor': 'salon',
|
|
325
|
+
'beautician': 'salon',
|
|
326
|
+
'cosmetologist': 'salon',
|
|
327
|
+
'hair cutting': 'salon',
|
|
328
|
+
'haircut': 'salon',
|
|
329
|
+
'hair coloring': 'salon',
|
|
330
|
+
'highlights': 'salon',
|
|
331
|
+
'blowout': 'salon',
|
|
332
|
+
'extensions': 'salon',
|
|
333
|
+
'braiding': 'salon',
|
|
334
|
+
'weave': 'salon',
|
|
335
|
+
'locs': 'salon',
|
|
336
|
+
'dreadlocks': 'salon',
|
|
337
|
+
|
|
338
|
+
// Barbershop
|
|
339
|
+
'barber': 'barbershop',
|
|
340
|
+
'barbershop': 'barbershop',
|
|
341
|
+
'barber shop': 'barbershop',
|
|
342
|
+
"men's haircut": 'barbershop',
|
|
343
|
+
'fade': 'barbershop',
|
|
344
|
+
'lineup': 'barbershop',
|
|
345
|
+
|
|
346
|
+
// Spa
|
|
347
|
+
'spa': 'spa',
|
|
348
|
+
'day spa': 'spa',
|
|
349
|
+
'med spa': 'spa',
|
|
350
|
+
'medical spa': 'spa',
|
|
351
|
+
'facial': 'spa',
|
|
352
|
+
'facials': 'spa',
|
|
353
|
+
'skincare': 'spa',
|
|
354
|
+
'esthetician': 'spa',
|
|
355
|
+
'aesthetician': 'spa',
|
|
356
|
+
'waxing': 'spa',
|
|
357
|
+
'laser hair': 'spa',
|
|
358
|
+
|
|
359
|
+
// Nail salon
|
|
360
|
+
'nail salon': 'nail-salon',
|
|
361
|
+
'nail': 'nail-salon',
|
|
362
|
+
'nails': 'nail-salon',
|
|
363
|
+
'manicure': 'nail-salon',
|
|
364
|
+
'pedicure': 'nail-salon',
|
|
365
|
+
'gel nails': 'nail-salon',
|
|
366
|
+
'acrylic nails': 'nail-salon',
|
|
367
|
+
|
|
368
|
+
// Massage
|
|
369
|
+
'massage': 'massage',
|
|
370
|
+
'massage therapy': 'massage',
|
|
371
|
+
'massage therapist': 'massage',
|
|
372
|
+
'deep tissue': 'massage',
|
|
373
|
+
'swedish massage': 'massage',
|
|
374
|
+
'thai massage': 'massage',
|
|
375
|
+
'sports massage': 'massage',
|
|
376
|
+
'reflexology': 'massage',
|
|
377
|
+
|
|
378
|
+
// Pet grooming
|
|
379
|
+
'pet grooming': 'pet-grooming',
|
|
380
|
+
'dog grooming': 'pet-grooming',
|
|
381
|
+
'pet groomer': 'pet-grooming',
|
|
382
|
+
'dog groomer': 'pet-grooming',
|
|
383
|
+
'cat grooming': 'pet-grooming',
|
|
384
|
+
'mobile grooming': 'pet-grooming',
|
|
385
|
+
|
|
386
|
+
// ==========================================================================
|
|
387
|
+
// REPAIR / SHOE REPAIR
|
|
388
|
+
// ==========================================================================
|
|
389
|
+
'shoe repair': 'shoe-repair',
|
|
390
|
+
'shoe shop': 'shoe-repair',
|
|
391
|
+
'cobbler': 'shoe-repair',
|
|
392
|
+
'leather repair': 'shoe-repair',
|
|
393
|
+
'boot repair': 'shoe-repair',
|
|
394
|
+
'heel repair': 'shoe-repair',
|
|
395
|
+
'sole repair': 'shoe-repair',
|
|
396
|
+
'shoe shine': 'shoe-repair',
|
|
397
|
+
'luggage repair': 'shoe-repair',
|
|
398
|
+
'purse repair': 'shoe-repair',
|
|
399
|
+
'bag repair': 'shoe-repair',
|
|
400
|
+
|
|
401
|
+
// ==========================================================================
|
|
402
|
+
// HOME SERVICES
|
|
403
|
+
// ==========================================================================
|
|
404
|
+
// Cleaning
|
|
405
|
+
'cleaning': 'cleaning',
|
|
406
|
+
'cleaning service': 'cleaning',
|
|
407
|
+
'house cleaning': 'cleaning',
|
|
408
|
+
'home cleaning': 'cleaning',
|
|
409
|
+
'maid service': 'cleaning',
|
|
410
|
+
'maid': 'cleaning',
|
|
411
|
+
'janitorial': 'cleaning',
|
|
412
|
+
'carpet cleaning': 'cleaning',
|
|
413
|
+
'window cleaning': 'cleaning',
|
|
414
|
+
'pressure washing': 'cleaning',
|
|
415
|
+
'power washing': 'cleaning',
|
|
416
|
+
|
|
417
|
+
// Landscaping
|
|
418
|
+
'landscaping': 'landscaping',
|
|
419
|
+
'landscaper': 'landscaping',
|
|
420
|
+
'lawn care': 'landscaping',
|
|
421
|
+
'lawn service': 'landscaping',
|
|
422
|
+
'lawn mowing': 'landscaping',
|
|
423
|
+
'gardening': 'landscaping',
|
|
424
|
+
'gardener': 'landscaping',
|
|
425
|
+
'tree service': 'landscaping',
|
|
426
|
+
'tree trimming': 'landscaping',
|
|
427
|
+
'irrigation': 'landscaping',
|
|
428
|
+
'sprinkler': 'landscaping',
|
|
429
|
+
|
|
430
|
+
// Handyman
|
|
431
|
+
'handyman': 'handyman',
|
|
432
|
+
'handy man': 'handyman',
|
|
433
|
+
'home repair': 'handyman',
|
|
434
|
+
'home maintenance': 'handyman',
|
|
435
|
+
'general contractor': 'handyman',
|
|
436
|
+
'remodeling': 'handyman',
|
|
437
|
+
'renovation': 'handyman',
|
|
438
|
+
|
|
439
|
+
// Plumber
|
|
440
|
+
'plumber': 'plumber',
|
|
441
|
+
'plumbing': 'plumber',
|
|
442
|
+
'plumber service': 'plumber',
|
|
443
|
+
'drain': 'plumber',
|
|
444
|
+
'sewer': 'plumber',
|
|
445
|
+
'water heater': 'plumber',
|
|
446
|
+
|
|
447
|
+
// Electrician
|
|
448
|
+
'electrician': 'electrician',
|
|
449
|
+
'electrical': 'electrician',
|
|
450
|
+
'electric': 'electrician',
|
|
451
|
+
'electrical contractor': 'electrician',
|
|
452
|
+
'wiring': 'electrician',
|
|
453
|
+
'panel': 'electrician',
|
|
454
|
+
|
|
455
|
+
// HVAC
|
|
456
|
+
'hvac': 'hvac',
|
|
457
|
+
'air conditioning': 'hvac',
|
|
458
|
+
'ac repair': 'hvac',
|
|
459
|
+
'heating': 'hvac',
|
|
460
|
+
'furnace': 'hvac',
|
|
461
|
+
'ventilation': 'hvac',
|
|
462
|
+
|
|
463
|
+
// Moving
|
|
464
|
+
'moving': 'moving',
|
|
465
|
+
'movers': 'moving',
|
|
466
|
+
'moving company': 'moving',
|
|
467
|
+
'relocation': 'moving',
|
|
468
|
+
'hauling': 'moving',
|
|
469
|
+
'junk removal': 'moving',
|
|
470
|
+
|
|
471
|
+
// Pest control
|
|
472
|
+
'pest control': 'pest-control',
|
|
473
|
+
'exterminator': 'pest-control',
|
|
474
|
+
'pest': 'pest-control',
|
|
475
|
+
'termite': 'pest-control',
|
|
476
|
+
'rodent': 'pest-control',
|
|
477
|
+
'bed bug': 'pest-control',
|
|
478
|
+
|
|
479
|
+
// ==========================================================================
|
|
480
|
+
// AUTO SERVICES
|
|
481
|
+
// ==========================================================================
|
|
482
|
+
'auto repair': 'auto-repair',
|
|
483
|
+
'auto shop': 'auto-repair',
|
|
484
|
+
'car repair': 'auto-repair',
|
|
485
|
+
'mechanic': 'auto-repair',
|
|
486
|
+
'automotive': 'auto-repair',
|
|
487
|
+
'auto service': 'auto-repair',
|
|
488
|
+
'transmission': 'auto-repair',
|
|
489
|
+
'brake': 'auto-repair',
|
|
490
|
+
'oil change': 'auto-repair',
|
|
491
|
+
'tune up': 'auto-repair',
|
|
492
|
+
'smog': 'auto-repair',
|
|
493
|
+
'emissions': 'auto-repair',
|
|
494
|
+
|
|
495
|
+
// Auto detail
|
|
496
|
+
'auto detail': 'auto-detail',
|
|
497
|
+
'car detail': 'auto-detail',
|
|
498
|
+
'auto detailing': 'auto-detail',
|
|
499
|
+
'car detailing': 'auto-detail',
|
|
500
|
+
'car wash': 'auto-detail',
|
|
501
|
+
'mobile detail': 'auto-detail',
|
|
502
|
+
|
|
503
|
+
// Tire shop
|
|
504
|
+
'tire shop': 'tire-shop',
|
|
505
|
+
'tire': 'tire-shop',
|
|
506
|
+
'tires': 'tire-shop',
|
|
507
|
+
'tire service': 'tire-shop',
|
|
508
|
+
'wheel': 'tire-shop',
|
|
509
|
+
'alignment': 'tire-shop',
|
|
510
|
+
|
|
511
|
+
// ==========================================================================
|
|
512
|
+
// PROFESSIONAL SERVICES
|
|
513
|
+
// ==========================================================================
|
|
514
|
+
// Accountant
|
|
515
|
+
'accountant': 'accountant',
|
|
516
|
+
'accounting': 'accountant',
|
|
517
|
+
'bookkeeper': 'accountant',
|
|
518
|
+
'bookkeeping': 'accountant',
|
|
519
|
+
'tax': 'accountant',
|
|
520
|
+
'tax preparation': 'accountant',
|
|
521
|
+
'tax preparer': 'accountant',
|
|
522
|
+
'cpa': 'accountant',
|
|
523
|
+
'enrolled agent': 'accountant',
|
|
524
|
+
|
|
525
|
+
// Lawyer
|
|
526
|
+
'lawyer': 'lawyer',
|
|
527
|
+
'attorney': 'lawyer',
|
|
528
|
+
'law firm': 'lawyer',
|
|
529
|
+
'law office': 'lawyer',
|
|
530
|
+
'legal': 'lawyer',
|
|
531
|
+
'legal services': 'lawyer',
|
|
532
|
+
'immigration': 'lawyer',
|
|
533
|
+
'divorce': 'lawyer',
|
|
534
|
+
'criminal defense': 'lawyer',
|
|
535
|
+
'personal injury': 'lawyer',
|
|
536
|
+
'bankruptcy': 'lawyer',
|
|
537
|
+
'estate planning': 'lawyer',
|
|
538
|
+
'notary': 'lawyer',
|
|
539
|
+
|
|
540
|
+
// Real estate
|
|
541
|
+
'real estate': 'real-estate',
|
|
542
|
+
'realtor': 'real-estate',
|
|
543
|
+
'realty': 'real-estate',
|
|
544
|
+
'real estate agent': 'real-estate',
|
|
545
|
+
'real estate broker': 'real-estate',
|
|
546
|
+
'property management': 'real-estate',
|
|
547
|
+
|
|
548
|
+
// Insurance
|
|
549
|
+
'insurance': 'insurance',
|
|
550
|
+
'insurance agent': 'insurance',
|
|
551
|
+
'insurance agency': 'insurance',
|
|
552
|
+
'insurance broker': 'insurance',
|
|
553
|
+
'life insurance': 'insurance',
|
|
554
|
+
'auto insurance': 'insurance',
|
|
555
|
+
'health insurance': 'insurance',
|
|
556
|
+
'medicare': 'insurance',
|
|
557
|
+
|
|
558
|
+
// Consulting
|
|
559
|
+
'consultant': 'consulting',
|
|
560
|
+
'consulting': 'consulting',
|
|
561
|
+
'business consultant': 'consulting',
|
|
562
|
+
'management consultant': 'consulting',
|
|
563
|
+
'advisor': 'consulting',
|
|
564
|
+
'financial advisor': 'consulting',
|
|
565
|
+
|
|
566
|
+
// ==========================================================================
|
|
567
|
+
// HEALTH & WELLNESS
|
|
568
|
+
// ==========================================================================
|
|
569
|
+
// Personal trainer
|
|
570
|
+
'personal trainer': 'personal-trainer',
|
|
571
|
+
'personal training': 'personal-trainer',
|
|
572
|
+
'fitness trainer': 'personal-trainer',
|
|
573
|
+
'fitness': 'personal-trainer',
|
|
574
|
+
'gym': 'personal-trainer',
|
|
575
|
+
'crossfit': 'personal-trainer',
|
|
576
|
+
'boot camp': 'personal-trainer',
|
|
577
|
+
|
|
578
|
+
// Yoga
|
|
579
|
+
'yoga': 'yoga-studio',
|
|
580
|
+
'yoga studio': 'yoga-studio',
|
|
581
|
+
'yoga instructor': 'yoga-studio',
|
|
582
|
+
'pilates': 'yoga-studio',
|
|
583
|
+
'meditation': 'yoga-studio',
|
|
584
|
+
|
|
585
|
+
// Martial arts
|
|
586
|
+
'martial arts': 'martial-arts',
|
|
587
|
+
'karate': 'martial-arts',
|
|
588
|
+
'taekwondo': 'martial-arts',
|
|
589
|
+
'jiu jitsu': 'martial-arts',
|
|
590
|
+
'bjj': 'martial-arts',
|
|
591
|
+
'mma': 'martial-arts',
|
|
592
|
+
'boxing': 'martial-arts',
|
|
593
|
+
'kickboxing': 'martial-arts',
|
|
594
|
+
'kung fu': 'martial-arts',
|
|
595
|
+
'judo': 'martial-arts',
|
|
596
|
+
'self defense': 'martial-arts',
|
|
597
|
+
|
|
598
|
+
// Chiropractor
|
|
599
|
+
'chiropractor': 'chiropractor',
|
|
600
|
+
'chiropractic': 'chiropractor',
|
|
601
|
+
'spine': 'chiropractor',
|
|
602
|
+
'back pain': 'chiropractor',
|
|
603
|
+
|
|
604
|
+
// ==========================================================================
|
|
605
|
+
// RETAIL
|
|
606
|
+
// ==========================================================================
|
|
607
|
+
// Craft seller
|
|
608
|
+
'craft': 'craft-seller',
|
|
609
|
+
'crafts': 'craft-seller',
|
|
610
|
+
'handmade': 'craft-seller',
|
|
611
|
+
'artisan': 'craft-seller',
|
|
612
|
+
'etsy': 'craft-seller',
|
|
613
|
+
'handcraft': 'craft-seller',
|
|
614
|
+
'jewelry maker': 'craft-seller',
|
|
615
|
+
'candle': 'craft-seller',
|
|
616
|
+
'soap maker': 'craft-seller',
|
|
617
|
+
'pottery': 'craft-seller',
|
|
618
|
+
|
|
619
|
+
// Boutique
|
|
620
|
+
'boutique': 'boutique',
|
|
621
|
+
'clothing store': 'boutique',
|
|
622
|
+
'fashion': 'boutique',
|
|
623
|
+
'apparel': 'boutique',
|
|
624
|
+
'women clothing': 'boutique',
|
|
625
|
+
'consignment': 'boutique',
|
|
626
|
+
'thrift': 'boutique',
|
|
627
|
+
'vintage': 'boutique',
|
|
628
|
+
|
|
629
|
+
// Florist
|
|
630
|
+
'florist': 'florist',
|
|
631
|
+
'flower shop': 'florist',
|
|
632
|
+
'flowers': 'florist',
|
|
633
|
+
'floral': 'florist',
|
|
634
|
+
'floral design': 'florist',
|
|
635
|
+
|
|
636
|
+
// Gift shop
|
|
637
|
+
'gift shop': 'gift-shop',
|
|
638
|
+
'gift store': 'gift-shop',
|
|
639
|
+
'gifts': 'gift-shop',
|
|
640
|
+
'souvenir': 'gift-shop',
|
|
641
|
+
'novelty': 'gift-shop',
|
|
642
|
+
|
|
643
|
+
// ==========================================================================
|
|
644
|
+
// EDUCATION & CREATIVE
|
|
645
|
+
// ==========================================================================
|
|
646
|
+
// Tutoring
|
|
647
|
+
'tutor': 'tutoring',
|
|
648
|
+
'tutoring': 'tutoring',
|
|
649
|
+
'tutoring service': 'tutoring',
|
|
650
|
+
'learning center': 'tutoring',
|
|
651
|
+
'test prep': 'tutoring',
|
|
652
|
+
'sat prep': 'tutoring',
|
|
653
|
+
'math tutor': 'tutoring',
|
|
654
|
+
'english tutor': 'tutoring',
|
|
655
|
+
'homework help': 'tutoring',
|
|
656
|
+
|
|
657
|
+
// Music lessons
|
|
658
|
+
'music lessons': 'music-lessons',
|
|
659
|
+
'music teacher': 'music-lessons',
|
|
660
|
+
'music school': 'music-lessons',
|
|
661
|
+
'piano lessons': 'music-lessons',
|
|
662
|
+
'guitar lessons': 'music-lessons',
|
|
663
|
+
'voice lessons': 'music-lessons',
|
|
664
|
+
'singing lessons': 'music-lessons',
|
|
665
|
+
'drum lessons': 'music-lessons',
|
|
666
|
+
'violin lessons': 'music-lessons',
|
|
667
|
+
|
|
668
|
+
// Photography
|
|
669
|
+
'photographer': 'photography',
|
|
670
|
+
'photography': 'photography',
|
|
671
|
+
'photo studio': 'photography',
|
|
672
|
+
'portrait': 'photography',
|
|
673
|
+
'wedding photographer': 'photography',
|
|
674
|
+
'headshot': 'photography',
|
|
675
|
+
|
|
676
|
+
// Videography
|
|
677
|
+
'videographer': 'videography',
|
|
678
|
+
'videography': 'videography',
|
|
679
|
+
'video production': 'videography',
|
|
680
|
+
'video editor': 'videography',
|
|
681
|
+
'filmmaker': 'videography',
|
|
682
|
+
|
|
683
|
+
// Event planning
|
|
684
|
+
'event planner': 'event-planning',
|
|
685
|
+
'event planning': 'event-planning',
|
|
686
|
+
'wedding planner': 'event-planning',
|
|
687
|
+
'party planner': 'event-planning',
|
|
688
|
+
'event coordinator': 'event-planning',
|
|
689
|
+
'event venue': 'event-planning',
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
// Check each keyword against the map
|
|
693
|
+
for (const keyword of lowerKeywords) {
|
|
694
|
+
// First, try exact matches
|
|
695
|
+
if (keywordMap[keyword]) {
|
|
696
|
+
return keywordMap[keyword];
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// Then, try partial matches (keyword contains key or key contains keyword)
|
|
700
|
+
for (const [key, type] of Object.entries(keywordMap)) {
|
|
701
|
+
if (keyword.includes(key) || key.includes(keyword)) {
|
|
702
|
+
return type;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
return 'generic';
|
|
708
|
+
}
|