mirror of
https://github.com/danbulant/Portfolio
synced 2026-05-27 14:02:14 +00:00
feat: file upload
This commit is contained in:
parent
926a201f83
commit
acda16ad1e
7 changed files with 113 additions and 25 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
import axios, { type AxiosProgressEvent } from 'axios';
|
import axios, { type AxiosProgressEvent } from 'axios';
|
||||||
import type { CandidateData, CandidateLogin } from 'src/stores/candidate';
|
import type { CandidateData, CandidateLogin } from 'src/stores/candidate';
|
||||||
|
import type { SubmissionProgress } from 'src/stores/portfolio';
|
||||||
import { API_URL, errorHandler } from '.';
|
import { API_URL, errorHandler } from '.';
|
||||||
|
|
||||||
export async function apiWhoami(): Promise<string> {
|
export async function apiWhoami(): Promise<string> {
|
||||||
|
|
@ -48,17 +49,29 @@ export async function apiFetchDetails(): Promise<CandidateData> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function apiFetchSubmissionProgress(): Promise<SubmissionProgress> {
|
||||||
|
try {
|
||||||
|
const res = await axios.get(API_URL + '/candidate/portfolio/submission_progress', { withCredentials: true });
|
||||||
|
return res.data;
|
||||||
|
} catch (e: any) {
|
||||||
|
throw errorHandler(e, 'Failed to fetch submission progress');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function apiUploadCoverLetter(
|
export async function apiUploadCoverLetter(
|
||||||
letter: File,
|
letter: File,
|
||||||
progressReporter: (progress: AxiosProgressEvent) => void
|
progressReporter: (progress: AxiosProgressEvent) => void
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const res = await axios.post(
|
const res = await axios.post(API_URL + '/candidate/add/cover_letter', letter, {
|
||||||
API_URL + '/candidate/cover_letter',
|
withCredentials: true,
|
||||||
{ letter: letter },
|
data: letter,
|
||||||
{ withCredentials: true, onUploadProgress: progressReporter }
|
headers: {
|
||||||
);
|
'Content-Type': 'application/pdf',
|
||||||
return res.data === 'true';
|
},
|
||||||
|
onUploadProgress: progressReporter,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
throw errorHandler(e, 'Failed to upload cover letter');
|
throw errorHandler(e, 'Failed to upload cover letter');
|
||||||
}
|
}
|
||||||
|
|
@ -69,14 +82,17 @@ export async function apiUploadPortfolioLetter(
|
||||||
progressReporter: (progress: AxiosProgressEvent) => void
|
progressReporter: (progress: AxiosProgressEvent) => void
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const res = await axios.post(
|
const res = await axios.post(API_URL + '/candidate/add/portfolio_letter', letter, {
|
||||||
API_URL + '/candidate/portfolio_letter',
|
withCredentials: true,
|
||||||
{ letter: letter },
|
data: letter,
|
||||||
{ withCredentials: true, onUploadProgress: progressReporter }
|
headers: {
|
||||||
);
|
'Content-Type': 'application/pdf',
|
||||||
return res.data === 'true';
|
},
|
||||||
|
onUploadProgress: progressReporter,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
throw errorHandler(e, 'Failed to upload portfolio letter');
|
throw errorHandler(e, 'Failed to upload cover letter');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,13 +101,16 @@ export async function apiUploadPortfolioZip(
|
||||||
progressReporter: (progress: AxiosProgressEvent) => void
|
progressReporter: (progress: AxiosProgressEvent) => void
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const res = await axios.post(
|
const res = await axios.post(API_URL + '/candidate/add/portfolio_zip', portfolio, {
|
||||||
API_URL + '/candidate/portfolio_zip',
|
withCredentials: true,
|
||||||
{ portfolio: portfolio },
|
data: portfolio,
|
||||||
{ withCredentials: true, onUploadProgress: progressReporter }
|
headers: {
|
||||||
);
|
'Content-Type': 'application/zip',
|
||||||
return res.data === 'true';
|
},
|
||||||
|
onUploadProgress: progressReporter,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
throw errorHandler(e, 'Failed to upload portfolio zip');
|
throw errorHandler(e, 'Failed to upload cover letter');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { AxiosProgressEvent } from "axios";
|
||||||
|
import { apiUploadCoverLetter } from "../../../@api/candidate";
|
||||||
|
import DashboardUploadCard from "./DashboardUploadCard.svelte";
|
||||||
|
|
||||||
|
const onFileDrop = async (file: File) => {
|
||||||
|
await apiUploadCoverLetter(file, (progressEvent: AxiosProgressEvent) => {
|
||||||
|
console.log(progressEvent.progress)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<DashboardUploadCard
|
||||||
|
on:filedrop={e => onFileDrop(e.detail)}
|
||||||
|
title="Motivační dopis"
|
||||||
|
filetype="PDF"
|
||||||
|
filesize="10 MB">
|
||||||
|
</DashboardUploadCard>
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import FileType from './FileType.svelte';
|
import FileType from './FileType.svelte';
|
||||||
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
export let title: string;
|
export let title: string;
|
||||||
export let filetype: 'PDF' | 'ZIP';
|
export let filetype: 'PDF' | 'ZIP';
|
||||||
|
|
@ -30,6 +33,9 @@
|
||||||
|
|
||||||
const onFileDrop = (dropped: Dropped) => {
|
const onFileDrop = (dropped: Dropped) => {
|
||||||
console.log(dropped);
|
console.log(dropped);
|
||||||
|
if (dropped.accepted.length > 0) {
|
||||||
|
dispatch('filedrop', dropped.accepted[0]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -44,7 +50,7 @@
|
||||||
<FileDrop
|
<FileDrop
|
||||||
multiple={false}
|
multiple={false}
|
||||||
maxSize={filetype == 'PDF' ? 100_000_000 : 10_000_000}
|
maxSize={filetype == 'PDF' ? 100_000_000 : 10_000_000}
|
||||||
accept={filetype == 'PDF' ? 'application/pdf' : 'application/octet-stream'}
|
accept={filetype == 'PDF' ? 'application/pdf' : 'application/zip'}
|
||||||
on:filedrop={(e) => onFileDrop(e.detail.files)}
|
on:filedrop={(e) => onFileDrop(e.detail.files)}
|
||||||
on:filedragenter={dashAnimationStart}
|
on:filedragenter={dashAnimationStart}
|
||||||
on:filedragleave={dashAnimationStop}
|
on:filedragleave={dashAnimationStop}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { AxiosProgressEvent } from "axios";
|
||||||
|
import { apiUploadPortfolioLetter } from "../../../@api/candidate";
|
||||||
|
import DashboardUploadCard from "./DashboardUploadCard.svelte";
|
||||||
|
|
||||||
|
const onFileDrop = async (file: File) => {
|
||||||
|
await apiUploadPortfolioLetter(file, (progressEvent: AxiosProgressEvent) => {
|
||||||
|
console.log(progressEvent.loaded)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<DashboardUploadCard
|
||||||
|
on:filedrop={e => onFileDrop(e.detail)}
|
||||||
|
title="Portfolio"
|
||||||
|
filetype="PDF"
|
||||||
|
filesize="10 MB">
|
||||||
|
</DashboardUploadCard>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { AxiosProgressEvent } from "axios";
|
||||||
|
import { apiUploadPortfolioZip } from "../../../@api/candidate";
|
||||||
|
import DashboardUploadCard from "./DashboardUploadCard.svelte";
|
||||||
|
|
||||||
|
const onFileDrop = async (file: File) => {
|
||||||
|
await apiUploadPortfolioZip(file, (progressEvent: AxiosProgressEvent) => {
|
||||||
|
console.log(progressEvent.loaded)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<DashboardUploadCard
|
||||||
|
on:filedrop={e => onFileDrop(e.detail)}
|
||||||
|
title="Další data"
|
||||||
|
filetype="ZIP"
|
||||||
|
filesize="100 MB">
|
||||||
|
</DashboardUploadCard>
|
||||||
|
|
@ -7,6 +7,9 @@
|
||||||
import DashboardUploadCard from '$lib/components/dashboard/DashboardUploadCard.svelte';
|
import DashboardUploadCard from '$lib/components/dashboard/DashboardUploadCard.svelte';
|
||||||
import DashboardInfoCard from '$lib/components/dashboard/DashboardInfoCard.svelte';
|
import DashboardInfoCard from '$lib/components/dashboard/DashboardInfoCard.svelte';
|
||||||
import { candidateData, fetchDetails } from '../../stores/candidate';
|
import { candidateData, fetchDetails } from '../../stores/candidate';
|
||||||
|
import CoverLetterUploadCard from '$lib/components/dashboard/CoverLetterUploadCard.svelte';
|
||||||
|
import PortfolioLetterUploadCard from '$lib/components/dashboard/PortfolioLetterUploadCard.svelte';
|
||||||
|
import PortfolioZipUploadCard from '$lib/components/dashboard/PortfolioZipUploadCard.svelte';
|
||||||
|
|
||||||
|
|
||||||
let fullName = "";
|
let fullName = "";
|
||||||
|
|
@ -39,13 +42,13 @@
|
||||||
</DashboardInfoCard>
|
</DashboardInfoCard>
|
||||||
</div>
|
</div>
|
||||||
<div class="coverletter col-span-5">
|
<div class="coverletter col-span-5">
|
||||||
<DashboardUploadCard title="Motivační dopis" filetype="PDF" filesize="10 MB" />
|
<CoverLetterUploadCard />
|
||||||
</div>
|
</div>
|
||||||
<div class="portfolio col-span-4">
|
<div class="portfolio col-span-4">
|
||||||
<DashboardUploadCard title="Portfolio" filetype="PDF" filesize="10 MB" />
|
<PortfolioLetterUploadCard />
|
||||||
</div>
|
</div>
|
||||||
<div class="moreData col-span-4">
|
<div class="moreData col-span-4">
|
||||||
<DashboardUploadCard title="Další data" filetype="ZIP" filesize="100 MB" />
|
<PortfolioZipUploadCard />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dashboard dashboardMobile">
|
<div class="dashboard dashboardMobile">
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { apiFetchSubmissionProgress } from "../api/candidate";
|
import { apiFetchSubmissionProgress } from "../@api/candidate";
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store";
|
||||||
|
|
||||||
export interface SubmissionProgress {
|
export interface SubmissionProgress {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue