a fun bot for the hc slack
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add project category

dunkirk.sh f09a4441 feb03e20

verified
+124
+11
src/features/api/routes/projects.ts
··· 7 7 export type Project = { 8 8 projectName: string; 9 9 projectDescription: string; 10 + projectCategory: 11 + | "hardware" 12 + | "hardware_software" 13 + | "website" 14 + | "app" 15 + | "game" 16 + | "art_design" 17 + | "other"; 10 18 projectBannerUrl: string; 11 19 /** Total time spent on takes, in seconds */ 12 20 totalTakesTime: number; ··· 48 56 let projectsWithCounts: { 49 57 projectName: string; 50 58 projectDescription: string; 59 + projectCategory: string; 51 60 projectBannerUrl: string; 52 61 totalTakesTime: number; 53 62 userId: string; ··· 62 71 .select({ 63 72 projectName: usersTable.projectName, 64 73 projectDescription: usersTable.projectDescription, 74 + projectCategory: usersTable.projectCategory, 65 75 projectBannerUrl: usersTable.projectBannerUrl, 66 76 totalTakesTime: usersTable.totalTakesTime, 67 77 userId: usersTable.id, ··· 79 89 .select({ 80 90 projectName: usersTable.projectName, 81 91 projectDescription: usersTable.projectDescription, 92 + projectCategory: usersTable.projectCategory, 82 93 projectBannerUrl: usersTable.projectBannerUrl, 83 94 totalTakesTime: usersTable.totalTakesTime, 84 95 userId: usersTable.id,
+98
src/features/takes/handlers/settings.ts
··· 9 9 type HackatimeVersion, 10 10 } from "../../../libs/hackatime"; 11 11 import { deployToHackClubCDN } from "../../../libs/cdn"; 12 + import { getCategoryLabel } from "../../../libs/categories"; 13 + import type { Project } from "../../api/routes/projects"; 12 14 13 15 export async function handleSettings( 14 16 triggerID: string, ··· 18 20 let initialValues: { 19 21 project_name: string; 20 22 project_description: string; 23 + project_category: Project["projectCategory"]; 21 24 repo_link: string | undefined; 22 25 demo_link: string | undefined; 23 26 hackatime_version: HackatimeVersion; ··· 25 28 } = { 26 29 project_name: "", 27 30 project_description: "", 31 + project_category: "other", 28 32 repo_link: undefined, 29 33 demo_link: undefined, 30 34 hackatime_version: "v1", ··· 45 49 initialValues = { 46 50 project_name: existingUser.projectName, 47 51 project_description: existingUser.projectDescription, 52 + project_category: 53 + existingUser.projectCategory && 54 + [ 55 + "hardware", 56 + "hardware_software", 57 + "website", 58 + "app", 59 + "game", 60 + "art_design", 61 + "other", 62 + ].includes(existingUser.projectCategory) 63 + ? (existingUser.projectCategory as Project["projectCategory"]) 64 + : "other", 48 65 repo_link: existingUser.repoLink || undefined, 49 66 demo_link: existingUser.demoLink || undefined, 50 67 hackatime_version: ··· 116 133 }, 117 134 { 118 135 type: "input", 136 + block_id: "project_category", 137 + label: { 138 + type: "plain_text", 139 + text: "Project Category", 140 + }, 141 + element: { 142 + type: "static_select", 143 + action_id: "project_category_input", 144 + initial_option: initialValues.project_category 145 + ? { 146 + text: { 147 + type: "plain_text", 148 + text: getCategoryLabel( 149 + initialValues.project_category, 150 + ), 151 + }, 152 + value: initialValues.project_category, 153 + } 154 + : undefined, 155 + placeholder: { 156 + type: "plain_text", 157 + text: "Select a project category", 158 + }, 159 + options: [ 160 + { 161 + text: { 162 + type: "plain_text", 163 + text: "Hardware", 164 + }, 165 + value: "hardware", 166 + }, 167 + { 168 + text: { 169 + type: "plain_text", 170 + text: "Hardware + Software", 171 + }, 172 + value: "hardware_software", 173 + }, 174 + { 175 + text: { 176 + type: "plain_text", 177 + text: "Website", 178 + }, 179 + value: "website", 180 + }, 181 + { 182 + text: { 183 + type: "plain_text", 184 + text: "App", 185 + }, 186 + value: "app", 187 + }, 188 + { 189 + text: { 190 + type: "plain_text", 191 + text: "Game", 192 + }, 193 + value: "game", 194 + }, 195 + { 196 + text: { 197 + type: "plain_text", 198 + text: "Art & Design", 199 + }, 200 + value: "art_design", 201 + }, 202 + { 203 + text: { 204 + type: "plain_text", 205 + text: "Other", 206 + }, 207 + value: "other", 208 + }, 209 + ], 210 + }, 211 + }, 212 + { 213 + type: "input", 119 214 block_id: "project_banner", 120 215 label: { 121 216 type: "plain_text", ··· 269 364 projectDescription: 270 365 values.project_description?.project_description_input 271 366 ?.value, 367 + projectCategory: 368 + values.project_category?.project_category_input 369 + ?.selected_option?.value, 272 370 projectBannerUrl, 273 371 repoLink: values.repo_link?.repo_link_input?.value, 274 372 demoLink: values.demo_link?.demo_link_input?.value,
+14
src/libs/categories.ts
··· 1 + import type { Project } from "../features/api/routes/projects"; 2 + 3 + export function getCategoryLabel(category: Project["projectCategory"]): string { 4 + const categoryMap: Record<Project["projectCategory"], string> = { 5 + hardware: "Hardware", 6 + hardware_software: "Hardware + Software", 7 + website: "Website", 8 + app: "App", 9 + game: "Game", 10 + art_design: "Art & Design", 11 + other: "Other", 12 + }; 13 + return categoryMap[category] || "Other"; 14 + }
+1
src/libs/schema.ts
··· 25 25 totalTakesTime: integer("total_takes_time").default(0).notNull(), 26 26 hackatimeKeys: text("hackatime_keys").notNull().default("[]"), 27 27 projectName: text("project_name").notNull().default(""), 28 + projectCategory: text("project_category").notNull().default("other"), 28 29 projectDescription: text("project_description").notNull().default(""), 29 30 projectBannerUrl: text("project_banner_url").notNull().default(""), 30 31 hackatimeVersion: text("hackatime_version").notNull().default("v1"),