diff --git a/client/package.json b/client/package.json index 4a39c02..d2d4dcd 100644 --- a/client/package.json +++ b/client/package.json @@ -22,7 +22,9 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "react-i18next": "^17.0.2", + "react-markdown": "^10.1.0", "react-router-dom": "^7.14.0", + "remark-gfm": "^4.0.1", "yaml": "^2.8.3" }, "devDependencies": { diff --git a/client/src/api/client.ts b/client/src/api/client.ts index 9cfa713..e671eef 100644 --- a/client/src/api/client.ts +++ b/client/src/api/client.ts @@ -90,7 +90,7 @@ export const snippets = { get(id: string): Promise { return request(`/snippets/${id}`); }, - create(payload: Pick & { description?: string }): Promise { + create(payload: Pick & { description?: string }): Promise { return request('/snippets', { method: 'POST', body: JSON.stringify(payload), @@ -98,7 +98,7 @@ export const snippets = { }, update( id: string, - patch: Partial>, + patch: Partial>, ): Promise { return request(`/snippets/${id}`, { method: 'PATCH', diff --git a/client/src/api/types.ts b/client/src/api/types.ts index 3c3af0d..e30b0e4 100644 --- a/client/src/api/types.ts +++ b/client/src/api/types.ts @@ -36,7 +36,8 @@ export interface Credential { export interface Snippet { id: string; - name: string; + alias: string; + title: string; description: string | null; code: string; createdAt: string; diff --git a/client/src/i18n/locales/en.json b/client/src/i18n/locales/en.json index 5388a0c..2ee8d9a 100644 --- a/client/src/i18n/locales/en.json +++ b/client/src/i18n/locales/en.json @@ -224,16 +224,20 @@ "action_cancel": "Cancel", "create_title": "New Snippet", "edit_title": "Edit Snippet", - "form_name": "Name", - "form_name_placeholder": "e.g. clickLoginButton", - "form_name_required": "Name is required", + "form_alias": "Alias", + "form_alias_placeholder": "e.g. clickLoginButton", + "form_alias_required": "Alias is required", + "form_title": "Title", + "form_title_placeholder": "e.g. Click Login Button", + "form_title_required": "Title is required", "form_description": "Description", "form_description_placeholder": "What does this snippet do?", "form_code": "Code", "form_code_placeholder": "await page.click('#login-btn');", "form_code_required": "Code is required", "field_id": "ID", - "field_name": "Name", + "field_alias": "Alias", + "field_title": "Title", "field_description": "Description", "field_created": "Created", "field_updated": "Updated", diff --git a/client/src/pages/snippet/CreateSnippetPage.tsx b/client/src/pages/snippet/CreateSnippetPage.tsx index 8759d23..f047c7c 100644 --- a/client/src/pages/snippet/CreateSnippetPage.tsx +++ b/client/src/pages/snippet/CreateSnippetPage.tsx @@ -11,10 +11,12 @@ export function CreateSnippetPage() { const navigate = useNavigate(); const toast = useToast(); - const [name, setName] = useState(''); + const [alias, setAlias] = useState(''); + const [title, setTitle] = useState(''); const [description, setDescription] = useState(''); const [code, setCode] = useState(''); - const [nameError, setNameError] = useState(''); + const [aliasError, setAliasError] = useState(''); + const [titleError, setTitleError] = useState(''); const [codeError, setCodeError] = useState(''); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); @@ -22,8 +24,12 @@ export function CreateSnippetPage() { const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); let valid = true; - if (!name.trim()) { - setNameError(t('snippets.form_name_required')); + if (!alias.trim()) { + setAliasError(t('snippets.form_alias_required')); + valid = false; + } + if (!title.trim()) { + setTitleError(t('snippets.form_title_required')); valid = false; } if (!code.trim()) { @@ -35,7 +41,8 @@ export function CreateSnippetPage() { setError(null); try { const snippet = await snippets.create({ - name: name.trim(), + alias: alias.trim(), + title: title.trim(), description: description.trim() || undefined, code: code.trim(), }); @@ -65,23 +72,37 @@ export function CreateSnippetPage() {
{ - setName(e.target.value); - setNameError(''); + setAlias(e.target.value); + setAliasError(''); }} - error={nameError || undefined} + error={aliasError || undefined} required autoFocus /> setDescription(e.target.value)} + label={t('snippets.form_title')} + placeholder={t('snippets.form_title_placeholder')} + value={title} + onChange={(e) => { + setTitle(e.target.value); + setTitleError(''); + }} + error={titleError || undefined} + required /> +
+ + +