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
116
117
118
119
120
121
122
123
124
125
126import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { toast } from '~/components/alerts';
import { Button } from '~/components/buttons';
import { SEO } from '~/components/layout';
import { addProperty } from '~/services';
import { useStore } from '~/store';
const BulkProperty = () => {
const navigate = useNavigate();
const [isFormValid, setIsFormValid] = useState(false);
const [data, setData] = useState([]);
const { loading, setLoading } = useStore();
const [current, setCurrent] = useState(1);
const onChange = (e) => {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = (e) => {
const text = e.target.result;
const rows = text.split('\n');
const parsedData = rows.map(row => row.split(','));
setData(parsedData);
};
reader.readAsText(file);
return;
}
useEffect(() => {
if (data?.length > 0) {
setIsFormValid(true);
}
else {
setIsFormValid(false);
}
}, [data]);
const handleSubmit = async (e) => {
e.preventDefault();
if (!isFormValid) return;
setLoading(true);
try {
const successes = [];
const errors = [];
for (const [index, row] of data.entries()) {
setCurrent(index);
try {
const response = await addProperty(row[0], row[1], row[2]);
console.log(response);
successes.push(row);
}
catch (err) {
errors.push(row);
}
}
setLoading(false);
toast.success({ title: 'Success', description: 'Properties added successfully!' });
navigate('/properties');
} catch (error) {
setLoading(false);
toast.error({ title: 'Error', description: 'An error occurred while adding the properties.' });
}
};
return (
<>
<SEO
title="Bulk Add Property - Equalify"
description="Bulk add new propeties to Equalify to start monitoring and improving its accessibility."
url="https://dashboard.equalify.app/properties/bulk"
/>
<h1 id="bulk-property-heading" className="text-2xl font-bold md:text-3xl">
Bulk Upload CSV
</h1>
<section
aria-labelledby="bulk-property-heading"
className="mt-7 space-y-6 rounded-lg bg-white p-6 shadow"
aria-live="polite"
>
<form onSubmit={handleSubmit} id="bulk-property-form" className='flex flex-col gap-4'>
<a target='_blank' className='underline' href='/template.csv'>Example Template CSV</a>
<input onChange={onChange} type='file' />
{data.length > 0 && <div className='flex flex-col'>
<div>Showing first 10 rows</div>
{data.slice(0, 10).map((row, index) => <div key={index} className={`p-1 flex flex-row gap-2 ${index === 0 && 'bg-card'}`}>
{row.map((cell, index) => <div key={index} style={{ width: `${100 / data[0].length}%` }} className='truncate'>{cell}</div>)}
</div>)}
<div>...</div>
</div>}
<div className="space-x-6">
<Button
type='reset'
variant={'outline'}
className="w-fit"
onClick={() => navigate(-1)}
aria-label='Cancel adding property'
>
Cancel
</Button>
<Button
type="submit"
form="bulk-property-form"
className="w-fit bg-[#1D781D] text-white"
disabled={!isFormValid}
aria-disabled={!isFormValid}
aria-live="polite"
>
Submit
</Button>
</div>
</form>
</section>
{loading && <div
className="fixed top-0 left-0 w-full h-full bg-[#6666] flex flex-row gap-2 items-center justify-center"
>
<div className='animate-spin flex flex-row items-center justify-center text-center'>↻</div>
Adding {current} of {data.length - 1} properties...
</div>}
</>
);
};
export default BulkProperty;