member model
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
ActiveAdmin.register Member do
|
||||
permit_params :nick, :real_nick, :motto, :avatar_filename
|
||||
|
||||
menu priority: 4
|
||||
|
||||
index do
|
||||
selectable_column
|
||||
id_column
|
||||
column :nick
|
||||
column :real_nick
|
||||
column :avatar_filename
|
||||
column :created_at
|
||||
actions
|
||||
end
|
||||
|
||||
filter :nick
|
||||
filter :real_nick
|
||||
|
||||
show do
|
||||
attributes_table do
|
||||
row :id
|
||||
row :nick
|
||||
row :real_nick
|
||||
row :motto
|
||||
row :avatar_filename
|
||||
row :created_at
|
||||
row :updated_at
|
||||
end
|
||||
end
|
||||
|
||||
form do |f|
|
||||
f.inputs do
|
||||
f.input :nick
|
||||
f.input :real_nick
|
||||
f.input :motto
|
||||
f.input :avatar_filename
|
||||
end
|
||||
f.actions
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,8 @@
|
||||
class Api::MembersController < ApiController
|
||||
def index
|
||||
members = Member.order(:id).map do |m|
|
||||
{ nick: m.nick, real_nick: m.real_nick, motto: m.motto, avatar_filename: m.avatar_filename }
|
||||
end
|
||||
render json: members
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class Member < ApplicationRecord
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w[avatar_filename created_at id motto nick real_nick updated_at]
|
||||
end
|
||||
end
|
||||
@@ -6,6 +6,7 @@ Rails.application.routes.draw do
|
||||
get "software", to: "software#index"
|
||||
get "software/highlighted", to: "software_highlighted#index"
|
||||
get "events", to: "events#index"
|
||||
get "members", to: "members#index"
|
||||
end
|
||||
|
||||
get "update", to: "update#update"
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
class CreateMembers < ActiveRecord::Migration[7.1]
|
||||
def change
|
||||
create_table :members do |t|
|
||||
t.string :nick, null: false
|
||||
t.string :real_nick, null: false
|
||||
t.text :motto
|
||||
t.string :avatar_filename
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
+10
-1
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.1].define(version: 2026_05_05_000005) do
|
||||
ActiveRecord::Schema[8.1].define(version: 2026_05_05_000006) do
|
||||
create_table "admin_users", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.string "email", default: "", null: false
|
||||
@@ -145,6 +145,15 @@ ActiveRecord::Schema[8.1].define(version: 2026_05_05_000005) do
|
||||
t.index ["username"], name: "users_username_unique", unique: true
|
||||
end
|
||||
|
||||
create_table "members", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.string "avatar_filename"
|
||||
t.datetime "created_at", null: false
|
||||
t.text "motto"
|
||||
t.string "nick", null: false
|
||||
t.string "real_nick", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
create_table "releases", id: { type: :bigint, unsigned: true }, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.string "cartridge_path"
|
||||
t.datetime "created_at", precision: 3
|
||||
|
||||
@@ -2,3 +2,16 @@ AdminUser.find_or_create_by!(email: ENV.fetch("ADMIN_EMAIL", "admin@teletype.hu"
|
||||
user.password = ENV.fetch("ADMIN_PASSWORD", "password123")
|
||||
user.password_confirmation = ENV.fetch("ADMIN_PASSWORD", "password123")
|
||||
end
|
||||
|
||||
[
|
||||
{ nick: "Mr. Zero", real_nick: "Tasi", motto: "His dream is to become an open-source knight.", avatar_filename: "mr.zero.png" },
|
||||
{ nick: "Mr. One", real_nick: "Ballz", motto: "The cheese is half-eaten. Something here went very wrong.", avatar_filename: "mr.one.png" },
|
||||
{ nick: "Mr. Two", real_nick: "Z", motto: "The egg was first or the chicken? It doesn't matter, we eat both.", avatar_filename: "mr.two.png" },
|
||||
{ nick: "Mr. Three", real_nick: "gBird", motto: "Life is beautiful because it contains the possibility of becoming human.", avatar_filename: "mr.three.png" },
|
||||
].each do |attrs|
|
||||
Member.find_or_create_by!(nick: attrs[:nick]) do |m|
|
||||
m.real_nick = attrs[:real_nick]
|
||||
m.motto = attrs[:motto]
|
||||
m.avatar_filename = attrs[:avatar_filename]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
|
||||
<main class="main-container py-16 px-4">
|
||||
<div class="team-grid">
|
||||
<div v-for="member in teamMembers" :key="member.name" class="team-card">
|
||||
<div v-for="member in members" :key="member.nick" class="team-card">
|
||||
<div class="team-card-image-container">
|
||||
<img :src="member.image" :alt="member.name" class="team-card-image" />
|
||||
<img :src="avatarUrl(member.avatar_filename)" :alt="member.nick" class="team-card-image" />
|
||||
</div>
|
||||
<div class="team-card-content">
|
||||
<h2 class="team-card-title">{{ member.name }}</h2>
|
||||
<p class="team-card-desc">{{ member.description }}</p>
|
||||
<h2 class="team-card-title">{{ member.nick }}: {{ member.real_nick }}</h2>
|
||||
<p class="team-card-desc">{{ member.motto }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -24,17 +24,25 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import mrZeroImg from '../assets/team/mr.zero.png'
|
||||
import mrOneImg from '../assets/team/mr.one.png'
|
||||
import mrTwoImg from '../assets/team/mr.two.png'
|
||||
import mrThreeImg from '../assets/team/mr.three.png'
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
const teamMembers = [
|
||||
{ name: 'Mr. Zero: Tasi', description: 'His dream is to become an open-source knight.', image: mrZeroImg },
|
||||
{ name: 'Mr. One: Ballz', description: 'The cheese is half-eaten. Something here went very wrong.', image: mrOneImg },
|
||||
{ name: 'Mr. Two: Z', description: "The egg was first or the chicken? It doesn't matter, we eat both.", image: mrTwoImg },
|
||||
{ name: 'Mr. Three: gBird', description: 'Life is beautiful because it contains the possibility of becoming human.', image: mrThreeImg },
|
||||
]
|
||||
interface Member {
|
||||
nick: string
|
||||
real_nick: string
|
||||
motto: string
|
||||
avatar_filename: string
|
||||
}
|
||||
|
||||
const members = ref<Member[]>([])
|
||||
|
||||
function avatarUrl(filename: string): string {
|
||||
return new URL(`../assets/team/${filename}`, import.meta.url).href
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const res = await fetch('/api/members')
|
||||
if (res.ok) members.value = await res.json()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user