Skip to content

Commit

Permalink
feat: upload file
Browse files Browse the repository at this point in the history
  • Loading branch information
nguyenthanhanit committed Dec 15, 2023
1 parent a2f4111 commit 710e589
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 29 deletions.
44 changes: 38 additions & 6 deletions app/admin/[slug]/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import SingleFileUploadForm from "@/components/admin/single-upload-form";
import {Spinner} from "@nextui-org/spinner";

export default function EditPage({params}: { params: { slug: string, id: string } }) {
const [thumbnail, setThumbnail] = useState<string>('');
const [loading, setLoading] = useState(true);

// This code inside useEffect will run when the component is mounted
Expand All @@ -33,15 +32,38 @@ export default function EditPage({params}: { params: { slug: string, id: string
});
}, []);

const onSubmit = async (data: any) => {
data.publish_at = moment(data.publish_at).format("x");
data.thumbnail = thumbnail;
const onSubmit = async (dataForm: any) => {
const formData = new FormData();
formData.append("media", dataForm.thumbnail);

const resUpload = await fetch("/admin/api/upload", {
method: "POST",
body: formData,
});

const {
data,
error,
}: {
data: {
url: string | string[];
} | null;
error: string | null;
} = await resUpload.json();

if (error || !data) {
toast.error(error || "Sorry! something went wrong.");
return;
}

dataForm.thumbnail = data.url;
dataForm.publish_at = moment(dataForm.publish_at).format("x");
const res = await fetch('/admin/api', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({type: params.slug, data}),
body: JSON.stringify({type: params.slug, dataForm}),
})

if (res.status === 200) {
Expand Down Expand Up @@ -108,13 +130,23 @@ export default function EditPage({params}: { params: { slug: string, id: string
className="border w-full rounded-md"
selected={field.value}
placeholderText="Ngày đăng"
required
{...field}
/>
}}
/>

<SingleFileUploadForm srcImg={setThumbnail}/>
<h1>Ảnh đại diện</h1>
<Controller
name="thumbnail"
control={control}
rules={{required: true}}
render={({field: {ref, ...field}}) => (
<SingleFileUploadForm {...field} />
)}
/>

<h1>Nội dung</h1>
<Controller
name="content"
control={control}
Expand Down
3 changes: 0 additions & 3 deletions app/admin/[slug]/new/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,6 @@ export default function NewPage({params}: { params: { slug: string } }) {
}}
/>


<SingleFileUploadForm srcImg={setThumbnail}/>

<Controller
name="content"
control={control}
Expand Down
16 changes: 12 additions & 4 deletions app/admin/api/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,22 @@ export async function DELETE(req: NextRequest, res: NextResponse) {
}

export async function POST(req: NextRequest, res: NextResponse) {
const {data, type} = await req.json()
const {dataForm, type} = await req.json()

await dbConnect();

if (type === 'news') {
await News.create(data);
if (dataForm?._id) {
if (type === 'news') {
await News.findByIdAndUpdate(dataForm._id, dataForm)
} else {
await Project.findByIdAndUpdate(dataForm._id, dataForm)
}
} else {
await Project.create(data);
if (type === 'news') {
await News.create(dataForm);
} else {
await Project.create(dataForm);
}
}

return new Response('Successfully', {
Expand Down
38 changes: 23 additions & 15 deletions components/admin/single-upload-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ import {Button} from "@nextui-org/button";
import {toast, ToastContainer} from "react-toastify";
import 'react-toastify/dist/ReactToastify.css';

const SingleFileUploadForm = ({srcImg}: any) => {
type Props = {
value: any
onChange: any
uploadDirect?: boolean
}

const SingleFileUploadForm = ({uploadDirect, value, onChange, ...rest}: Props) => {
const [file, setFile] = useState<File | null>(null);
const [previewUrl, setPreviewUrl] = useState<string | null>(null);
const [previewUrl, setPreviewUrl] = useState<string | null>(value);

const onFileUploadChange = (e: ChangeEvent<HTMLInputElement>) => {
const fileInput = e.target;
Expand All @@ -31,6 +37,7 @@ const SingleFileUploadForm = ({srcImg}: any) => {

/** Setting file state */
setFile(file); // we will use the file state, to send it later to the server
onChange(file);
setPreviewUrl(URL.createObjectURL(file)); // we will use this to show the preview of the image

/** Reset file input */
Expand All @@ -44,7 +51,7 @@ const SingleFileUploadForm = ({srcImg}: any) => {
return;
}
setFile(null);
srcImg('');
onChange(null);
setPreviewUrl(null);
};

Expand Down Expand Up @@ -78,9 +85,6 @@ const SingleFileUploadForm = ({srcImg}: any) => {
toast.error(error || "Sorry! something went wrong.");
return;
}

srcImg(data.url)

} catch (error) {
toast.error("Sorry! something went wrong.");
}
Expand Down Expand Up @@ -127,6 +131,8 @@ const SingleFileUploadForm = ({srcImg}: any) => {
type="file"
className="block w-0 h-0 m-0 p-0"
onChange={onFileUploadChange}
value={value}
{...rest}
/>
</label>
)}
Expand All @@ -141,15 +147,17 @@ const SingleFileUploadForm = ({srcImg}: any) => {
>
Huỷ
</Button>
<Button
disabled={!previewUrl}
onClick={onUploadFile}
color="primary"
variant="bordered"
className="shadow-sm hover:bg-blue-500 hover:text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
>
Upload
</Button>
{
uploadDirect && <Button
disabled={!previewUrl}
onClick={onUploadFile}
color="primary"
variant="bordered"
className="shadow-sm hover:bg-blue-500 hover:text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
>
Upload
</Button>
}
</div>
</div>
</form>
Expand Down
2 changes: 1 addition & 1 deletion models/News.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const userSchema = new mongoose.Schema<INews>({
name: {type: String, required: true},
publish_at: {type: Number, required: true},
content: {type: String, required: true},
thumbnail: {type: String, required: false},
thumbnail: {type: String, required: true},
});

const News = mongoose.models.News || mongoose.model<INews>('News', userSchema);
Expand Down
Binary file not shown.

0 comments on commit 710e589

Please sign in to comment.