feat: add image preview and upload animation to AddProductTab
This commit is contained in:
parent
47de2877c3
commit
60d6586f77
1 changed files with 63 additions and 13 deletions
|
|
@ -1,8 +1,32 @@
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useSeller } from '../../../context/SellerContext';
|
import { useSeller } from '../../../context/SellerContext';
|
||||||
|
|
||||||
export default function AddProductTab() {
|
export default function AddProductTab() {
|
||||||
const { setDashTab } = useSeller();
|
const { setDashTab } = useSeller();
|
||||||
|
|
||||||
|
const [imagePreview, setImagePreview] = useState<string | null>(null);
|
||||||
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
|
|
||||||
|
const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const file = e.target.files?.[0];
|
||||||
|
if (file) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onloadend = () => {
|
||||||
|
setImagePreview(reader.result as string);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setIsSubmitting(true);
|
||||||
|
// Simulate API call and progress
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsSubmitting(false);
|
||||||
|
setDashTab('products');
|
||||||
|
}, 1500); // 1.5 seconds animation
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -18,7 +42,7 @@ export default function AddProductTab() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="box" style={{ borderTop: '4px solid var(--bulma-primary)' }}>
|
<div className="box" style={{ borderTop: '4px solid var(--bulma-primary)' }}>
|
||||||
<form onSubmit={(e) => { e.preventDefault(); setDashTab('products'); }}>
|
<form onSubmit={handleSubmit}>
|
||||||
<div className="columns is-multiline">
|
<div className="columns is-multiline">
|
||||||
|
|
||||||
{/* Left Column: Basic Info */}
|
{/* Left Column: Basic Info */}
|
||||||
|
|
@ -69,18 +93,32 @@ export default function AddProductTab() {
|
||||||
<label className="label has-text-grey-dark">Product Image</label>
|
<label className="label has-text-grey-dark">Product Image</label>
|
||||||
<div className="control">
|
<div className="control">
|
||||||
<div className="file is-boxed is-fullwidth">
|
<div className="file is-boxed is-fullwidth">
|
||||||
<label className="file-label is-flex-direction-column is-align-items-center">
|
<label className="file-label is-flex-direction-column is-align-items-center" style={{ width: '100%' }}>
|
||||||
<input className="file-input" type="file" name="resume" accept="image/*" />
|
<input className="file-input" type="file" accept="image/*" onChange={handleImageChange} required={!imagePreview} />
|
||||||
<span className="file-cta is-flex is-flex-direction-column is-align-items-center py-5 has-background-white" style={{ border: '1px solid var(--bulma-primary)' }}>
|
<span
|
||||||
<span className="file-icon mb-2 has-text-primary">
|
className="file-cta is-flex is-flex-direction-column is-align-items-center py-5 has-background-white"
|
||||||
<span className="material-symbols-outlined is-size-3">upload</span>
|
style={{ border: '1px solid var(--bulma-primary)', width: '100%', overflow: 'hidden' }}
|
||||||
</span>
|
>
|
||||||
<span className="file-label has-text-primary">
|
{imagePreview ? (
|
||||||
Choose an image…
|
<img src={imagePreview} alt="Preview" style={{ maxHeight: '150px', objectFit: 'contain' }} />
|
||||||
</span>
|
) : (
|
||||||
|
<>
|
||||||
|
<span className="file-icon mb-2 has-text-primary">
|
||||||
|
<span className="material-symbols-outlined is-size-3">upload</span>
|
||||||
|
</span>
|
||||||
|
<span className="file-label has-text-primary">
|
||||||
|
Choose an image…
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
{imagePreview && (
|
||||||
|
<p className="help has-text-centered mt-2 is-size-7">
|
||||||
|
<a onClick={() => setImagePreview(null)} className="has-text-danger">Remove image</a>
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -103,8 +141,20 @@ export default function AddProductTab() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="is-flex is-justify-content-flex-end mt-5">
|
<div className="is-flex is-justify-content-flex-end mt-5">
|
||||||
<button type="button" className="button is-light mr-3" onClick={() => setDashTab('products')}>Cancel</button>
|
<button
|
||||||
<button type="submit" className="button is-primary is-outlined">Publish Product</button>
|
type="button"
|
||||||
|
className="button is-light mr-3"
|
||||||
|
onClick={() => setDashTab('products')}
|
||||||
|
disabled={isSubmitting}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className={`button is-primary is-outlined ${isSubmitting ? 'is-loading' : ''}`}
|
||||||
|
>
|
||||||
|
Publish Product
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue