events api
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user