events api

This commit is contained in:
2026-05-05 19:49:24 +02:00
parent 66442c420b
commit 130be14c59
6 changed files with 86 additions and 42 deletions
+35
View File
@@ -0,0 +1,35 @@
ActiveAdmin.register Event do
permit_params :name, :date
menu priority: 3
index do
selectable_column
id_column
column :name
column :date
column :created_at
actions
end
filter :name
filter :date
show do
attributes_table do
row :id
row :name
row :date
row :created_at
row :updated_at
end
end
form do |f|
f.inputs do
f.input :name
f.input :date, as: :date_time_picker
end
f.actions
end
end
@@ -0,0 +1,8 @@
class Api::EventsController < ApiController
def index
events = Event.upcoming.map do |e|
{ name: e.name, date: e.date.utc.strftime("%Y-%m-%dT%H:%M:%SZ") }
end
render json: events
end
end
+9
View File
@@ -0,0 +1,9 @@
class Event < ApplicationRecord
default_scope { where(deleted_at: nil) }
scope :upcoming, -> { where("date > ?", Time.current).order(:date) }
def self.ransackable_attributes(auth_object = nil)
%w[id name date created_at updated_at]
end
end
+1
View File
@@ -5,6 +5,7 @@ Rails.application.routes.draw do
namespace :api do
get "software", to: "software#index"
get "software/highlighted", to: "software_highlighted#index"
get "events", to: "events#index"
end
get "update", to: "update#update"
@@ -0,0 +1,15 @@
class CreateEvents < ActiveRecord::Migration[8.1]
def change
create_table :events, id: { type: :bigint, unsigned: true },
charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci",
if_not_exists: true do |t|
t.string :name, null: false
t.datetime :date, null: false
t.datetime :deleted_at, precision: 3
t.timestamps precision: 3
t.index :deleted_at, name: "idx_events_deleted_at"
t.index :date, name: "idx_events_date"
end
end
end
+18 -42
View File
@@ -1,58 +1,35 @@
---
import Layout from '../layouts/Layout.astro';
import { formatDateTime } from '../utils/dateFormat';
import fs from 'node:fs';
import path from 'node:path';
import yaml from 'js-yaml';
interface Event {
name: string;
date: string;
}
interface EventData {
events: Event[];
}
const BASE = "https://games.teletype.hu";
let nextEvent: (Event & { dateISO: string; dateText: string }) | null = null;
let followingEvents: (Event & { dateText: string })[] = [];
try {
const rootDir = process.cwd();
let eventsPath = path.join(rootDir, 'src', 'events.yaml');
if (!fs.existsSync(eventsPath)) {
eventsPath = path.join(rootDir, 'src', 'events-example.yaml');
}
if (fs.existsSync(eventsPath)) {
const fileContents = fs.readFileSync(eventsPath, 'utf8');
const data = yaml.load(fileContents) as EventData;
if (data && data.events) {
const now = new Date();
const futureEvents = data.events
.map(e => ({
...e,
dateObj: new Date(e.date)
}))
.filter(e => e.dateObj > now)
.sort((a, b) => a.dateObj.getTime() - b.dateObj.getTime());
if (futureEvents.length > 0) {
const first = futureEvents[0];
nextEvent = {
name: first.name,
date: first.date,
dateISO: first.dateObj.toISOString(),
dateText: formatDateTime(first.dateObj)
};
followingEvents = futureEvents.slice(1).map(e => ({
name: e.name,
date: e.date,
dateText: formatDateTime(e.dateObj)
}));
}
const res = await fetch(BASE + "/api/events");
if (res.ok) {
const events: Event[] = await res.json();
if (events.length > 0) {
const first = events[0];
const firstDate = new Date(first.date);
nextEvent = {
name: first.name,
date: first.date,
dateISO: firstDate.toISOString(),
dateText: formatDateTime(firstDate)
};
followingEvents = events.slice(1).map(e => ({
name: e.name,
date: e.date,
dateText: formatDateTime(new Date(e.date))
}));
}
}
} catch (e) {
@@ -60,7 +37,6 @@ try {
}
// Fetch highlighted software
const BASE = "https://games.teletype.hu";
const API_HIGHLIGHTED = BASE + "/api/software/highlighted";
let highlightedSoftware = null;
let highlightedStableRelease = null;