1- import React , { useState } from "react" ;
1+ import React , { useState , useEffect } from "react" ;
22import { toast } from "react-toastify" ;
33import { ShieldCheckIcon , ArrowPathIcon , ListBulletIcon } from "@heroicons/react/24/outline" ;
44
55const SelectedReposVulnerabilityScanner = ( { setResult, isLoading, setIsLoading, userId } ) => {
6- const [ selectedRepos , setSelectedRepos ] = useState ( [ ] ) ;
6+ const [ repos , setRepos ] = useState ( [ ] ) ;
7+ const [ selectedRepo , setSelectedRepo ] = useState ( "" ) ;
8+ const [ reposLoading , setReposLoading ] = useState ( false ) ;
9+ const [ reposError , setReposError ] = useState ( "" ) ;
10+
11+ useEffect ( ( ) => {
12+ const fetchRepos = async ( ) => {
13+ setReposLoading ( true ) ;
14+ setReposError ( "" ) ;
15+ try {
16+ const response = await fetch ( "http://127.0.0.1:5000/github/repos" , {
17+ method : "GET" ,
18+ headers : { Authorization : `Bearer ${ localStorage . getItem ( "token" ) } ` } ,
19+ } ) ;
20+ if ( ! response . ok ) {
21+ const errorData = await response . json ( ) ;
22+ throw new Error ( errorData . error || "Trouble while retrieving repos." ) ;
23+ }
24+ const data = await response . json ( ) ;
25+ const selectedRepos = data . filter ( ( repo ) => repo . is_selected ) ;
26+ setRepos ( selectedRepos ) ;
27+ if ( selectedRepos . length > 0 ) {
28+ setSelectedRepo ( selectedRepos [ 0 ] . full_name ) ;
29+ }
30+ toast . success ( "Selected repos loaded!" , {
31+ toastId : "selected-repos-loaded" ,
32+ position : "top-right" ,
33+ autoClose : 3000 ,
34+ theme : "light" ,
35+ } ) ;
36+ } catch ( err ) {
37+ setReposError ( "Impossible to retrieve the selected repos" ) ;
38+ toast . error ( err . message , {
39+ position : "top-right" ,
40+ autoClose : 3000 ,
41+ theme : "light" ,
42+ } ) ;
43+ } finally {
44+ setReposLoading ( false ) ;
45+ }
46+ } ;
47+ fetchRepos ( ) ;
48+ } , [ ] ) ;
49+
50+ useEffect ( ( ) => {
51+ localStorage . setItem ( "lastSelectedRepo" , selectedRepo ) ;
52+ } , [ selectedRepo ] ) ;
753
854 const scanSelectedRepos = async ( ) => {
9- if ( selectedRepos . length === 0 ) {
10- toast . warn ( "Please select at least one repository to scan!" , {
55+ if ( ! selectedRepo ) {
56+ toast . warn ( "Please select a repository to scan!" , {
1157 position : "top-right" ,
1258 autoClose : 3000 ,
1359 theme : "light" ,
@@ -17,14 +63,21 @@ const SelectedReposVulnerabilityScanner = ({ setResult, isLoading, setIsLoading,
1763
1864 setIsLoading ( true ) ;
1965 try {
20- const response = await fetch ( "http://127.0.0.1:5000/scan-selected-repos" , {
66+ const repoData = repos . find ( ( r ) => r . full_name === selectedRepo ) ;
67+ if ( ! repoData ) {
68+ throw new Error ( "Selected repository not found" ) ;
69+ }
70+
71+ const formData = new FormData ( ) ;
72+ formData . append ( "input_type" , "repo" ) ;
73+ formData . append ( "repo_url" , repoData . html_url ) ;
74+
75+ const response = await fetch ( "http://127.0.0.1:5000/semgrep" , {
2176 method : "POST" ,
2277 headers : {
23- "Content-Type" : "application/json" ,
2478 Authorization : `Bearer ${ localStorage . getItem ( "token" ) } ` ,
25- "X-User-ID" : userId ,
2679 } ,
27- body : JSON . stringify ( { repositories : selectedRepos } ) ,
80+ body : formData ,
2881 } ) ;
2982
3083 if ( ! response . ok ) {
@@ -33,7 +86,7 @@ const SelectedReposVulnerabilityScanner = ({ setResult, isLoading, setIsLoading,
3386 }
3487
3588 const data = await response . json ( ) ;
36- setResult ( data ) ;
89+ setResult ( { repo : repoData . full_name , data } ) ;
3790 toast . success ( "Vulnerability scan completed successfully" , {
3891 position : "top-right" ,
3992 autoClose : 3000 ,
@@ -56,21 +109,48 @@ const SelectedReposVulnerabilityScanner = ({ setResult, isLoading, setIsLoading,
56109 < ListBulletIcon className = "h-7 w-7 text-red-400" />
57110 Vulnerability Scanner - Selected Repositories
58111 </ h2 >
59- < div className = "mb-6" >
60- < p className = "text-gray-600 mb -4" >
61- Select repositories from your account to scan for vulnerabilities:
62- </ p >
63- < div className = "bg-gray-100 p-4 rounded-lg" >
64- < p className = "text-gray-500 text-center" >
65- Repository selection interface will be implemented here
66- </ p >
112+ { reposLoading ? (
113+ < div className = "flex justify-center items-center py -4" >
114+ < ArrowPathIcon className = "h-6 w-6 text-blue-500 animate-spin" />
115+ < span className = "ml-2 text-gray-400" > Loading Repos... </ span >
116+ </ div >
117+ ) : reposError ? (
118+ < div className = "flex justify-center items-center py-4 text-red-400" >
119+ < p > { reposError } < /p >
67120 </ div >
68- </ div >
121+ ) : repos . length > 0 ? (
122+ < div className = "mb-6" >
123+ < label htmlFor = "repo-select" className = "text-gray-600 mb-2 block" >
124+ Select a repository to scan:
125+ </ label >
126+ < select
127+ id = "repo-select"
128+ value = { selectedRepo }
129+ onChange = { ( e ) => setSelectedRepo ( e . target . value ) }
130+ disabled = { isLoading }
131+ className = { `w-full bg-gray-700 text-gray-100 border border-gray-600 rounded-lg p-3 focus:outline-none focus:ring-2 focus:ring-red-500 focus:border-transparent transition duration-200 ${
132+ isLoading ? "opacity-50" : ""
133+ } `}
134+ >
135+ < option value = "" > Select a repository</ option >
136+ { repos . map ( ( repo ) => (
137+ < option key = { repo . full_name } value = { repo . full_name } >
138+ { repo . full_name }
139+ </ option >
140+ ) ) }
141+ </ select >
142+ </ div >
143+ ) : (
144+ < p className = "text-gray-400" >
145+ There are no selected repos yet, go to dashboard to select one
146+ </ p >
147+ ) }
69148 < button
149+ type = "button"
70150 onClick = { scanSelectedRepos }
71- disabled = { isLoading || selectedRepos . length === 0 }
151+ disabled = { isLoading || ! selectedRepo }
72152 className = { `w-full sm:w-auto bg-red-600 text-white px-6 py-3 rounded-lg font-semibold hover:bg-red-700 transition-colors duration-200 flex items-center justify-center gap-2 ${
73- isLoading || selectedRepos . length === 0 ? "opacity-50 cursor-not-allowed" : ""
153+ isLoading || ! selectedRepo ? "opacity-50 cursor-not-allowed" : ""
74154 } `}
75155 >
76156 { isLoading ? (
@@ -81,7 +161,7 @@ const SelectedReposVulnerabilityScanner = ({ setResult, isLoading, setIsLoading,
81161 ) : (
82162 < >
83163 < ShieldCheckIcon className = "h-5 w-5" />
84- Scan Selected Repositories
164+ Scan Selected Repository
85165 </ >
86166 ) }
87167 </ button >
0 commit comments