refactor(notes): use shared types and interfaces in components
This commit is contained in:
1 parent
2975b80a94
commit
557e48116a
12 files changed
+16
-57
No files matched your search
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import type { Note } from './types'
|
import type { NotePatch } from './types/note'
|
||||||
import { useNotes } from './hooks/useNotes'
|
import { useNotes } from './hooks/useNotes'
|
||||||
import NoteList from './components/NoteList'
|
import NoteList from './components/NoteList'
|
||||||
import NoteEditor from './components/NoteEditor'
|
import NoteEditor from './components/NoteEditor'
|
||||||
@@ -21,7 +21,7 @@ function App() {
|
|||||||
setCreating(false)
|
setCreating(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUpdate = (id: number, patch: Partial<Pick<Note, 'title' | 'content'>>) => {
|
const handleUpdate = (id: number, patch: NotePatch) => {
|
||||||
updateNote(id, patch)
|
updateNote(id, patch)
|
||||||
setSelectedId(null)
|
setSelectedId(null)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
interface DeleteModalProps {
|
import type { DeleteModalProps } from '../interfaces/delete-modal'
|
||||||
open: boolean
|
|
||||||
title: string
|
|
||||||
onConfirm: () => void
|
|
||||||
onCancel: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
function DeleteModal({ open, title, onConfirm, onCancel }: DeleteModalProps) {
|
function DeleteModal({ open, title, onConfirm, onCancel }: DeleteModalProps) {
|
||||||
if (!open) return null
|
if (!open) return null
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
interface FloatingButtonProps {
|
import type { FloatingButtonProps } from '../interfaces/floating-button'
|
||||||
onClick: () => void
|
|
||||||
label?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
function FloatingButton({ onClick, label = 'Créer une note' }: FloatingButtonProps) {
|
function FloatingButton({ onClick, label = 'Créer une note' }: FloatingButtonProps) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { fireEvent, render, screen } from '@testing-library/react'
|
import { fireEvent, render, screen } from '@testing-library/react'
|
||||||
import { describe, expect, it, vi } from 'vitest'
|
import { describe, expect, it, vi } from 'vitest'
|
||||||
import NoteEditor from './NoteEditor'
|
import NoteEditor from './NoteEditor'
|
||||||
import type { Note } from '../types'
|
import type { Note } from '../types/note'
|
||||||
|
|
||||||
const note: Note = { id: 42, title: 'Courses', content: 'Lait\nOeufs' }
|
const note: Note = { id: 42, title: 'Courses', content: 'Lait\nOeufs' }
|
||||||
|
|
||||||
|
|||||||
@@ -1,33 +1,10 @@
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import type { Note } from '../types'
|
import type {
|
||||||
|
NoteEditorProps,
|
||||||
|
NoteFormProps,
|
||||||
|
} from '../interfaces/note-editor'
|
||||||
import DeleteModal from './DeleteModal'
|
import DeleteModal from './DeleteModal'
|
||||||
|
|
||||||
interface EditEditorProps {
|
|
||||||
mode: 'edit'
|
|
||||||
note: Note
|
|
||||||
onUpdate: (id: number, patch: Partial<Pick<Note, 'title' | 'content'>>) => void
|
|
||||||
onDelete: (id: number) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CreateEditorProps {
|
|
||||||
mode: 'create'
|
|
||||||
onCreate: (title: string, content: string) => void
|
|
||||||
onCancelCreate: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
type NoteEditorProps = EditEditorProps | CreateEditorProps
|
|
||||||
|
|
||||||
interface NoteFormProps {
|
|
||||||
title: string
|
|
||||||
content: string
|
|
||||||
titleMissing: boolean
|
|
||||||
cancelLabel: string
|
|
||||||
onTitleChange: (value: string) => void
|
|
||||||
onContentChange: (value: string) => void
|
|
||||||
onCancel: () => void
|
|
||||||
onSubmit: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
const TITLE_REQUIRED_MESSAGE = 'Le titre est obligatoire.'
|
const TITLE_REQUIRED_MESSAGE = 'Le titre est obligatoire.'
|
||||||
|
|
||||||
function NoteForm({
|
function NoteForm({
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { fireEvent, render, screen } from '@testing-library/react'
|
import { fireEvent, render, screen } from '@testing-library/react'
|
||||||
import { describe, expect, it, vi } from 'vitest'
|
import { describe, expect, it, vi } from 'vitest'
|
||||||
import NoteList from './NoteList'
|
import NoteList from './NoteList'
|
||||||
import type { Note } from '../types'
|
import type { Note } from '../types/note'
|
||||||
|
|
||||||
const notes: Note[] = [
|
const notes: Note[] = [
|
||||||
{ id: 3, title: 'Courses', content: 'Lait' },
|
{ id: 3, title: 'Courses', content: 'Lait' },
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
import type { Note } from '../types'
|
import type { NoteListProps } from '../interfaces/note-list'
|
||||||
|
|
||||||
interface NoteListProps {
|
|
||||||
notes: Note[]
|
|
||||||
onSelect: (id: number) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
const EMPTY_MESSAGE = 'Aucune note pour le moment.\nTouchez + pour en créer une.'
|
const EMPTY_MESSAGE = 'Aucune note pour le moment.\nTouchez + pour en créer une.'
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { act, renderHook } from '@testing-library/react'
|
|||||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||||
import { useNotes } from './useNotes'
|
import { useNotes } from './useNotes'
|
||||||
import { loadNotes } from '../lib/notesStorage'
|
import { loadNotes } from '../lib/notesStorage'
|
||||||
import type { Note } from '../types'
|
import type { Note } from '../types/note'
|
||||||
|
|
||||||
describe('useNotes', () => {
|
describe('useNotes', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import type { Note } from '../types'
|
import type { Note, NotePatch } from '../types/note'
|
||||||
import { loadNotes, saveNotes } from '../lib/notesStorage'
|
import { loadNotes, saveNotes } from '../lib/notesStorage'
|
||||||
|
|
||||||
export function useNotes() {
|
export function useNotes() {
|
||||||
@@ -15,7 +15,7 @@ export function useNotes() {
|
|||||||
return note
|
return note
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const updateNote = useCallback((id: number, patch: Partial<Pick<Note, 'title' | 'content'>>) => {
|
const updateNote = useCallback((id: number, patch: NotePatch) => {
|
||||||
setNotes((current) => current.map((note) => (note.id === id ? { ...note, ...patch } : note)))
|
setNotes((current) => current.map((note) => (note.id === id ? { ...note, ...patch } : note)))
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { beforeEach, describe, expect, it } from 'vitest'
|
import { beforeEach, describe, expect, it } from 'vitest'
|
||||||
import { loadNotes, saveNotes } from './notesStorage'
|
import { loadNotes, saveNotes } from './notesStorage'
|
||||||
import type { Note } from '../types'
|
import type { Note } from '../types/note'
|
||||||
|
|
||||||
const STORAGE_KEY = 'notes'
|
const STORAGE_KEY = 'notes'
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Note } from '../types'
|
import type { Note } from '../types/note'
|
||||||
|
|
||||||
const STORAGE_KEY = 'notes'
|
const STORAGE_KEY = 'notes'
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
export interface Note {
|
|
||||||
id: number
|
|
||||||
title: string
|
|
||||||
content: string
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user