chore: more work on cv and on main page

This commit is contained in:
Andre Henriques 2024-09-30 15:15:08 +01:00
parent 8bb068499b
commit 407b955950
13 changed files with 285 additions and 166 deletions

View File

@ -1,5 +1,5 @@
spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/applications spring.datasource.url=jdbc:postgresql://kronos:5432/applications
spring.datasource.username=applications spring.datasource.username=applications
spring.datasource.password=applications spring.datasource.password=applications

View File

@ -30,7 +30,9 @@ data class Application(
var extra_data: String, var extra_data: String,
var payrange: String, var payrange: String,
var status: Int, var status: Int,
var flairs: List<Flair> var company: String,
var recruiter: String,
var flairs: List<Flair>,
) { ) {
companion object : RowMapper<Application> { companion object : RowMapper<Application> {
override public fun mapRow(rs: ResultSet, rowNum: Int): Application { override public fun mapRow(rs: ResultSet, rowNum: Int): Application {
@ -44,6 +46,8 @@ data class Application(
rs.getString("extra_data"), rs.getString("extra_data"),
rs.getString("payrange"), rs.getString("payrange"),
rs.getInt("status"), rs.getInt("status"),
rs.getString("company"),
rs.getString("recruiter"),
emptyList() emptyList()
) )
} }
@ -60,6 +64,8 @@ data class FlairRequest(val id: String, val text: String)
data class UpdateUrl(val id: String, val url: String) data class UpdateUrl(val id: String, val url: String)
data class CVData(val company: String, val recruiter: String, val flairs: List<SimpleFlair>)
@RestController @RestController
@ControllerAdvice @ControllerAdvice
@RequestMapping("/api/application") @RequestMapping("/api/application")
@ -69,6 +75,23 @@ class ApplicationsController(
val flairService: FlairService val flairService: FlairService
) { ) {
@GetMapping(path = ["/cv/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE])
public fun getCV(
@PathVariable id: String,
@RequestHeader("token") token: String
): CVData? {
print("here!");
val user = sessionService.verifyToken(token);
val application = applicationService.findApplicationByIdNoUser(id);
if (application == null) return null;
val flairs = application.flairs.map {it.toFlairSimple()};
return CVData(application.company, application.recruiter, flairs);
}
@PostMapping(path = ["/text"], produces = [MediaType.APPLICATION_JSON_VALUE]) @PostMapping(path = ["/text"], produces = [MediaType.APPLICATION_JSON_VALUE])
public fun submitText( public fun submitText(
@RequestBody submit: SubmitRequest, @RequestBody submit: SubmitRequest,
@ -179,6 +202,8 @@ class ApplicationsController(
"", "",
"", "",
0, 0,
"",
"",
emptyList() emptyList()
) )
} }
@ -435,13 +460,27 @@ class ApplicationService(val db: JdbcTemplate, val flairService: FlairService) {
return application return application
} }
public fun findApplicationByIdNoUser(id: String): Application? {
var applications = db.query("select * from applications where id=?", arrayOf(id), Application).toList()
if (applications.size == 0) {
return null
}
var application = applications[0]
application.flairs = flairService.listFromLinkApplicationId(application.id)
return application
}
public fun createApplication(user: UserDb, application: Application): Boolean { public fun createApplication(user: UserDb, application: Application): Boolean {
if (this.findApplicationByUrl(user, application.url, application.unique_url) != null) { if (this.findApplicationByUrl(user, application.url, application.unique_url) != null) {
return false return false
} }
db.update( db.update(
"insert into applications (id, url, original_url, unique_url, title, user_id, extra_data, payrange, status) values (?, ?, ?, ?, ?, ?, ?, ?, ?);", "insert into applications (id, url, original_url, unique_url, title, user_id, extra_data, payrange, status, company, recruiter) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
application.id, application.id,
application.url, application.url,
application.original_url, application.original_url,
@ -451,6 +490,8 @@ class ApplicationService(val db: JdbcTemplate, val flairService: FlairService) {
application.extra_data, application.extra_data,
application.payrange, application.payrange,
application.status, application.status,
application.company,
application.recruiter
) )
return true return true
@ -476,7 +517,7 @@ class ApplicationService(val db: JdbcTemplate, val flairService: FlairService) {
public fun update(application: Application): Application { public fun update(application: Application): Application {
db.update( db.update(
"update applications set url=?, original_url=?, unique_url=?, title=?, user_id=?, extra_data=?, payrange=?, status=? where id=?", "update applications set url=?, original_url=?, unique_url=?, title=?, user_id=?, extra_data=?, payrange=?, status=?, company=?, recruiter=? where id=?",
application.url, application.url,
application.original_url, application.original_url,
application.unique_url, application.unique_url,
@ -485,6 +526,8 @@ class ApplicationService(val db: JdbcTemplate, val flairService: FlairService) {
application.extra_data, application.extra_data,
application.payrange, application.payrange,
application.status, application.status,
application.company,
application.recruiter,
application.id, application.id,
) )
return application return application

View File

@ -68,6 +68,12 @@ class FlairController(val sessionService: SessionService, val flairService: Flai
} }
} }
data class SimpleFlair(
val name: String,
val description: String,
val color: String,
)
data class Flair( data class Flair(
var id: String, var id: String,
var user_id: String, var user_id: String,
@ -88,6 +94,10 @@ data class Flair(
) )
} }
} }
fun toFlairSimple(): SimpleFlair {
return SimpleFlair(this.name, this.description, this.color);
}
} }
data class FlairLink(var id: String, var application_id: String, var flair_id: String) data class FlairLink(var id: String, var application_id: String, var flair_id: String)
@ -134,14 +144,14 @@ public class FlairService(val db: JdbcTemplate) {
public fun listFromLinkApplicationId(id: String): List<Flair> = public fun listFromLinkApplicationId(id: String): List<Flair> =
db.query( db.query(
"select f.id, f.user_id, f.color, f.name, f.expr, f.description from flair_link as fl inner join flair as f on f.id = fl.flair_id where application_id=?;", "select f.id, f.user_id, f.color, f.name, f.expr, f.description from flair_link as fl inner join flair as f on f.id = fl.flair_id where application_id=? order by name asc;",
arrayOf(id), arrayOf(id),
Flair Flair
) )
.toList() .toList()
public fun listUser(user: UserDb): List<Flair> = public fun listUser(user: UserDb): List<Flair> =
db.query("select * from flair where user_id=?;", arrayOf(user.id), Flair).toList() db.query("select * from flair where user_id=? order by name asc;", arrayOf(user.id), Flair).toList()
public fun getById(user: UserDb, id: String): Flair? { public fun getById(user: UserDb, id: String): Flair? {
val items = val items =

View File

@ -16,6 +16,8 @@ create table if not exists applications (
url text not null, url text not null,
original_url text, original_url text,
unique_url text, unique_url text,
company text,
recruiter text,
title text, title text,
user_id text, user_id text,
extra_data text, extra_data text,

View File

@ -1,20 +1,28 @@
browser.runtime.onMessage.addListener(function (message) { browser.runtime.onMessage.addListener((message) => {
if (message.type === "MY_GET_URL_R") { if (message.type === "MY_GET_URL_R") {
window.postMessage(message); window.postMessage(message);
} else if (message.type === "GET_DATA_FROM_PAGE") { } else if (message.type === "GET_DATA_FROM_PAGE") {
let company = document const company = document
.querySelector('header[data-test="job-details-header"]') .querySelector('header[data-test="job-details-header"]')
.children[0].children[0].querySelector("h4").innerHTML; .children[0].children[0].querySelector("h4").innerHTML;
let jobTitle = document const jobTitle = document
.querySelector('header[data-test="job-details-header"]') .querySelector('header[data-test="job-details-header"]')
.querySelector("h1").innerHTML; .querySelector("h1").innerHTML;
browser.runtime.sendMessage({ type: "GOT_INFO_R", company, jobTitle });
let money = ""
const moneySectionNode = document.querySelector('section>section');
if (moneySectionNode && ["Base pay range", "Base pay"].includes(moneySectionNode.querySelector('h2').textContent)) {
money = moneySectionNode.querySelector("div>div>div").children[1]?.textContent ?? ''
}
browser.runtime.sendMessage({ type: "GOT_INFO_R", company, jobTitle, money });
} else if (message.type === "GOT_INFO_R") { } else if (message.type === "GOT_INFO_R") {
window.postMessage(message); window.postMessage(message);
} }
}); });
window.addEventListener("message", function (e) { window.addEventListener("message", (e) => {
if (e.data.type === "MY_GET_URL") { if (e.data.type === "MY_GET_URL") {
browser.runtime.sendMessage({ type: "MY_GET_URL" }); browser.runtime.sendMessage({ type: "MY_GET_URL" });
} else if (e.data.type === "HAS_EXTENSION_Q") { } else if (e.data.type === "HAS_EXTENSION_Q") {

View File

@ -32,6 +32,8 @@ export type Application = {
extra_data: string; extra_data: string;
payrange: string; payrange: string;
status: number; status: number;
recruiter: string;
company: string;
flairs: Flair[]; flairs: Flair[];
}; };

View File

@ -4,10 +4,10 @@
let ready = $state(false); let ready = $state(false);
const { children }: { children: Snippet } = $props(); const { children, redirect }: { children: Snippet, redirect: string } = $props();
onMount(() => { onMount(() => {
ready = userStore.checkLogin(); ready = userStore.checkLogin(redirect);
}); });
</script> </script>

View File

@ -22,23 +22,19 @@ function createUserStore() {
} }
return { return {
checkLogin(redirect = true) { checkLogin(redirect = "/login") {
console.log('test1');
if (user !== undefined) { if (user !== undefined) {
return true; return true;
} }
console.log('test2');
if (redirect) { if (redirect) {
goto('/login'); goto(redirect);
} }
console.log('test3');
return false; return false;
}, },
get isLoggedIn() { get isLoggedIn() {
console.log(user);
return user !== undefined; return user !== undefined;
}, },

View File

@ -6,7 +6,7 @@
import AppliyedList from './AppliyedList.svelte'; import AppliyedList from './AppliyedList.svelte';
</script> </script>
<HasUser> <HasUser redirect="/cv">
<div class="flex flex-col h-[100vh]"> <div class="flex flex-col h-[100vh]">
<NavBar /> <NavBar />
<div class="w-full px-4 grow h-full gap-3 flex flex-col"> <div class="w-full px-4 grow h-full gap-3 flex flex-col">

View File

@ -23,7 +23,14 @@
return true; return true;
} }
const f = new RegExp(filter, 'ig'); const f = new RegExp(filter, 'ig');
return i.title.match(f);
let x = i.title;
if (i.company) {
x = `${x} @ ${i.company}`;
}
return x.match(f);
}) as item} }) as item}
<div <div
class="card p-2 my-2 bg-slate-100" class="card p-2 my-2 bg-slate-100"
@ -39,8 +46,16 @@
<div class:animate-pulse={applicationStore.dragging?.id === item.id}> <div class:animate-pulse={applicationStore.dragging?.id === item.id}>
<h2 class="text-lg text-blue-500"> <h2 class="text-lg text-blue-500">
{item.title} {item.title}
{#if item.company}
<div class="text-violet-800" >
@ {item.company}
</div>
{/if}
</h2> </h2>
<a href={item.url} class="text-violet-600 overflow-hidden whitespace-nowrap block"> <a
href={item.url}
class="text-violet-600 overflow-hidden whitespace-nowrap block"
>
{item.url} {item.url}
</a> </a>
</div> </div>

View File

@ -1,5 +1,7 @@
<script lang="ts"> <script lang="ts">
import { get } from '$lib/utils';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import Flair from '../flair/Flair.svelte';
let id: string | undefined | null; let id: string | undefined | null;
@ -11,9 +13,39 @@
loadData(); loadData();
}); });
const application = undefined; type SimpleFlair = {
name: string;
description: string;
color: string;
};
async function loadData() {} type Application = {
flairs: SimpleFlair[];
};
let application: Application | undefined = $state(undefined);
async function loadData() {
try {
application = await get(`application/cv/${id}`);
application.flairs.sort((a, b) => {
if (a.description && b.description) {
return 0;
}
if (a.description) {
return -1;
}
if (b.description) {
return 1;
}
return 0;
})
} catch (e) {
console.log('TODO show this to the user', e);
}
}
</script> </script>
<svelte:head> <svelte:head>
@ -21,10 +53,10 @@
</svelte:head> </svelte:head>
<div class="flex items-center w-full flex-col"> <div class="flex items-center w-full flex-col">
<div class="max-w-[210mm] px-5 py-16"> <div class="py-10 w-[210mm]">
<div class="bg-white rounded-lg p-3"> <div class="bg-white rounded-lg p-3">
<div class="w-full flex"> <div class="w-full flex">
<h1 class="dark:text-white text-black text-5xl">Andre Henriques</h1> <h1 class="text-black text-5xl">Andre Henriques</h1>
<div class="flex-grow"></div> <div class="flex-grow"></div>
<div class="text-right"> <div class="text-right">
<ul> <ul>
@ -34,9 +66,7 @@
> >
</li> </li>
<li class="px-1"> <li class="px-1">
<a class="underline" href="tel:+4407823391342" <a class="underline" href="tel:+4407823391342">+44 0 782339 1342</a>
>+44 0 782339 1342</a
>
</li> </li>
</ul> </ul>
</div> </div>
@ -56,42 +86,62 @@
</div> </div>
</div> </div>
</div> </div>
</div>
{#if application} {#if application}
<div class="p-5"></div> <h2 class="text-white p-3 text-4xl">
<div>TODO: Application Information</div> 👋 Hello
{#if application.recruiter}
<span class="font-bold">{application.recruiter}</span> @ <span class="font-bold">{application.company}</span>
{:else if application.company}
recruiter @ <span class="font-bold">{application.company}</span>
{/if}
</h2>
<div class="p-3 bg-white w-[210mm] rounded-lg">
<h1>Your Ad / My skills</h1>
<div class="flex flex-wrap gap-2 py-2">
{#each application.flairs as flair}
<div class="min-w-0 {flair.description ? 'flex-grow w-full' : ''}">
<div class="p-2 rounded-lg" style="background: {flair.color};">
{flair.name}
{#if flair.description}
<div class="bg-white my-1 p-1 rounded-md">{flair.description}</div>
{/if}
</div>
</div>
{/each}
</div>
</div>
{/if} {/if}
<div class="p-5"></div> <div class="p-5"></div>
<div class="text-black bg-white p-4 rounded-lg"> <div class="px-5 w-[210mm]">
<h2 class="pb-2 text-3xl">Work Expericence</h2> <h2 class="pb-2 text-4xl font-bold text-white">Work Expericence</h2>
<div> </div>
<div>
<div class="p-2"></div>
<div class="w-[100vw] flex items-center flex-col">
<div class="p-3 bg-white w-[210mm] rounded-lg">
<h1>Senior Software Developer @ Planum Solucoes</h1> <h1>Senior Software Developer @ Planum Solucoes</h1>
<div class="ml-5"> <div class="ml-5">
<h2>4 year - May 2020 - Present</h2> <h2>4 year - May 2020 - Present</h2>
<h3>Working with:</h3> <h3>Developed various projects:</h3>
<ul class="pl-5 list-disc"> <ul class="pl-5 list-disc">
<li>Python</li> <li>Developing various websites using React and Svelte.</li>
<li>Jenkins</li> <li>Interacting with a RESTful API</li>
<li>GitLab CI</li> <li>Implemented an ORM system using Java Reflection</li>
<li>Ansible</li> <li>Implemented automatic deployment with GitLab CI/CD tools.</li>
<li>Docker</li> <li>Linux Server Administration</li>
</ul> <li>Technologies used: React, WebRTC, WebSockets, Rest, Google Maps AP</li>
<h3>Associated Software Developer / DevOps Engineer:</h3>
<ul class="pl-5 list-disc">
<li>Developed web-based tools for the DevOps team to use</li>
<li>
Updated Jenkins pipelines that the team uses to manage one of the
most important pipelines that the team manages.
</li>
<li>
Created new scripts that were used to clean up multiple terabytes of
unused data that led to improvements in the performance of the other
scripts running on the same server as well as the performance of the
backup system
</li>
</ul> </ul>
</div> </div>
</div> </div>
</div>
<div class="p-2"></div>
<div class="w-[100vw] flex items-center flex-col">
<div class="text-black w-[210mm] bg-white p-4 rounded-lg">
<div>
<div> <div>
<h1>Associate Devops Engineer @ Sky UK</h1> <h1>Associate Devops Engineer @ Sky UK</h1>
<div class="ml-5"> <div class="ml-5">
@ -122,8 +172,11 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="p-5"></div> <div class="p-5"></div>
<div class="bg-white p-3 text-black rounded-lg">
<div class="bg-white p-3 text-black rounded-lg w-[210mm]">
<h2 class="pb-2 text-3xl">Education</h2> <h2 class="pb-2 text-3xl">Education</h2>
<div> <div>
<div> <div>
@ -134,9 +187,9 @@
</div> </div>
</div> </div>
</div> </div>
<!--div class="p-5"></div> <!--div class="p-5"></div>
<div>TODO: Previous projetcs</div --> <div>TODO: Previous projetcs</div -->
<!-- div class="p-5"></div> <!-- div class="p-5"></div>
<div>TODO: Info form</div --> <div>TODO: Info form</div -->
</div> </div>
</div>

View File

@ -0,0 +1,22 @@
<script lang="ts">
import { applicationStore } from '$lib/ApplicationsStore.svelte';
import { preventDefault } from '$lib/utils';
import type { Snippet } from 'svelte';
let { ondrop, icon, children }: { ondrop: () => void, icon: string, children: Snippet } = $props();
</script>
<div
class="grid place-items-center w-full card p-2 rounded-lg"
role="none"
ondragover={preventDefault(() => {})}
ondragenter={preventDefault(() => {})}
{ondrop}
>
<span
class="bi bi-{icon} text-7xl absolute"
class:animate-bounce={applicationStore.dragging}
></span>
<span class="bi bi-{icon} text-7xl opacity-0"></span>
<div class="text-xl">{@render children()}</div>
</div>

View File

@ -11,6 +11,7 @@
import ExtractTextDialog from './ExtractTextDialog.svelte'; import ExtractTextDialog from './ExtractTextDialog.svelte';
import Flair from '../flair/Flair.svelte'; import Flair from '../flair/Flair.svelte';
import NewUrlDialog from './NewUrlDialog.svelte'; import NewUrlDialog from './NewUrlDialog.svelte';
import DropZone from './DropZone.svelte';
import { userStore } from '$lib/UserStore.svelte'; import { userStore } from '$lib/UserStore.svelte';
let activeItem: Application | undefined = $state(); let activeItem: Application | undefined = $state();
@ -42,6 +43,7 @@
if (item.status === 0) { if (item.status === 0) {
openWindow(item.url); openWindow(item.url);
openCV(item.id);
} }
try { try {
@ -76,6 +78,14 @@
); );
} }
function openCV(id?: string) {
window.open(
`/cv?id=${id ?? activeItem!.id}`,
'cv viwer',
`location,height=${window.screen.height},width=${window.screen.width},scrollbars,status,toolbar,menubar,popup`
);
}
async function loadActive() { async function loadActive() {
try { try {
activeItem = await get('application/active'); activeItem = await get('application/active');
@ -107,7 +117,9 @@
function setExtData() { function setExtData() {
if (!lastExtData || !activeItem) return; if (!lastExtData || !activeItem) return;
activeItem.title = `${lastExtData.company} - ${lastExtData.jobTitle}`; activeItem.title = lastExtData.jobTitle;
activeItem.company = lastExtData.company;
activeItem.payrange = lastExtData.money;
window.requestAnimationFrame(() => { window.requestAnimationFrame(() => {
save(); save();
lastExtData = undefined; lastExtData = undefined;
@ -203,6 +215,16 @@
{statusMapping} {statusMapping}
</div> </div>
{/if} {/if}
<div class="flex gap-2">
<fieldset class="grow">
<label class="flabel" for="title">Company</label>
<input class="finput" id="title" bind:value={activeItem.company} onchange={save} />
</fieldset>
<fieldset class="grow">
<label class="flabel" for="title">Recruiter</label>
<input class="finput" id="title" bind:value={activeItem.recruiter} onchange={save} />
</fieldset>
</div>
<fieldset> <fieldset>
<label class="flabel" for="title">Title</label> <label class="flabel" for="title">Title</label>
<input class="finput" id="title" bind:value={activeItem.title} onchange={save} /> <input class="finput" id="title" bind:value={activeItem.title} onchange={save} />
@ -262,10 +284,7 @@
> >
Open Open
</button> </button>
<button <button class="btn-primary" onclick={openCV}>
class="btn-primary"
onclick={() => window.open(`/cv?id=${activeItem!.id}`, '_blank')}
>
Open CV Open CV
</button> </button>
<button class="btn-primary" onclick={() => extractTokens.showModal()}> <button class="btn-primary" onclick={() => extractTokens.showModal()}>
@ -284,100 +303,49 @@
</div> </div>
{#if applicationStore.dragging} {#if applicationStore.dragging}
<div class="flex w-full flex-grow rounded-lg p-1 gap-2"> <div class="flex w-full flex-grow rounded-lg p-1 gap-2">
<!-- Do nothing -->
<DropZone icon="box-arrow-down" ondrop={() => {
moveStatus(ApplicationStatus.ToApply);
}}>
To apply
</DropZone>
<!-- Ignore --> <!-- Ignore -->
<div <DropZone icon="trash-fill" ondrop={() => {
class="grid place-items-center w-full card p-2 rounded-lg"
role="none"
ondragover={preventDefault(() => {})}
ondragenter={preventDefault(() => {})}
ondrop={() => {
moveStatus(ApplicationStatus.Ignore); moveStatus(ApplicationStatus.Ignore);
}} }}>
> Ignore it
<span </DropZone>
class="bi bi-trash-fill text-7xl absolute"
class:animate-bounce={applicationStore.dragging}
></span>
<span class="bi bi-trash-fill text-7xl opacity-0"></span>
<div class="text-xl">Drop Application Ignore it.</div>
</div>
<!-- Expired --> <!-- Expired -->
<div <DropZone icon="clock-fill text-orange-500" ondrop={() => {
class="grid place-items-center w-full card p-2 rounded-lg"
role="none"
ondragover={preventDefault(() => {})}
ondragenter={preventDefault(() => {})}
ondrop={() => {
if (activeItem && activeItem.status === ApplicationStatus.Expired) { if (activeItem && activeItem.status === ApplicationStatus.Expired) {
moveStatus(ApplicationStatus.ToApply); moveStatus(ApplicationStatus.ToApply);
} else { } else {
moveStatus(ApplicationStatus.Expired); moveStatus(ApplicationStatus.Expired);
} }
}} }}>
> Mark as expired
<span </DropZone>
class="bi bi-clock-fill text-7xl text-orange-500 absolute"
class:animate-bounce={applicationStore.dragging}
></span>
<span class="bi bi-clock-fill text-7xl text-orange-500 opacity-0"></span>
<div class="text-orange-500 text-xl">Mark as expired.</div>
</div>
<!-- Repeated --> <!-- Repeated -->
<div <DropZone icon="trash-fill text-danger" ondrop={() => remove()}>
class="grid place-items-center w-full card p-2 rounded-lg" Delete it
role="none" </DropZone>
ondragover={preventDefault(() => {})}
ondragenter={preventDefault(() => {})}
ondrop={() => {
remove();
}}
>
<span
class="bi bi-trash-fill text-7xl text-danger absolute"
class:animate-bounce={applicationStore.dragging}
></span>
<span class="bi bi-trash-fill text-7xl text-danger opacity-0"></span>
<div class="text-danger text-xl">This is repeated</div>
</div>
<!-- Applyed --> <!-- Applyed -->
<div <DropZone icon="server text-confirm" ondrop={async () => {
class="grid place-items-center w-full card p-2 rounded-lg"
role="none"
ondragover={preventDefault(() => {})}
ondragenter={preventDefault(() => {})}
ondrop={async () => {
await moveStatus(ApplicationStatus.Applyed); await moveStatus(ApplicationStatus.Applyed);
applicationStore.loadAplyed(true); applicationStore.loadAplyed(true);
}} }}>
> Apply
<span </DropZone>
class="bi bi-server text-7xl text-confirm absolute"
class:animate-bounce={applicationStore.dragging}
></span>
<span class="bi bi-server text-7xl text-confirm opacity-0"></span>
<div class="text-confirm text-xl">Apply</div>
</div>
<!-- Rejected --> <!-- Rejected -->
<div <DropZone icon="fire text-danger" ondrop={() => moveStatus(ApplicationStatus.ApplyedButSaidNo)}>
class="grid place-items-center w-full card p-2 rounded-lg" I was rejeted :(
role="none" </DropZone>
ondragover={preventDefault(() => {})}
ondragenter={preventDefault(() => {})}
ondrop={() => {
moveStatus(ApplicationStatus.ApplyedButSaidNo);
}}
>
<span
class="bi bi-fire text-danger text-7xl absolute"
class:animate-bounce={applicationStore.dragging}
></span>
<span class="bi bi-fire text-7xl text-danger opacity-0"></span>
<div class="text-danger text-xl">I was rejeted :(.</div>
</div>
</div> </div>
{/if} {/if}
{:else} {:else}