templates for self-hosting game jams (or any other kind of jam tbh)
1---
2import { getCollection, getEntry } from 'astro:content';
3import GameCard from '../components/GameCard.astro';
4const allGames = await getCollection('games');
5---
6<>
7 <aside id="filters">
8 <div class="afs-filter-container">
9 <!-- Filter Controls -->
10 <div class="afs-filter-controls">
11 <!-- Basic Filters -->
12
13 <!-- Search Input -->
14 <input type="text" class="afs-filter-search" placeholder="Search by title, author, or tags" />
15
16 <p class="label">Sort entries by:</p>
17 <ul id="sorts">
18 <li><button class="custom-sort" data-sort-key="date" data-sort-direction="desc"> <span class="afs-sort-direction"><span class="icon sort-desc"></span></span> Date</button></li>
19 <li><button class="custom-sort" data-sort-key="title" data-sort-direction="asc"> <span class="afs-sort-direction"><span class="icon sort-asc"></span></span> Title</button></li>
20 <li><button class="custom-sort" data-sort-key="shuffle" data-sort-direction="desc"><span class="icon random"></span></span> Random</button></li>
21 </ul>
22
23 <details open><summary>Platform</summary>
24 <ul>
25 <li><button class="afs-btn-filter" data-filter="platforms:browser"><span class="icon web"></span> Play in browser</button></li>
26 <li><button class="afs-btn-filter" data-filter="platforms:windows"><span class="icon windows"></span> Windows</button></li>
27 <li><button class="afs-btn-filter" data-filter="platforms:macos"><span class="icon macos"></span> Mac OS</button></li>
28 <li><button class="afs-btn-filter" data-filter="platforms:linux"><span class="icon linux"></span> Linux</button></li>
29 <li><button class="afs-btn-filter" data-filter="platforms:android"><span class="icon android"></span> Android</button></li>
30 </ul>
31 </details>
32
33 <details><summary>Tags</summary>
34 <div id="tags">
35 <button class="afs-btn-filter" data-filter="*">all</button>
36
37 </div>
38 </details>
39
40 <details><summary>Submission Date</summary>
41 <div id="date-filter"></div>
42 </details>
43
44 <!-- Results Counter -->
45 <div class="afs-filter-counter"></div>
46 </div>
47
48 <!-- Pagination Container -->
49 <div class="afs-pagination-container"></div>
50 </div>
51 </aside>
52 <section id="list">
53 {console.log(allGames)}
54 {allGames.map(game => (
55 <li><a href={`/games/${game.id}`}>{game.data.title}</a></li>
56 ))}
57 </section>
58</>
59
60<style lang="scss">
61#filters {
62 grid-area: filters;
63 text-align: left;
64
65 #tags {
66 display: flex;
67 flex-wrap: wrap;
68 gap: 5px;
69 justify-content: flex-start;
70
71 button {
72 white-space: pre;
73 }
74 }
75
76 details {
77 margin-bottom: 10px;
78
79 ul {
80 list-style: none;
81 margin: 0;
82 padding: 0;
83 }
84 }
85
86 p.label,
87 details summary {
88 font-size: .8em;
89 color: color-mix(in srgb-linear, var(--foreground), var(--background) 10%);
90 padding: 5px 0;
91 margin-bottom: 0;
92 }
93
94 ul#sorts {
95 list-style: none;
96 margin: 0 0 10px;
97 padding: 0;
98
99 li {
100 button {
101 appearance: none;
102 border: none;
103 background-color: transparent;
104 color: var(--foreground);
105 border-radius: 0;
106 font-family: inherit;
107 font-size: inherit;
108 font-size: .9em;
109
110 img {
111 width: 16px;
112 height: 16px;
113 margin-right: 5px;
114 display: inline-block;
115 vertical-align: middle;
116 }
117
118 &.sort-active {
119 color: color-mix(in srgb-linear, var(--accent), #000000 10%);
120 font-weight: bold;
121 }
122 }
123 }
124 }
125
126 .afs-btn-filter {
127 appearance: none;
128 padding: 3px 0;
129 border: none;
130 border-radius: 0;
131 font-family: inherit;
132 background-color: transparent;
133
134 &.active {
135 color: color-mix(in srgb-linear, var(--accent), #000000 10%);
136 background-color: transparent;
137 font-weight: bold;
138 }
139 }
140
141 .afs-filter-search {
142 width: 100%;
143 padding: 0.5rem;
144 border: 1px solid var(--accent);
145 border-radius: 0.25rem;
146 font-size: 0.875rem;
147 color: var(--foreground);
148 transition: border-color 0.2s ease;
149 margin-bottom: 10px;
150 font-family: inherit;
151 }
152
153 .afs-filter-counter {
154 text-align: center;
155 font-style: italic;
156 font-size: .9em;
157 }
158}
159
160#list {
161 display: grid;
162 grid-area: list;
163 grid-template-columns: repeat(4, 1fr);
164 grid-template-rows: fit-content(300px);
165 gap: 10px;
166}
167</style>