diff --git a/MAINTAINING.md b/MAINTAINING.md index 8186d2a..868f0c2 100644 --- a/MAINTAINING.md +++ b/MAINTAINING.md @@ -7,8 +7,9 @@ Alternatively use the onboarding button on the app home ## Creating Accounts -To create an account, +To create an account, Role should be "read" "write" or "admin" + ``` npm run createaccount youruser yourpassword role ``` diff --git a/dev/create_account.ts b/dev/create_account.ts index b88acfd..bebd353 100644 --- a/dev/create_account.ts +++ b/dev/create_account.ts @@ -4,29 +4,26 @@ import logger from '~lib/logger' const prisma = new PrismaClient() - - - async function main() { await createUser(process.argv[2].trim(), process.argv[3].trim(), level[0], level[1]) } -const levels:Record = { - "admin": [true, true], - "write": [true, false], - "read": [false, false] +const levels: Record = { + admin: [true, true], + write: [true, false], + read: [false, false] } -console.log("-------") -if (process.argv.length < 5 || process.argv[2].length < 2 || process.argv[3].length<2 || process.argv[4].length < 2) { +console.log('-------') +if (process.argv.length < 5 || process.argv[2].length < 2 || process.argv[3].length < 2 || process.argv[4].length < 2) { console.log(process.argv) - console.warn("!Missing arguments") + console.warn('!Missing arguments') process.exit(1) } const level = levels[process.argv[4].trim()] if (levels[process.argv[4]] == null) { console.log(process.argv) - console.warn("Invalid level") + console.warn('Invalid level') process.exit(1) } diff --git a/prisma/migrations/20240831013103_add_team_associations/migration.sql b/prisma/migrations/20240831013103_add_team_associations/migration.sql new file mode 100644 index 0000000..201e674 --- /dev/null +++ b/prisma/migrations/20240831013103_add_team_associations/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Members" ADD COLUMN "is_primary_team" BOOLEAN NOT NULL DEFAULT true; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index f33a980..f53e1a4 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -120,6 +120,7 @@ model Member { slack_photo String? @db.VarChar(255) slack_photo_small String? @db.VarChar(255) fallback_photo String? @db.VarChar(255) + is_primary_team Boolean @default(true) active Boolean @default(true) createdAt DateTime @default(now()) @db.Timestamptz(6) diff --git a/src/lib/util.ts b/src/lib/util.ts index ebe4b04..f9f6e0f 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -1,11 +1,16 @@ import type { Member } from '@prisma/client' export function getMemberPhoto(member: Pick, small: boolean = false): string | null { - if (member.use_slack_photo) { - return (small ? member.slack_photo_small : member.slack_photo) ?? member.fallback_photo - } else { - return member.fallback_photo + let slackPhoto = member.slack_photo + let schoolPhoto = member.fallback_photo + if (small) { + schoolPhoto = schoolPhoto?.replace('w_300,h_300', 'w_40,h_40') ?? null + slackPhoto = member.slack_photo_small ?? slackPhoto } + if (slackPhoto) { + return slackPhoto ?? schoolPhoto + } + return schoolPhoto } export function safeParseInt(value: unknown): number | undefined { diff --git a/src/routes/admin/membercerts.tsx b/src/routes/admin/membercerts.tsx index 0a7a3dc..4d91cf9 100644 --- a/src/routes/admin/membercerts.tsx +++ b/src/routes/admin/membercerts.tsx @@ -2,7 +2,7 @@ import { Hono } from 'hono' import prisma from '~lib/prisma' import { scheduleCertAnnouncement } from '~tasks/certs' -export const router = new Hono().basePath('/membercerts') +export const router = new Hono().basePath('/membercerts/') export const cert_colors = [ 'bg-red-200 border-red-500 accent-red-400', // diff --git a/src/slack/blocks/member/user_hours.ts b/src/slack/blocks/member/user_hours.ts index 0a8786e..e16e6cc 100644 --- a/src/slack/blocks/member/user_hours.ts +++ b/src/slack/blocks/member/user_hours.ts @@ -19,6 +19,8 @@ export async function getUserHourSummaryBlocks(user: Prisma.MemberWhereUniqueInp Blocks.Divider(), Blocks.Section().fields('External', hours.external.toFixed(1)), Blocks.Divider(), + Blocks.Section().fields('Meeting', hours.meeting.toFixed(1)), + Blocks.Divider(), Blocks.Section().fields('Event', hours.event.toFixed(1)), Blocks.Divider(), Blocks.Section().fields('Summer', hours.summer.toFixed(1)), diff --git a/src/spreadsheet/index.ts b/src/spreadsheet/index.ts index ebcd2f0..76cf723 100644 --- a/src/spreadsheet/index.ts +++ b/src/spreadsheet/index.ts @@ -56,9 +56,9 @@ export async function updateSheet() { 'QualifyingHours', 'TotalHours', 'WeeklyHours', + 'IsPrimaryTeam', 'Photo', - 'Certifications', - 'FirstRegistered' + 'Certifications' ] as const const columns = Object.fromEntries(headers.map((h, i) => [h, i])) as Record<(typeof headers)[number], number> const rows: (string | number)[][] = [] @@ -81,6 +81,7 @@ export async function updateSheet() { row[columns.WeeklyHours] = weeklyHours[m.email] ?? 0 row[columns.Photo] = getMemberPhoto(m, true) ?? '' row[columns.Certifications] = certMap[m.email]?.join(', ') + row[columns.IsPrimaryTeam] = m.is_primary_team rows.push(row) if (hours.qualifying >= 50) { diff --git a/src/views/admin_members/grid.ts b/src/views/admin_members/grid.ts index 5e0268c..c9e0837 100644 --- a/src/views/admin_members/grid.ts +++ b/src/views/admin_members/grid.ts @@ -20,12 +20,18 @@ export function getColumns(params: { photo_column_formatter?: unknown }) { editable: true, headerName: 'Slack Photo Approved', initialWidth: 100 + }, + { + field: 'is_primary_team', + editable: true, + headerName: 'Primary Team?', + initialWidth: 100 } ] if (params.photo_column_formatter) { out.unshift({ headerName: '', - valueGetter: (params) => getMemberPhoto(params.data as never) ?? '', + valueGetter: (params) => getMemberPhoto(params.data as never, true) ?? '', editable: false, cellRenderer: params.photo_column_formatter, initialWidth: 100 diff --git a/src/views/admin_members/new_member.ts b/src/views/admin_members/new_member.ts index 9c9083f..eec317d 100644 --- a/src/views/admin_members/new_member.ts +++ b/src/views/admin_members/new_member.ts @@ -6,7 +6,7 @@ import 'ag-grid-community/styles/ag-theme-quartz.min.css' import { toTitleCase } from '~lib/util' import { getColumns } from '~views/admin_members/grid' -const getDefaultRow = () => ({ use_slack_photo: false }) as never +const getDefaultRow = () => ({ use_slack_photo: false, is_primary_team: false }) as never export async function initNewMemberTable(mainTable: GridApi) { class ButtonComponent implements ag.ICellRendererComp { private eGui!: HTMLElement