144 lines
3.4 KiB
TypeScript
144 lines
3.4 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { ref, computed } from 'vue'
|
|
|
|
export interface AddressFormData {
|
|
street: string
|
|
zipCode: string
|
|
city: string
|
|
country: string
|
|
}
|
|
|
|
export interface Address {
|
|
id: number
|
|
street: string
|
|
zipCode: string
|
|
city: string
|
|
country: string
|
|
}
|
|
|
|
export const useAddressStore = defineStore('address', () => {
|
|
const addresses = ref<Address[]>([])
|
|
const loading = ref(false)
|
|
const error = ref<string | null>(null)
|
|
|
|
const currentPage = ref(1)
|
|
const pageSize = 20
|
|
|
|
const searchQuery = ref('')
|
|
|
|
function initMockData() {
|
|
addresses.value = [
|
|
{ id: 1, street: 'Main Street 123', zipCode: '10-001', city: 'New York', country: 'United States' },
|
|
{ id: 2, street: 'Oak Avenue 123', zipCode: '90-001', city: 'Los Angeles', country: 'United States' },
|
|
{ id: 3, street: 'Pine Road 123', zipCode: '60-601', city: 'Chicago', country: 'United States' }
|
|
]
|
|
}
|
|
|
|
const filteredAddresses = computed(() => {
|
|
if (!searchQuery.value) return addresses.value
|
|
|
|
const query = searchQuery.value.toLowerCase()
|
|
|
|
return addresses.value.filter(addr =>
|
|
addr.street.toLowerCase().includes(query) ||
|
|
addr.city.toLowerCase().includes(query) ||
|
|
addr.country.toLowerCase().includes(query) ||
|
|
addr.zipCode.toLowerCase().includes(query)
|
|
)
|
|
})
|
|
|
|
const totalItems = computed(() => filteredAddresses.value.length)
|
|
const totalPages = computed(() => Math.ceil(totalItems.value / pageSize))
|
|
|
|
const paginatedAddresses = computed(() => {
|
|
const start = (currentPage.value - 1) * pageSize
|
|
return filteredAddresses.value.slice(start, start + pageSize)
|
|
})
|
|
|
|
function getAddressById(id: number) {
|
|
return addresses.value.find(addr => addr.id === id)
|
|
}
|
|
|
|
function normalize(data: AddressFormData): AddressFormData {
|
|
return {
|
|
street: data.street.trim(),
|
|
zipCode: data.zipCode.trim(),
|
|
city: data.city.trim(),
|
|
country: data.country.trim()
|
|
}
|
|
}
|
|
|
|
function generateId(): number {
|
|
return Math.max(0, ...addresses.value.map(a => a.id)) + 1
|
|
}
|
|
|
|
function addAddress(formData: AddressFormData): Address {
|
|
const newAddress: Address = {
|
|
id: generateId(),
|
|
...normalize(formData)
|
|
}
|
|
|
|
addresses.value.unshift(newAddress)
|
|
resetPagination()
|
|
|
|
return newAddress
|
|
}
|
|
|
|
function updateAddress(id: number, formData: AddressFormData): boolean {
|
|
const index = addresses.value.findIndex(a => a.id === id)
|
|
if (index === -1) return false
|
|
|
|
const existing = addresses.value[index]
|
|
if (!existing) return false
|
|
|
|
addresses.value[index] = {
|
|
id: existing.id,
|
|
...normalize(formData)
|
|
}
|
|
return true
|
|
}
|
|
function deleteAddress(id: number): boolean {
|
|
const index = addresses.value.findIndex(a => a.id === id)
|
|
if (index === -1) return false
|
|
|
|
addresses.value.splice(index, 1)
|
|
resetPagination()
|
|
|
|
return true
|
|
}
|
|
|
|
function setPage(page: number) {
|
|
currentPage.value = page
|
|
}
|
|
|
|
function setSearchQuery(query: string) {
|
|
searchQuery.value = query
|
|
currentPage.value = 1
|
|
}
|
|
|
|
function resetPagination() {
|
|
currentPage.value = 1
|
|
}
|
|
|
|
initMockData()
|
|
|
|
return {
|
|
addresses,
|
|
loading,
|
|
error,
|
|
currentPage,
|
|
pageSize,
|
|
totalItems,
|
|
totalPages,
|
|
searchQuery,
|
|
filteredAddresses,
|
|
paginatedAddresses,
|
|
getAddressById,
|
|
addAddress,
|
|
updateAddress,
|
|
deleteAddress,
|
|
setPage,
|
|
setSearchQuery,
|
|
resetPagination
|
|
}
|
|
}) |