Files
smoothschedule/frontend/src/components/EmailTemplateSelector.tsx
poduck b3e2c1f324 refactor(frontend): Remove '/api' prefix from all API calls to align with backend URL convention
- Updated all API endpoint strings in 'frontend/src' (via sed and manual fixes) to remove the '/api/' prefix.
- Manually fixed 'Timeline.tsx' absolute URLs to use the 'api' subdomain and correct path.
- Manually fixed 'useAuth.ts' logout fetch URLs.
- Updated 'HelpApiDocs.tsx' sandbox URL.
- This change, combined with the backend URL update, fully transitions the application to use subdomain-based routing (e.g., 'http://api.lvh.me:8000/resource/') instead of path-prefix routing (e.g., 'http://api.lvh.me:8000/api/resource/').
2025-12-01 02:14:17 -05:00

113 lines
4.0 KiB
TypeScript

import React from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery } from '@tanstack/react-query';
import { Mail, ExternalLink } from 'lucide-react';
import api from '../api/client';
import { EmailTemplate } from '../types';
interface EmailTemplateSelectorProps {
value: string | number | undefined;
onChange: (templateId: string | number | undefined) => void;
category?: string;
placeholder?: string;
required?: boolean;
disabled?: boolean;
className?: string;
}
const EmailTemplateSelector: React.FC<EmailTemplateSelectorProps> = ({
value,
onChange,
category,
placeholder,
required = false,
disabled = false,
className = '',
}) => {
const { t } = useTranslation();
// Fetch email templates
const { data: templates = [], isLoading } = useQuery<EmailTemplate[]>({
queryKey: ['email-templates-list', category],
queryFn: async () => {
const params = new URLSearchParams();
if (category) params.append('category', category);
const { data } = await api.get(`/email-templates/?${params.toString()}`);
return data.map((t: any) => ({
id: String(t.id),
name: t.name,
description: t.description,
category: t.category,
scope: t.scope,
updatedAt: t.updated_at,
}));
},
});
const selectedTemplate = templates.find(t => String(t.id) === String(value));
return (
<div className={`space-y-2 ${className}`}>
<div className="relative">
<select
value={value || ''}
onChange={(e) => onChange(e.target.value || undefined)}
disabled={disabled || isLoading}
className="w-full pl-10 pr-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-500 focus:border-brand-500 disabled:opacity-50 disabled:cursor-not-allowed appearance-none"
>
<option value="">
{isLoading
? t('common.loading', 'Loading...')
: placeholder || t('emailTemplates.selectTemplate', 'Select a template...')}
</option>
{templates.map((template) => (
<option key={template.id} value={template.id}>
{template.name}
{template.category !== 'OTHER' && ` (${template.category})`}
</option>
))}
</select>
<Mail className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-gray-400 pointer-events-none" />
<div className="absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none">
<svg className="h-5 w-5 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</div>
</div>
{/* Selected template info */}
{selectedTemplate && (
<div className="flex items-center justify-between p-2 bg-gray-50 dark:bg-gray-800 rounded text-sm">
<span className="text-gray-600 dark:text-gray-400 truncate">
{selectedTemplate.description || selectedTemplate.name}
</span>
<a
href={`#/email-templates`}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-1 text-brand-600 dark:text-brand-400 hover:underline ml-2 flex-shrink-0"
>
<ExternalLink className="h-3 w-3" />
{t('common.edit', 'Edit')}
</a>
</div>
)}
{/* Empty state with link to create */}
{!isLoading && templates.length === 0 && (
<div className="text-sm text-gray-500 dark:text-gray-400">
{t('emailTemplates.noTemplatesYet', 'No email templates yet.')}{' '}
<a
href="#/email-templates"
className="text-brand-600 dark:text-brand-400 hover:underline"
>
{t('emailTemplates.createFirst', 'Create your first template')}
</a>
</div>
)}
</div>
);
};
export default EmailTemplateSelector;