some changes
continuous-integration/drone/push Build is passing Details

main
parent f0d992d34e
commit e0780f4217

@ -27,3 +27,22 @@ export async function sendJSON(url: string, data: any): Promise<Result<any, stri
return { status: 'error', value: e!.toString() } return { status: 'error', value: e!.toString() }
} }
} }
export async function sendDelete(url: string): Promise<Result<any, string>> {
try {
const res = await fetch(url, {
method: 'DELETE',
credentials: 'include',
})
if (!res.ok) {
console.error(res)
return { status: 'error', value: await res.text() }
}
return { status: 'ok', value: await res.json() }
} catch (e) {
console.error(e)
return { status: 'error', value: e!.toString() }
}
}

@ -47,7 +47,7 @@ const ActionCardAnswer = ({ action, ...props }: { action: ActionAnswer } & Actio
<div class="stack-h center gap-sm"> <div class="stack-h center gap-sm">
<div class="icon">schedule</div> <div class="icon">schedule</div>
<div class="text dimmed"> <div class="text dimmed">
{action.timestamp && format(new Date(action.timestamp), 'dd/MM/yyyy HH:mm:ss')} {action.timestamp && format(new Date(action.timestamp), 'HH:mm:ss')}
<span class="text smaller"> <span class="text smaller">
{action.timestamp && ' ' + format(new Date(action.timestamp), 'SSS')} {action.timestamp && ' ' + format(new Date(action.timestamp), 'SSS')}
</span> </span>
@ -79,7 +79,7 @@ const ActionCardJolly = ({ action, ...props }: { action: ActionJolly } & ActionC
<div class="stack-h center gap-sm"> <div class="stack-h center gap-sm">
<div class="icon">schedule</div> <div class="icon">schedule</div>
<div class="text dimmed"> <div class="text dimmed">
{action.timestamp && format(new Date(action.timestamp), 'dd/MM/yyyy HH:mm:ss')} {action.timestamp && format(new Date(action.timestamp), 'HH:mm:ss')}
<span class="text smaller"> <span class="text smaller">
{action.timestamp && ' ' + format(new Date(action.timestamp), 'SSS')} {action.timestamp && ' ' + format(new Date(action.timestamp), 'SSS')}
</span> </span>

@ -2,7 +2,7 @@ import { SubmitAction } from '@/components/SubmitAction'
import { ActionRegistry } from '@/components/ActionRegistry' import { ActionRegistry } from '@/components/ActionRegistry'
import { useEffect, useRef, useState } from 'preact/hooks' import { useEffect, useRef, useState } from 'preact/hooks'
import type { Room } from '@/db/model' import type { Room } from '@/db/model'
import { requestJSON } from '@/client/utils' import { requestJSON, sendDelete, sendJSON } from '@/client/utils'
import { computeScoreboardState } from '@/ggwp' import { computeScoreboardState } from '@/ggwp'
import { Leaderboard } from './Leaderboard' import { Leaderboard } from './Leaderboard'
@ -86,6 +86,23 @@ export const AdminPage = ({ roomId }: { roomId: string }) => {
/> />
<h2>Registro Azioni</h2> <h2>Registro Azioni</h2>
<ActionRegistry room={room} refreshRoom={fetchRoom} /> <ActionRegistry room={room} refreshRoom={fetchRoom} />
<h2>Zona Pericolosa</h2>
<div class="card tint-red stack-v center">
<button
onClick={async () => {
const answer = confirm('Sei sicuro di voler eliminare la stanza?')
if (!answer) {
return
}
await sendDelete(`/api/room/${room.id}`)
alert('Stanza eliminata, puoi comunque continuare a visualizzare i risultati')
}}
>
Elimina Stanza
</button>
</div>
</> </>
) )
} }

@ -26,7 +26,7 @@ export const SubmitActionAnswer = ({
}) })
return ( return (
<div class="card tint-red stack-v center"> <div class="card tint-green stack-v center">
<h3>Invia Risposta</h3> <h3>Invia Risposta</h3>
<select <select
@ -120,7 +120,7 @@ export const SubmitActionJolly = ({
}) })
return ( return (
<div class="card tint-red stack-v center"> <div class="card tint-gold stack-v center">
<h3>Invia Jolly</h3> <h3>Invia Jolly</h3>
<select <select

@ -19,17 +19,19 @@ db.exec(`
); );
`) `)
// db.exec(` db.exec(`
// CREATE TABLE IF NOT EXISTS game_actions ( CREATE TABLE IF NOT EXISTS deleted_rooms (
// id INTEGER PRIMARY KEY, id TEXT PRIMARY KEY,
// room_id TEXT NOT NULL, deleted_at TEXT NOT NULL
// created_at TEXT NOT NULL, );
`)
// data TEXT NOT NULL,
// FOREIGN KEY (room_id) REFERENCES rooms (id) db.exec(`
// ); CREATE TABLE IF NOT EXISTS sessions (
// `) sid TEXT PRIMARY KEY,
room_id TEXT NOT NULL
);
`)
export function databaseStatus(): string { export function databaseStatus(): string {
return 'ok' return 'ok'
@ -66,6 +68,15 @@ export function updateRoom(id: string, data: RoomData): void {
).run(JSON.stringify(data), id) ).run(JSON.stringify(data), id)
} }
export function deleteRoom(id: string): void {
db.prepare<[string, string]>(
`
INSERT INTO deleted_rooms (id, deleted_at)
VALUES (?, ?);
`
).run(id, new Date().toISOString())
}
export function getRoom(id: string): RoomData | null { export function getRoom(id: string): RoomData | null {
const row = db const row = db
.prepare< .prepare<
@ -77,6 +88,9 @@ export function getRoom(id: string): RoomData | null {
} }
>('SELECT * FROM rooms WHERE id = ?') >('SELECT * FROM rooms WHERE id = ?')
.get(id) .get(id)
console.log(row)
if (!row) { if (!row) {
return null return null
} }
@ -108,7 +122,14 @@ export function getRooms(): Room[] {
id: string id: string
data: string data: string
} }
>('SELECT id, data FROM rooms') >(
`
SELECT rooms.id, rooms.data
FROM rooms
LEFT JOIN deleted_rooms ON rooms.id = deleted_rooms.id
WHERE deleted_rooms.id IS NULL
`
)
.all() .all()
return rows.map(row => ({ return rows.map(row => ({

@ -1,4 +1,4 @@
import { getRoom, updateRoom } from '@/db' import { deleteRoom, getRoom, updateRoom } from '@/db'
import { addRoomUpdateListener, removeRoomUpdateListener } from '@/db/events' import { addRoomUpdateListener, removeRoomUpdateListener } from '@/db/events'
import type { RoomData } from '@/db/model' import type { RoomData } from '@/db/model'
import { getSession } from '@/db/sessions' import { getSession } from '@/db/sessions'
@ -88,3 +88,32 @@ export const POST: APIRoute = async ({ params, request, cookies }) => {
headers: { 'content-type': 'application/json' }, headers: { 'content-type': 'application/json' },
}) })
} }
export const DELETE: APIRoute = async ({ params, cookies }) => {
const { id: roomId } = params
if (!roomId) {
return new Response('Invalid room id', { status: 400 })
}
const room = getRoom(roomId)
if (!room) {
return new Response('Room not found', { status: 404 })
}
// check auth
const sid = cookies.get('sid')
if (!sid) {
return new Response('Unauthorized', { status: 401 })
}
const sessionRoom = getSession(sid.value)
if (sessionRoom !== roomId) {
return new Response('Unauthorized', { status: 401 })
}
deleteRoom(roomId)
return new Response(JSON.stringify('ok'), {
headers: { 'content-type': 'application/json' },
})
}

@ -28,6 +28,7 @@ img {
--red: oklch(63.11% 0.2387 32.0573); --red: oklch(63.11% 0.2387 32.0573);
--green: oklch(60.3% 0.3 134.48); --green: oklch(60.3% 0.3 134.48);
--orange: oklch(76.96% 0.1692 67.6368); --orange: oklch(76.96% 0.1692 67.6368);
--gold: oklch(from royalblue calc(l + 0.1) calc(c - 0.025) 90);
} }
body { body {
@ -169,6 +170,10 @@ a {
--tint: var(--orange); --tint: var(--orange);
} }
.tint-gold {
--tint: var(--gold);
}
.stack-v { .stack-v {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

Loading…
Cancel
Save