diff --git a/get-sticker-fulfilment.ts b/get-sticker-fulfilment.ts
new file mode 100644
index 0000000..044f200
--- /dev/null
+++ b/get-sticker-fulfilment.ts
@@ -0,0 +1,50 @@
+import Cryptr from 'cryptr';
+
+const cryptr = new Cryptr(process.env.APP_SECRET_KEY ?? '');
+
+export function encrypt(plaintext: string) {
+ return cryptr.encrypt(plaintext);
+}
+
+export function decrypt(ciphertext: string) {
+ return cryptr.decrypt(ciphertext);
+}
+
+const tokens = [''];
+
+export async function getUserData(token: string) {
+ const userDataURL = new URL(`https://auth.hackclub.com/api/v1/me`);
+ const userDataRes = await fetch(userDataURL, {
+ method: 'GET',
+ headers: {
+ Authorization: `Bearer ${token}`
+ }
+ });
+
+ if (!userDataRes.ok) {
+ throw new Error('Failed to fetch user data');
+ }
+
+ const userDataJSON = await userDataRes.json();
+
+ return userDataJSON.identity!;
+}
+
+const countries: Record = {};
+
+for (let i = 0; i < tokens.length; i++) {
+ try {
+ const token = decrypt(tokens[i]);
+ const userData = await getUserData(token);
+ const { addresses } = userData;
+ const address = addresses?.find((address: { primary: boolean }) => address.primary);
+ console.log('Address', i + '/' + tokens.length + ':', address.country);
+
+ countries[address.country as string] = (countries[address.country as string] ?? 0) + 1;
+ } catch {
+ console.warn('Failed: user ' + i);
+ }
+}
+
+console.log('\n');
+console.log(countries);
diff --git a/src/routes/dashboard/admin/admin/stickers/+page.server.ts b/src/routes/dashboard/admin/admin/stickers/+page.server.ts
index 25afdce..944cc72 100644
--- a/src/routes/dashboard/admin/admin/stickers/+page.server.ts
+++ b/src/routes/dashboard/admin/admin/stickers/+page.server.ts
@@ -1,7 +1,8 @@
import { db } from '$lib/server/db/index.js';
import { user, project } from '$lib/server/db/schema.js';
import { error } from '@sveltejs/kit';
-import { sql, and, eq, asc } from 'drizzle-orm';
+import { sql, and, eq, asc, ne } from 'drizzle-orm';
+import type { Actions } from './$types';
export async function load({ locals }) {
if (!locals.user) {
@@ -28,7 +29,10 @@ export async function load({ locals }) {
.innerJoin(user, eq(project.userId, user.id))
.where(
and(
- eq(project.status, 'finalized'),
+ ne(project.status, 'building'),
+ ne(project.status, 'submitted'),
+ ne(project.status, 'rejected'),
+ ne(project.status, 'rejected_locked'),
eq(project.deleted, false),
eq(user.stickersShipped, false)
)
@@ -40,3 +44,39 @@ export async function load({ locals }) {
users
};
}
+
+export const actions = {
+ fulfil: async ({ locals, request }) => {
+ if (!locals.user) {
+ throw error(500);
+ }
+ if (!locals.user.hasAdmin) {
+ throw error(403, { message: 'oi get out' });
+ }
+
+ const data = await request.formData();
+ const id: number = parseInt(data.get('id')?.toString() ?? '');
+
+ const [queriedUser] = await db.select().from(user).where(eq(user.id, id));
+
+ if (!queriedUser) {
+ return {
+ userNotFound: true
+ };
+ }
+
+ if (queriedUser.stickersShipped) {
+ return {
+ alreadyFulfilled: true,
+ id
+ };
+ }
+
+ await db.update(user).set({ stickersShipped: true }).where(eq(user.id, id));
+
+ return {
+ fulfilled: true,
+ id
+ }
+ }
+} satisfies Actions;
diff --git a/src/routes/dashboard/admin/admin/stickers/+page.svelte b/src/routes/dashboard/admin/admin/stickers/+page.svelte
index 4cabc4d..ec97f6f 100644
--- a/src/routes/dashboard/admin/admin/stickers/+page.svelte
+++ b/src/routes/dashboard/admin/admin/stickers/+page.svelte
@@ -1,14 +1,17 @@
@@ -18,7 +21,48 @@
Stickers/keyrings
- Showing {filteredUsers.length} users
+
+
+ Showing {filteredUsers.length} users
@@ -48,7 +92,7 @@
{user.slackId}
-
Project created
+
Project created
{relativeDate(user.projectCreatedAt)}