mirror of
https://github.com/System-End/scraps.git
synced 2026-04-19 22:05:09 +00:00
no hackatiem id sent
This commit is contained in:
parent
42ce53ea15
commit
2348592b58
5 changed files with 61 additions and 38 deletions
|
|
@ -82,7 +82,6 @@ hackatime.get('/projects', async ({ headers }) => {
|
|||
|
||||
return {
|
||||
slackId: user.slackId,
|
||||
hackatimeUserId,
|
||||
projects: projects.map((p) => ({
|
||||
name: p.name,
|
||||
hours: Math.round(p.total_duration / 3600 * 10) / 10,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { reviewsTable } from '../schemas/reviews'
|
|||
import { usersTable } from '../schemas/users'
|
||||
import { projectActivityTable } from '../schemas/activity'
|
||||
import { getUserFromSession, fetchUserIdentity } from '../lib/auth'
|
||||
import { syncSingleProject } from '../lib/hackatime-sync'
|
||||
import { syncSingleProject, getHackatimeUser } from '../lib/hackatime-sync'
|
||||
import { notifyProjectSubmitted } from '../lib/slack'
|
||||
import { submitProjectToYSWS } from '../lib/ysws'
|
||||
import { config } from '../config'
|
||||
|
|
@ -19,6 +19,53 @@ function parseHackatimeProject(hackatimeProject: string | null): string | null {
|
|||
return hackatimeProject.trim()
|
||||
}
|
||||
|
||||
async function prefixHackatimeIds(hackatimeProject: string | null, email: string): Promise<string | null> {
|
||||
if (!hackatimeProject) return null
|
||||
const names = hackatimeProject.split(',').map(p => p.trim()).filter(p => p.length > 0)
|
||||
if (names.length === 0) return null
|
||||
|
||||
// Check if already prefixed (has numeric id: prefix)
|
||||
const alreadyPrefixed = names.every(n => {
|
||||
const colonIdx = n.indexOf(':')
|
||||
return colonIdx !== -1 && !n.startsWith('U') && !isNaN(parseInt(n.substring(0, colonIdx), 10))
|
||||
})
|
||||
if (alreadyPrefixed) return hackatimeProject
|
||||
|
||||
const hackatimeUser = await getHackatimeUser(email)
|
||||
if (!hackatimeUser || typeof hackatimeUser.user_id !== 'number') return hackatimeProject
|
||||
|
||||
return names.map(name => {
|
||||
const colonIdx = name.indexOf(':')
|
||||
if (colonIdx !== -1 && !name.startsWith('U') && !isNaN(parseInt(name.substring(0, colonIdx), 10))) {
|
||||
return name
|
||||
}
|
||||
const slashIdx = name.indexOf('/')
|
||||
if (slashIdx !== -1 && name.startsWith('U')) {
|
||||
name = name.substring(slashIdx + 1)
|
||||
}
|
||||
return `${hackatimeUser.user_id}:${name}`
|
||||
}).join(',')
|
||||
}
|
||||
|
||||
function stripHackatimeIds(hackatimeProject: string | null): string | null {
|
||||
if (!hackatimeProject) return null
|
||||
return hackatimeProject
|
||||
.split(',')
|
||||
.map(entry => {
|
||||
const trimmed = entry.trim()
|
||||
const colonIdx = trimmed.indexOf(':')
|
||||
if (colonIdx !== -1 && !trimmed.startsWith('U')) {
|
||||
return trimmed.substring(colonIdx + 1)
|
||||
}
|
||||
const slashIdx = trimmed.indexOf('/')
|
||||
if (slashIdx !== -1 && trimmed.startsWith('U')) {
|
||||
return trimmed.substring(slashIdx + 1)
|
||||
}
|
||||
return trimmed
|
||||
})
|
||||
.join(',') || null
|
||||
}
|
||||
|
||||
function parseHackatimeProjects(hackatimeProject: string | null): string | null {
|
||||
if (!hackatimeProject) return null
|
||||
return hackatimeProject
|
||||
|
|
@ -196,6 +243,7 @@ projects.get('/', async ({ headers, query }) => {
|
|||
return {
|
||||
data: projectsList.map(p => ({
|
||||
...p,
|
||||
hackatimeProject: stripHackatimeIds(p.hackatimeProject),
|
||||
status: p.status === 'pending_admin_approval' ? 'waiting_for_review' : p.status
|
||||
})),
|
||||
pagination: {
|
||||
|
|
@ -367,7 +415,7 @@ projects.get('/:id', async ({ params, headers }) => {
|
|||
image: project[0].image,
|
||||
githubUrl: project[0].githubUrl,
|
||||
playableUrl: project[0].playableUrl,
|
||||
hackatimeProject: isOwner ? project[0].hackatimeProject : undefined,
|
||||
hackatimeProject: isOwner ? stripHackatimeIds(project[0].hackatimeProject) : undefined,
|
||||
hours: projectHours,
|
||||
hoursOverride: isOwner ? project[0].hoursOverride : undefined,
|
||||
tier: project[0].tier,
|
||||
|
|
@ -410,7 +458,7 @@ projects.post('/', async ({ body, headers }) => {
|
|||
return { error: 'Image must be from cdn.hackclub.com' }
|
||||
}
|
||||
|
||||
const projectName = parseHackatimeProjects(data.hackatimeProject || null)
|
||||
const projectName = await prefixHackatimeIds(parseHackatimeProjects(data.hackatimeProject || null), user.email)
|
||||
const tier = data.tier !== undefined ? Math.max(1, Math.min(4, data.tier)) : 1
|
||||
|
||||
const newProject = await db
|
||||
|
|
@ -441,7 +489,7 @@ projects.post('/', async ({ body, headers }) => {
|
|||
action: 'project_created'
|
||||
})
|
||||
|
||||
return newProject[0]
|
||||
return { ...newProject[0], hackatimeProject: stripHackatimeIds(newProject[0].hackatimeProject) }
|
||||
})
|
||||
|
||||
projects.put('/:id', async ({ params, body, headers }) => {
|
||||
|
|
@ -484,7 +532,7 @@ projects.put('/:id', async ({ params, body, headers }) => {
|
|||
return { error: playableCheck.error }
|
||||
}
|
||||
|
||||
const projectName = parseHackatimeProjects(data.hackatimeProject || null)
|
||||
const projectName = await prefixHackatimeIds(parseHackatimeProjects(data.hackatimeProject || null), user.email)
|
||||
const tier = data.tier !== undefined ? Math.max(1, Math.min(4, data.tier)) : undefined
|
||||
|
||||
const updated = await db
|
||||
|
|
@ -513,7 +561,7 @@ projects.put('/:id', async ({ params, body, headers }) => {
|
|||
updated[0].hours = syncResult.hours
|
||||
}
|
||||
|
||||
return updated[0]
|
||||
return { ...updated[0], hackatimeProject: stripHackatimeIds(updated[0].hackatimeProject) }
|
||||
})
|
||||
|
||||
projects.delete("/:id", async ({ params, headers }) => {
|
||||
|
|
@ -579,7 +627,7 @@ projects.post("/:id/unsubmit", async ({ params, headers }) => {
|
|||
action: 'project_unsubmitted'
|
||||
})
|
||||
|
||||
return updated[0]
|
||||
return { ...updated[0], hackatimeProject: stripHackatimeIds(updated[0].hackatimeProject) }
|
||||
})
|
||||
|
||||
// Submit project for review
|
||||
|
|
@ -668,7 +716,7 @@ projects.post("/:id/submit", async ({ params, headers, body }) => {
|
|||
}
|
||||
}
|
||||
|
||||
return updated[0]
|
||||
return { ...updated[0], hackatimeProject: stripHackatimeIds(updated[0].hackatimeProject) }
|
||||
})
|
||||
|
||||
// Get project reviews (public feedback)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@
|
|||
let selectedHackatimeProjects = $state<HackatimeProject[]>([]);
|
||||
let hackatimeProjects = $state<HackatimeProject[]>([]);
|
||||
let userSlackId = $state<string | null>(null);
|
||||
let hackatimeUserId = $state<number | null>(null);
|
||||
let loadingProjects = $state(false);
|
||||
let showDropdown = $state(false);
|
||||
let loading = $state(false);
|
||||
|
|
@ -97,7 +96,6 @@
|
|||
const data = await response.json();
|
||||
hackatimeProjects = data.projects || [];
|
||||
userSlackId = data.slackId || null;
|
||||
hackatimeUserId = data.hackatimeUserId ?? null;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch hackatime projects:', e);
|
||||
|
|
@ -198,7 +196,7 @@
|
|||
error = null;
|
||||
|
||||
const hackatimeValue = selectedHackatimeProjects.length > 0
|
||||
? selectedHackatimeProjects.map(p => hackatimeUserId != null ? `${hackatimeUserId}:${p.name}` : p.name).join(',')
|
||||
? selectedHackatimeProjects.map(p => p.name).join(',')
|
||||
: null;
|
||||
const finalGithubUrl = githubUrl.trim() || selectedHackatimeProjects[0]?.repoUrl || null;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
let uploadingImage = $state(false);
|
||||
let hackatimeProjects = $state<HackatimeProject[]>([]);
|
||||
let userSlackId = $state<string | null>(null);
|
||||
let hackatimeUserId = $state<number | null>(null);
|
||||
let selectedHackatimeName = $state<string | null>(null);
|
||||
let loadingProjects = $state(false);
|
||||
let showDropdown = $state(false);
|
||||
|
|
@ -73,7 +72,6 @@
|
|||
const data = await response.json();
|
||||
hackatimeProjects = data.projects || [];
|
||||
userSlackId = data.slackId || null;
|
||||
hackatimeUserId = data.hackatimeUserId ?? null;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch hackatime projects:', e);
|
||||
|
|
@ -87,16 +85,7 @@
|
|||
editedProject = { ...project };
|
||||
imagePreview = project.image;
|
||||
error = null;
|
||||
const raw = project.hackatimeProject || null;
|
||||
if (raw) {
|
||||
const colonIdx = raw.indexOf(':');
|
||||
const slashIdx = raw.indexOf('/');
|
||||
if (colonIdx !== -1 && !raw.startsWith('U')) selectedHackatimeName = raw.substring(colonIdx + 1);
|
||||
else if (slashIdx !== -1 && raw.startsWith('U')) selectedHackatimeName = raw.substring(slashIdx + 1);
|
||||
else selectedHackatimeName = raw;
|
||||
} else {
|
||||
selectedHackatimeName = null;
|
||||
}
|
||||
selectedHackatimeName = project.hackatimeProject || null;
|
||||
fetchHackatimeProjects();
|
||||
}
|
||||
});
|
||||
|
|
@ -165,9 +154,7 @@
|
|||
loading = true;
|
||||
error = null;
|
||||
|
||||
const hackatimeValue = selectedHackatimeName
|
||||
? (hackatimeUserId != null ? `${hackatimeUserId}:${selectedHackatimeName}` : selectedHackatimeName)
|
||||
: null;
|
||||
const hackatimeValue = selectedHackatimeName || null;
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_URL}/projects/${editedProject.id}`, {
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
let uploadingImage = $state(false);
|
||||
let hackatimeProjects = $state<HackatimeProject[]>([]);
|
||||
let userSlackId = $state<string | null>(null);
|
||||
let hackatimeUserId = $state<number | null>(null);
|
||||
let selectedHackatimeNames = $state<string[]>([]);
|
||||
let loadingProjects = $state(false);
|
||||
let showDropdown = $state(false);
|
||||
|
|
@ -106,14 +105,7 @@
|
|||
aiDescription = project?.aiDescription || '';
|
||||
reviewerNotes = project?.reviewerNotes || '';
|
||||
if (project?.hackatimeProject) {
|
||||
selectedHackatimeNames = project.hackatimeProject.split(',').map((p: string) => {
|
||||
p = p.trim();
|
||||
const colonIdx = p.indexOf(':');
|
||||
if (colonIdx !== -1 && !p.startsWith('U')) return p.substring(colonIdx + 1);
|
||||
const slashIdx = p.indexOf('/');
|
||||
if (slashIdx !== -1 && p.startsWith('U')) return p.substring(slashIdx + 1);
|
||||
return p;
|
||||
}).filter((p: string) => p.length > 0);
|
||||
selectedHackatimeNames = project.hackatimeProject.split(',').map((p: string) => p.trim()).filter((p: string) => p.length > 0);
|
||||
}
|
||||
fetchHackatimeProjects();
|
||||
} catch (e) {
|
||||
|
|
@ -133,7 +125,6 @@
|
|||
const apiData = await response.json();
|
||||
hackatimeProjects = apiData.projects || [];
|
||||
userSlackId = apiData.slackId || null;
|
||||
hackatimeUserId = apiData.hackatimeUserId ?? null;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch hackatime projects:', e);
|
||||
|
|
@ -225,7 +216,7 @@
|
|||
error = null;
|
||||
|
||||
const hackatimeValue = selectedHackatimeNames.length > 0
|
||||
? selectedHackatimeNames.map(n => hackatimeUserId != null ? `${hackatimeUserId}:${n}` : n).join(',')
|
||||
? selectedHackatimeNames.join(',')
|
||||
: null;
|
||||
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue