(changed): changed field fix, drawing api and partial form
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
"vite": "^7.0.4"
|
"vite": "^7.0.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"hotkeys-js": "^3.13.15"
|
"hotkeys-js": "^3.13.15",
|
||||||
|
"@libsql/client": "^0.14.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export const combined = sqliteView('combined', {
|
|||||||
winning_ticket: integer('winning_ticket'),
|
winning_ticket: integer('winning_ticket'),
|
||||||
winner: text('winner')
|
winner: text('winner')
|
||||||
}).as(
|
}).as(
|
||||||
sql`SELECT b.prefix, b.b_id, b.winning_ticket, CONCAT(t.last_name, ", ", t.first_name) AS winner
|
sql`SELECT b.prefix, b.b_id, b.winning_ticket, CONCAT(t.last_name, ', ', t.first_name) AS winner
|
||||||
FROM baskets b LEFT JOIN tickets t
|
FROM baskets b LEFT JOIN tickets t
|
||||||
ON b.prefix = t.prefix AND b.winning_ticket = t.t_id
|
ON b.prefix = t.prefix AND b.winning_ticket = t.t_id
|
||||||
ORDER BY b.prefix, b.b_id`
|
ORDER BY b.prefix, b.b_id`
|
||||||
@@ -49,7 +49,7 @@ export const report = sqliteView('report', {
|
|||||||
winning_ticket: integer('winning_ticket'),
|
winning_ticket: integer('winning_ticket'),
|
||||||
description: text('description')
|
description: text('description')
|
||||||
}).as(
|
}).as(
|
||||||
sql`SELECT b.prefix, CONCAT(t.last_name, ", ", t.first_name) AS winner_name, t.phone_number, \
|
sql`SELECT b.prefix, CONCAT(t.last_name, ', ', t.first_name) AS winner_name, t.phone_number, \
|
||||||
t.preference, b.b_id, b.winning_ticket, b.description
|
t.preference, b.b_id, b.winning_ticket, b.description
|
||||||
FROM baskets b LEFT JOIN tickets t
|
FROM baskets b LEFT JOIN tickets t
|
||||||
ON b.prefix = t.prefix AND b.winning_ticket = t.t_id
|
ON b.prefix = t.prefix AND b.winning_ticket = t.t_id
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export async function GET({ params }) {
|
|||||||
for (let i=n_b_from; i <= n_b_to; i++) {
|
for (let i=n_b_from; i <= n_b_to; i++) {
|
||||||
let data = await db.select().from(baskets).where(and(eq(baskets.prefix, params.prefix), eq(baskets.b_id, i)));
|
let data = await db.select().from(baskets).where(and(eq(baskets.prefix, params.prefix), eq(baskets.b_id, i)));
|
||||||
if (data[0]) {
|
if (data[0]) {
|
||||||
r_dict[i] = {...data[0]};
|
r_dict[i] = {...data[0], changed: false};
|
||||||
} else {
|
} else {
|
||||||
r_dict[i] = {prefix: params.prefix, b_id: i, description: "", donors: "", winning_ticket: 0, changed: false};
|
r_dict[i] = {prefix: params.prefix, b_id: i, description: "", donors: "", winning_ticket: 0, changed: false};
|
||||||
}
|
}
|
||||||
|
|||||||
39
webapp/src/routes/api/combined/+server.js
Normal file
39
webapp/src/routes/api/combined/+server.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { env } from "$env/dynamic/private";
|
||||||
|
import { db } from "$lib/server/db";
|
||||||
|
import { baskets, combined } from "$lib/server/db/schema";
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
if (env.TAM3_REMOTE) {
|
||||||
|
const res = await fetch(`${env.TAM3_REMOTE}/api/combined/?api_key=${env.TAM3_REMOTE_KEY}`);
|
||||||
|
if (!res.ok) {
|
||||||
|
return new Response(JSON.stringify({detail: "Error fetching winners"}), {
|
||||||
|
status: res.status,
|
||||||
|
statusText: res.statusText
|
||||||
|
})
|
||||||
|
};
|
||||||
|
const data = await res.json();
|
||||||
|
return new Response(JSON.stringify(data), {status: 200, statusText: "Winners fetched successfully."})
|
||||||
|
} else {
|
||||||
|
const data = await db.select().from(combined);
|
||||||
|
return new Response(JSON.stringify(data), {status: 200, statusText: "Winners loaded successfully."})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST({ request }) {
|
||||||
|
const r_data = await request.json()
|
||||||
|
for (let winner of r_data) {
|
||||||
|
await db.insert(baskets).values({prefix: winner.prefix, b_id: winner.b_id, winning_ticket: winner.winning_ticket})
|
||||||
|
.onConflictDoUpdate({target: [baskets.prefix, baskets.b_id], set: {winning_ticket: winner.winning_ticket}})
|
||||||
|
}
|
||||||
|
if (env.TAM3_REMOTE) {
|
||||||
|
const res = await fetch(`${env.TAM3_REMOTE}/api/combined/?api_key=${env.TAM3_REMOTE_KEY}`, {
|
||||||
|
body: JSON.stringify(r_data),
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type': 'application/json'}
|
||||||
|
});
|
||||||
|
if (!res.ok) {
|
||||||
|
return new Response(JSON.stringify({detail: "Error posting winners."}), {status: res.status, statusText: res.statusText})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return new Response(JSON.stringify({detail: "Posted winners successfully."}))
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { env } from "process";
|
||||||
|
import { db } from "$lib/server/db";
|
||||||
|
import { combined } from "$lib/server/db/schema";
|
||||||
|
import { eq, and } from "drizzle-orm";
|
||||||
|
|
||||||
|
export async function GET({ params }) {
|
||||||
|
const n_b_from = parseInt(params.b_from), n_b_to = parseInt(params.b_to);
|
||||||
|
if (env.TAM3_REMOTE) {
|
||||||
|
const res = await fetch(`${env.TAM3_REMOTE}/api/combined/${params.prefix}/${n_b_from}/${n_b_to}/?api_key=${env.TAM3_REMOTE_KEY}`);
|
||||||
|
if (!res.ok) {
|
||||||
|
return new Response(JSON.stringify({detail: "Unable to fetch winners"}), {status: res.status, statusText: res.statusText})
|
||||||
|
};
|
||||||
|
const data = await res.json();
|
||||||
|
return new Response(JSON.stringify(data), {status: 200, statusText: "Tickets fetched successfully."})
|
||||||
|
} else {
|
||||||
|
let r_dict = {};
|
||||||
|
for (let i = n_b_from; i <= n_b_to; i++) {
|
||||||
|
let data = await db.select().from(combined).where(and(eq(combined.prefix, params.prefix), eq(combined.b_id, i)));
|
||||||
|
if (data[0]) {
|
||||||
|
r_dict[i] = {...data[0], changed: false};
|
||||||
|
} else {
|
||||||
|
r_dict[i] = {prefix: params.prefix, b_id: i, winning_ticket: 0, winner: ", ", changed: false}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return new Response(JSON.stringify(Object.values(r_dict)), {status: 200, statusText: "Tickets loaded successfully."})
|
||||||
|
}
|
||||||
|
}
|
||||||
24
webapp/src/routes/api/combined/[prefix]/[b_id]/+server.js
Normal file
24
webapp/src/routes/api/combined/[prefix]/[b_id]/+server.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { env } from "$env/dynamic/private";
|
||||||
|
import { db } from "$lib/server/db";
|
||||||
|
import { combined } from "$lib/server/db/schema";
|
||||||
|
import { eq, and } from "drizzle-orm";
|
||||||
|
|
||||||
|
export async function GET({ params }) {
|
||||||
|
if (env.TAM3_REMOTE) {
|
||||||
|
const res = await fetch(`${env.TAM3_REMOTE}/api/combined/${params.prefix}/${params.b_id}/?api_key=${env.TAM3_REMOTE_KEY}`);
|
||||||
|
if (!res.ok) {
|
||||||
|
return new Response(JSON.stringify({detail: "Unable to fetch winner"}), {status: res.status, statusText: res.statusText})
|
||||||
|
};
|
||||||
|
const data = await res.json();
|
||||||
|
return new Response(JSON.stringify(data), {status: 200, statusText: "Fetched winner successfully."})
|
||||||
|
} else {
|
||||||
|
let r_data = {}
|
||||||
|
const data = await db.select().from(combined).where(and(eq(combined.prefix, params.prefix), eq(combined.b_id, params.b_id)));
|
||||||
|
if (data[0]) {
|
||||||
|
r_data = {...data[0], changed: false};
|
||||||
|
} else {
|
||||||
|
r_data = {prefix: params.prefix, b_id: parseInt(params.b_id), winning_ticket: 0, winner: ", ", changed: false}
|
||||||
|
}
|
||||||
|
return new Response(JSON.stringify(r_data), {status: 200, statusText: "Loaded winner successfully."});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ export async function GET({ params }) {
|
|||||||
for (let i=n_t_from; i <= n_t_to; i++) {
|
for (let i=n_t_from; i <= n_t_to; i++) {
|
||||||
let data = await db.select().from(tickets).where(and(eq(tickets.prefix, params.prefix), eq(tickets.t_id, i)));
|
let data = await db.select().from(tickets).where(and(eq(tickets.prefix, params.prefix), eq(tickets.t_id, i)));
|
||||||
if (data[0]) {
|
if (data[0]) {
|
||||||
r_dict[i] = {...data[0]};
|
r_dict[i] = {...data[0], changed: false};
|
||||||
} else {
|
} else {
|
||||||
r_dict[i] = {prefix: params.prefix, t_id: i, first_name: "", last_name: "", phone_number: "", preference: "CALL", changed: false};
|
r_dict[i] = {prefix: params.prefix, t_id: i, first_name: "", last_name: "", phone_number: "", preference: "CALL", changed: false};
|
||||||
}
|
}
|
||||||
|
|||||||
5
webapp/src/routes/drawing/[prefix]/+page.js
Normal file
5
webapp/src/routes/drawing/[prefix]/+page.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export async function load({ params, fetch }) {
|
||||||
|
const res = await fetch(`/api/prefixes/${params.prefix}`);
|
||||||
|
const prefix_data = await res.json();
|
||||||
|
return {prefix: prefix_data}
|
||||||
|
}
|
||||||
62
webapp/src/routes/drawing/[prefix]/+page.svelte
Normal file
62
webapp/src/routes/drawing/[prefix]/+page.svelte
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<script>
|
||||||
|
import { browser } from '$app/environment';
|
||||||
|
import FormHeader from '$lib/components/FormHeader.svelte';
|
||||||
|
|
||||||
|
const { data } = $props();
|
||||||
|
const prefix = {...data.prefix};
|
||||||
|
let pagerForm = $state({id_from: 0, id_to: 0});
|
||||||
|
let current_idx = $state(0);
|
||||||
|
let current_drawings = $state([]);
|
||||||
|
let copy_buffer = $state({prefix: prefix.name, b_id: 1, winning_ticket: 0, winner: ", "});
|
||||||
|
|
||||||
|
|
||||||
|
const functions = {}
|
||||||
|
|
||||||
|
if (browser) {
|
||||||
|
document.title = `${prefix.name} Drawing Form`
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<h1>{prefix.name} Drawing Form</h1>
|
||||||
|
<FormHeader {prefix} {functions} bind:pagerForm />
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 12ch">Basket ID</th>
|
||||||
|
<th style="width: 20ch">Winning Number</th>
|
||||||
|
<th>Winner</th>
|
||||||
|
<th style="width: 20ch">Changed</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#each current_drawings as drawing, idx}
|
||||||
|
<tr>
|
||||||
|
<td>{drawing.b_id}</td>
|
||||||
|
<td><input type="number" id="{idx}_wt" bind:value={drawing.winning_ticket}></td>
|
||||||
|
<td>{drawing.winner}</td>
|
||||||
|
<td><button tabindex="-1">{drawing.changed ? "Y" : "N"}</button></td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
th {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
tbody tr:nth-child(2n) {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
background: transparent;
|
||||||
|
border: solid 1px #000000;
|
||||||
|
}
|
||||||
|
input, button {
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user