# All files / src/hooks useSnippetForm.ts

100% Statements 115/115
88.88% Branches 24/27
100% Functions 7/7
100% Lines 115/115

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    1161x
    1x
    1x
    1x
    1x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    27x
    8x
    8x
    8x
    8x
    8x
    8x
    8x
    27x
    19x
    19x
    19x
    19x
    19x
    19x
    19x
    19x
    27x
    80x
    80x
    80x
    80x
    3x
    3x
    3x
    3x
    3x
    80x
    80x
    1x
    1x
    80x
    80x
    4x
    4x
    4x
    4x
    80x
    80x
    4x
    4x
    4x
    2x
    2x
    4x
    2x
    2x
    4x
    4x
    4x
    4x
    80x
    80x
    7x
    7x
    7x
    7x
    7x
    7x
    7x
    7x
    7x
    80x
    80x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
    80x
     import { useState, useEffect } from 'react'
    import { Snippet, InputParameter } from '@/lib/types'
    import { appConfig, strings } from '@/lib/config'

    export function useSnippetForm(editingSnippet?: Snippet | null, open?: boolean) {
      const [title, setTitle] = useState('')
      const [description, setDescription] = useState('')
      const [language, setLanguage] = useState(appConfig.defaultLanguage)
      const [code, setCode] = useState('')
      const [hasPreview, setHasPreview] = useState(false)
      const [functionName, setFunctionName] = useState('')
      const [inputParameters, setInputParameters] = useState<InputParameter[]>([])
      const [errors, setErrors] = useState<{ title?: string; code?: string }>({})

      /* eslint-disable react-hooks/exhaustive-deps */
      // This effect hydrates the form when the dialog opens or when a different snippet is selected for editing.
      // The state reset is intentional user-facing behavior. We intentionally omit state setters from deps.
      useEffect(() => {
        if (editingSnippet) {
          setTitle(editingSnippet.title)
          setDescription(editingSnippet.description)
          setLanguage(editingSnippet.language)
          setCode(editingSnippet.code)
          setHasPreview(editingSnippet.hasPreview || false)
          setFunctionName(editingSnippet.functionName || '')
          setInputParameters(editingSnippet.inputParameters || [])
        } else {
          setTitle('')
          setDescription('')
          setLanguage(appConfig.defaultLanguage)
          setCode('')
          setHasPreview(false)
          setFunctionName('')
          setInputParameters([])
        }
        setErrors({})
      }, [editingSnippet, open])
      /* eslint-enable react-hooks/exhaustive-deps */

      const handleAddParameter = () => {
        setInputParameters((prev) => [
          ...prev,
          { name: '', type: 'string', defaultValue: '', description: '' },
        ])
      }

      const handleRemoveParameter = (index: number) => {
        setInputParameters((prev) => prev.filter((_, i) => i !== index))
      }

      const handleUpdateParameter = (index: number, field: keyof InputParameter, value: string) => {
        setInputParameters((prev) =>
          prev.map((param, i) => (i === index ? { ...param, [field]: value } : param))
        )
      }

      const validate = () => {
        const newErrors: { title?: string; code?: string } = {}

        if (!title.trim()) {
          newErrors.title = strings.snippetDialog.fields.title.errorMessage
        }
        if (!code.trim()) {
          newErrors.code = strings.snippetDialog.fields.code.errorMessage
        }

        setErrors(newErrors)
        return Object.keys(newErrors).length === 0
      }

      const getFormData = () => ({
        title: title.trim(),
        description: description.trim(),
        language,
        code: code.trim(),
        category: editingSnippet?.category || 'general',
        hasPreview,
        functionName: functionName.trim() || undefined,
        inputParameters: inputParameters.length > 0 ? inputParameters : undefined,
      })

      const resetForm = () => {
        setTitle('')
        setDescription('')
        setLanguage(appConfig.defaultLanguage)
        setCode('')
        setHasPreview(false)
        setFunctionName('')
        setInputParameters([])
        setErrors({})
      }

      return {
        title,
        description,
        language,
        code,
        hasPreview,
        functionName,
        inputParameters,
        errors,
        setTitle,
        setDescription,
        setLanguage,
        setCode,
        setHasPreview,
        setFunctionName,
        handleAddParameter,
        handleRemoveParameter,
        handleUpdateParameter,
        validate,
        getFormData,
        resetForm,
      }
    }