summaryrefslogtreecommitdiff
path: root/components/common/selectors/place-of-shipping/place-of-shipping-selector.tsx
blob: 635323650d7846b400de56f95529d15f94d0660a (plain)
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



'use client'

/**
 * 선적지/하역지 선택기
 *
 * placeOfShipping 테이블 기준으로 선적지/하역지에 쓰이는 장소코드 및 장소명 선택
 */

import { Select, SelectItem, SelectContent } from "@/components/ui/select"
import { SelectTrigger } from "@/components/ui/select"
import { SelectValue } from "@/components/ui/select"
import { Input } from "@/components/ui/input"
import { useState, useEffect, useMemo } from "react"
import { getPlaceOfShippingForSelection } from "./place-of-shipping-service"

interface PlaceOfShippingData {
  code: string
  description: string
}

interface PlaceOfShippingSelectorProps {
  value?: string
  onValueChange?: (value: string) => void
  placeholder?: string
  disabled?: boolean
  className?: string
}

export function PlaceOfShippingSelector({
  value = "",
  onValueChange,
  placeholder = "선적지/하역지 선택",
  disabled = false,
  className
}: PlaceOfShippingSelectorProps) {
  const [placeOfShippingData, setPlaceOfShippingData] = useState<PlaceOfShippingData[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [searchTerm, setSearchTerm] = useState("")

  const filteredData = useMemo(() => {
    if (!searchTerm) return placeOfShippingData
    return placeOfShippingData.filter(item =>
      item.code.toLowerCase().includes(searchTerm.toLowerCase()) ||
      item.description.toLowerCase().includes(searchTerm.toLowerCase())
    )
  }, [placeOfShippingData, searchTerm])

  useEffect(() => {
    const loadData = async () => {
      try {
        const data = await getPlaceOfShippingForSelection()
        setPlaceOfShippingData(data)
      } catch (error) {
        console.error('선적지/하역지 데이터 로드 실패:', error)
        setPlaceOfShippingData([])
      } finally {
        setIsLoading(false)
      }
    }

    loadData()
  }, [])

  return (
    <div className="space-y-2">
      <Input
        placeholder="검색..."
        value={searchTerm}
        onChange={(e) => setSearchTerm(e.target.value)}
        className="w-full"
      />
      <Select
        value={value}
        onValueChange={onValueChange}
        disabled={disabled || isLoading}
      >
        <SelectTrigger className={className}>
          <SelectValue placeholder={isLoading ? "로딩 중..." : placeholder} />
        </SelectTrigger>
        <SelectContent>
          {filteredData.length === 0 && searchTerm ? (
            <div className="p-2 text-sm text-muted-foreground">
              검색 결과가 없습니다
            </div>
          ) : (
            filteredData.map((item) => (
              <SelectItem key={item.code} value={item.code}>
                {item.code} {item.description}
              </SelectItem>
            ))
          )}
        </SelectContent>
      </Select>
    </div>
  )
}