@@ -19,6 +19,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
1919import DragAndDropUpload from "./DragAndDropUpload" ;
2020import { Loader2 , Check , X } from "lucide-react" ;
2121import { EXTERNAL } from '@/constant' ;
22+ import { getUserProfile , type UserProfile } from '@/lib/utils' ;
2223
2324const schema = z . object ( {
2425 jobDescription : z . string ( ) . min ( 1 , "Paste the JD or provide a URL" ) ,
@@ -27,7 +28,7 @@ const schema = z.object({
2728
2829type FormValues = z . infer < typeof schema > ;
2930
30- type Me = { id : string } | null ;
31+ type Me = UserProfile | null ;
3132type BalanceRow = {
3233 id : number ;
3334 user : string ;
@@ -78,25 +79,28 @@ export default function RoleFitForm() {
7879
7980 const DIRECTUS_URL = EXTERNAL . directus_url ;
8081
82+ // Helper function to get authorization header
83+ const getAuthHeaders = ( ) : Record < string , string > => {
84+ return isAuthed
85+ ? { } // No auth header needed for authenticated users (using session cookies)
86+ : { Authorization : `Bearer ${ EXTERNAL . directus_key } ` } ; // Guest token for unauthenticated users
87+ } ;
88+
8189 // --- Auth & Quota fetch (session cookies) ---
8290 useEffect ( ( ) => {
8391 let cancelled = false ;
8492
8593 ( async ( ) => {
8694 try {
8795 // who am I?
88- const meRes = await fetch ( `${ DIRECTUS_URL } /users/me` , {
89- credentials : "include" ,
90- } ) ;
91- if ( ! meRes . ok ) {
96+ const meData = await getUserProfile ( DIRECTUS_URL ) ;
97+ if ( ! meData ) {
9298 setIsAuthed ( false ) ;
9399 setMe ( null ) ;
94100 setQuotaUsed ( null ) ;
95101 setQuotaRemaining ( null ) ;
96102 return ;
97103 }
98- const meJson = await meRes . json ( ) ;
99- const meData : Me = meJson ?. data ?? null ;
100104 if ( cancelled ) return ;
101105
102106 setMe ( meData ) ;
@@ -167,7 +171,8 @@ export default function RoleFitForm() {
167171 url . searchParams . set ( "limit" , "1" ) ;
168172
169173 const res = await fetch ( url . toString ( ) , {
170- headers : { Authorization : `Bearer ${ EXTERNAL . directus_key } ` } ,
174+ credentials : isAuthed ? "include" : "omit" ,
175+ headers : getAuthHeaders ( ) ,
171176 } ) ;
172177 const js = await res . json ( ) ;
173178 if ( ! res . ok ) throw new Error ( js ?. errors ?. [ 0 ] ?. message || "Checksum lookup failed" ) ;
@@ -193,7 +198,8 @@ export default function RoleFitForm() {
193198 fd . append ( "file" , file , file . name || "cv.pdf" ) ;
194199 const uploadRes = await fetch ( `${ DIRECTUS_URL } /files` , {
195200 method : "POST" ,
196- headers : { Authorization : `Bearer ${ EXTERNAL . directus_key } ` } ,
201+ credentials : isAuthed ? "include" : "omit" ,
202+ headers : getAuthHeaders ( ) ,
197203 body : fd ,
198204 } ) ;
199205 const uploadJs = await uploadRes . json ( ) ;
@@ -207,17 +213,21 @@ export default function RoleFitForm() {
207213
208214 /** Create submission */
209215 const createSubmission = async ( jd : string , fileId : string ) => {
216+ const body = {
217+ cv_file : fileId ,
218+ status : "submitted" ,
219+ job_description : { raw_input : jd } ,
220+ ...( isAuthed && me ?. id ? { user : me . id } : { } ) ,
221+ } ;
222+
210223 const res = await fetch ( `${ DIRECTUS_URL } /items/role_fit_index_submission` , {
211224 method : "POST" ,
225+ credentials : isAuthed ? "include" : "omit" ,
212226 headers : {
213- Authorization : `Bearer ${ EXTERNAL . directus_key } ` ,
227+ ... getAuthHeaders ( ) ,
214228 "Content-Type" : "application/json" ,
215229 } ,
216- body : JSON . stringify ( {
217- cv_file : fileId ,
218- status : "submitted" ,
219- job_description : { raw_input : jd } ,
220- } ) ,
230+ body : JSON . stringify ( body ) ,
221231 } ) ;
222232 const js = await res . json ( ) ;
223233 if ( ! res . ok ) throw new Error ( js ?. errors ?. [ 0 ] ?. message || "Submission failed" ) ;
@@ -235,7 +245,8 @@ export default function RoleFitForm() {
235245 url . searchParams . set ( "sort" , "-date_created" ) ;
236246 url . searchParams . set ( "filter[submission][_eq]" , id ) ;
237247 const res = await fetch ( url . toString ( ) , {
238- headers : { Authorization : `Bearer ${ EXTERNAL . directus_key } ` } ,
248+ credentials : isAuthed ? "include" : "omit" ,
249+ headers : getAuthHeaders ( ) ,
239250 } ) ;
240251 const js = await res . json ( ) ;
241252 if ( res . ok && js ?. data ?. length ) {
@@ -279,7 +290,10 @@ export default function RoleFitForm() {
279290 } , 90_000 ) ;
280291
281292 ws . onopen = ( ) => {
282- ws . send ( JSON . stringify ( { type : "auth" , access_token : EXTERNAL . directus_key } ) ) ;
293+ const authToken = isAuthed ? undefined : EXTERNAL . directus_key ;
294+ if ( authToken ) {
295+ ws . send ( JSON . stringify ( { type : "auth" , access_token : authToken } ) ) ;
296+ }
283297 } ;
284298
285299 ws . onmessage = async ( evt ) => {
@@ -313,7 +327,8 @@ export default function RoleFitForm() {
313327 url . searchParams . set ( "sort" , "-date_created" ) ;
314328 url . searchParams . set ( "filter[submission][_eq]" , String ( id ) ) ;
315329 const res = await fetch ( url . toString ( ) , {
316- headers : { Authorization : `Bearer ${ EXTERNAL . directus_key } ` } ,
330+ credentials : isAuthed ? "include" : "omit" ,
331+ headers : getAuthHeaders ( ) ,
317332 } ) ;
318333 const js = await res . json ( ) ;
319334 if ( res . ok && js ?. data ?. length ) {
@@ -519,14 +534,27 @@ export default function RoleFitForm() {
519534 ) : null }
520535 </ div >
521536
522- < Button
523- type = "submit"
524- variant = "default"
525- className = "w-full"
526- disabled = { submitting || step !== 0 }
527- >
528- { buttonText }
529- </ Button >
537+ { /* Conditionally show button or top-up link based on quota */ }
538+ { isAuthed === true && quotaRemaining === 0 ? (
539+ < Button
540+ asChild
541+ variant = "default"
542+ className = "w-full"
543+ >
544+ < a href = "/dashboard/role-fit-index/top-up" >
545+ Top Up Credits to Continue
546+ </ a >
547+ </ Button >
548+ ) : (
549+ < Button
550+ type = "submit"
551+ variant = "default"
552+ className = "w-full"
553+ disabled = { submitting || step !== 0 }
554+ >
555+ { buttonText }
556+ </ Button >
557+ ) }
530558 </ form >
531559 </ Form >
532560 </ CardContent >
0 commit comments