Omar ID EL MOUMEN commited on
Commit
327d208
·
1 Parent(s): 95d420b

Upload frontend

Browse files
Files changed (3) hide show
  1. frontend/index.html +26 -0
  2. frontend/script.js +201 -0
  3. frontend/style.css +130 -0
frontend/index.html ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <head>
2
+ <title>ArXiv 6G Research Search</title>
3
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
4
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
5
+ <link rel="stylesheet" href="style.css">
6
+ </head>
7
+ <body>
8
+ <h1>ArXiv 6G Research Search</h1>
9
+ <div id="search-container">
10
+ <input type="text" id="keyword-input" placeholder="Enter search keyword">
11
+ <input type="number" min="1" id="limit-input" value="15" disabled placeholder="Enter limit of documents">
12
+ <button id="search-button">Search</button>
13
+ </div>
14
+ <input type="checkbox" name="limit" id="limit-check"><label for="limit-check">Custom limit ?</label>
15
+ <div id="results-container"></div>
16
+ <div id="popup" class="popup">
17
+ <div class="popup-content">
18
+ <span class="close">&times;</span>
19
+ <h2 id="popup-title">Fenêtre Popup</h2>
20
+ <div class="scrollable-text">
21
+
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <script src="script.js"></script>
26
+ </body>
frontend/script.js ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener('DOMContentLoaded', function() {
2
+ const searchInput = document.getElementById('keyword-input');
3
+ const limitInput = document.getElementById("limit-input");
4
+ const searchButton = document.getElementById('search-button');
5
+ const limitCheckbox = document.getElementById("limit-check");
6
+ const popupText = document.querySelector(".scrollable-text");
7
+ const popupTitle = document.getElementById("popup-title");
8
+ const body = document.body;
9
+ const resultsContainer = document.getElementById('results-container');
10
+
11
+ // Function to perform the search
12
+ async function performSearch() {
13
+ const keyword = searchInput.value.trim();
14
+ let limit = limitInput.value.trim();
15
+ if (!keyword) {
16
+ resultsContainer.innerHTML = '<div class="error-message">Please enter a search keyword.</div>';
17
+ return;
18
+ }
19
+
20
+ if (!limit){
21
+ limit = 15;
22
+ }
23
+
24
+ // Show loading indicator
25
+ resultsContainer.innerHTML = '<div class="loading">Searching for ' + limit.toString() + ' papers about "' + keyword + '"...</div>';
26
+
27
+ try {
28
+ const response = await fetch('https://om4r932-arxiv.hf.space/search', {
29
+ method: 'POST',
30
+ headers: {
31
+ 'Accept': 'application/json',
32
+ 'Content-Type': 'application/json'
33
+ },
34
+ body: JSON.stringify({
35
+ keyword: keyword,
36
+ limit: limit
37
+ })
38
+ });
39
+
40
+ if (!response.ok) {
41
+ throw new Error(`HTTP error! status: ${response.status}`);
42
+ }
43
+
44
+ const data = await response.json();
45
+
46
+ if (data.error) {
47
+ resultsContainer.innerHTML = `<div class="error-message">Search error: ${data.message}</div>`;
48
+ return;
49
+ }
50
+
51
+ displayResults(data.message);
52
+ } catch (error) {
53
+ console.error('Search error:', error);
54
+ resultsContainer.innerHTML = `<div class="error-message">Error performing search: ${error.message}</div>`;
55
+ }
56
+ }
57
+
58
+ function handleCustomLimit(){
59
+ if(limitCheckbox.checked){
60
+ limitInput.removeAttribute("disabled")
61
+ } else {
62
+ limitInput.value = 15;
63
+ limitInput.setAttribute("disabled", "")
64
+ }
65
+ }
66
+
67
+ // Function to display the results
68
+ function displayResults(results) {
69
+ resultsContainer.innerHTML = '';
70
+
71
+ if (!results || Object.keys(results).length === 0) {
72
+ resultsContainer.innerHTML = '<div class="error-message">No results found. Try a different keyword.</div>';
73
+ return;
74
+ }
75
+
76
+ const resultsCount = Object.keys(results).length;
77
+ const resultsHeader = document.createElement('h2');
78
+ resultsHeader.textContent = `Found ${resultsCount} paper${resultsCount > 1 ? 's' : ''}`;
79
+ resultsContainer.appendChild(resultsHeader);
80
+
81
+ Object.entries(results).forEach(([id, paper]) => {
82
+ const paperElement = document.createElement('div');
83
+ paperElement.classList.add('paper-result');
84
+
85
+ // Format the abstract to preserve line breaks
86
+ const formattedAbstract = paper.abstract;
87
+
88
+ paperElement.innerHTML = `
89
+ <div class="paper-title">${paper.title}</div>
90
+ <div class="paper-authors">${paper.authors}</div>
91
+ <div class="paper-date">Published: ${paper.date}</div>
92
+ <div class="paper-abstract">${formattedAbstract}</div>
93
+ <div class="paper-id">ArXiv ID: ${id}</div>
94
+ <a type="button" class="btn btn-primary" role="button" href="${paper.pdf}">Show PDF</a>
95
+ <input type="button" value="Extract Text" doc="${id}" class="extractText btn btn-success"/>
96
+ <input type="button" value="Get titles" doc="${id}" class="getTitle btn btn-danger"/>
97
+ `;
98
+ resultsContainer.appendChild(paperElement);
99
+ });
100
+
101
+ document.querySelectorAll(".extractText").forEach(btn => {
102
+ btn.addEventListener("click", async function () {
103
+ let id_doc = btn.getAttribute("doc");
104
+ popupTitle.textContent = `PDF extraction - Document no ${id_doc}`;
105
+ try {
106
+ const response = await fetch('https://om4r932-arxiv.hf.space/extract', {
107
+ method: 'POST',
108
+ headers: {
109
+ 'Accept': 'application/json',
110
+ 'Content-Type': 'application/json'
111
+ },
112
+ body: JSON.stringify({
113
+ doc_id: id_doc
114
+ })
115
+ });
116
+
117
+ if (!response.ok) {
118
+ throw new Error(`HTTP error! status: ${response.status}`);
119
+ }
120
+
121
+ const data = await response.json();
122
+
123
+ if (data.error) {
124
+ popupText.innerHTML = `<div class="error-message">Search error: ${data.message}</div>`;
125
+ return;
126
+ }
127
+
128
+ popupText.textContent = data.text;
129
+ } catch (error) {
130
+ console.error('Search error:', error);
131
+ popupText.innerHTML = `<div class="error-message">Error performing search: ${error.message}</div>`;
132
+ }
133
+ document.getElementById("popup").style.display = "flex";
134
+ body.classList.add("no-scroll")
135
+ });
136
+ })
137
+
138
+ document.querySelectorAll(".getTitle").forEach(btn => {
139
+ btn.addEventListener("click", async function () {
140
+ let id_doc = btn.getAttribute("doc");
141
+ popupTitle.textContent = `Chapters - Document no ${id_doc}`;
142
+ try {
143
+ const response = await fetch('https://om4r932-arxiv.hf.space/extract', {
144
+ method: 'POST',
145
+ headers: {
146
+ 'Accept': 'application/json',
147
+ 'Content-Type': 'application/json'
148
+ },
149
+ body: JSON.stringify({
150
+ doc_id: id_doc
151
+ })
152
+ });
153
+
154
+ if (!response.ok) {
155
+ throw new Error(`HTTP error! status: ${response.status}`);
156
+ }
157
+
158
+ const data = await response.json();
159
+
160
+ if (data.error) {
161
+ popupText.innerHTML = `<div class="error-message">Search error: ${data.message}</div>`;
162
+ return;
163
+ }
164
+ let t = "";
165
+ if(typeof data.titles == Array){
166
+ data.titles.forEach(title => {
167
+ t += title + "\n";
168
+ });
169
+ popupText.textContent = t;
170
+ }else {
171
+ popupText.textContent = data.titles;
172
+ }
173
+ } catch (error) {
174
+ console.error('Search error:', error);
175
+ popupText.innerHTML = `<div class="error-message">Error performing search: ${error.message}</div>`;
176
+ }
177
+ document.getElementById("popup").style.display = "flex";
178
+ body.classList.add("no-scroll")
179
+ });
180
+ })
181
+ }
182
+
183
+ // Add event listeners
184
+ document.querySelector(".close").addEventListener("click", () => {
185
+ document.getElementById("popup").style.display = "none";
186
+ body.classList.remove("no-scroll");
187
+ })
188
+
189
+ window.addEventListener("click", function (event) {
190
+ if (event.target === popup) {
191
+ popup.style.display = "none";
192
+ body.classList.remove("no-scroll");
193
+ }
194
+ });
195
+
196
+ searchButton.addEventListener('click', performSearch);
197
+ limitCheckbox.addEventListener("change", handleCustomLimit);
198
+ searchInput.addEventListener('keypress', (e) => {
199
+ if (e.key === 'Enter') performSearch();
200
+ });
201
+ });
frontend/style.css ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ font-family: Arial, sans-serif;
3
+ max-width: 800px;
4
+ margin: 0 auto;
5
+ padding: 20px;
6
+ }
7
+ #search-container {
8
+ display: flex;
9
+ margin-bottom: 20px;
10
+ }
11
+ #keyword-input {
12
+ flex-grow: 1;
13
+ padding: 10px;
14
+ font-size: 16px;
15
+ border: 1px solid #ccc;
16
+ border-radius: 4px 0 0 4px;
17
+ }
18
+ #search-button {
19
+ padding: 10px 20px;
20
+ background-color: #4CAF50;
21
+ color: white;
22
+ border: none;
23
+ border-radius: 0 4px 4px 0;
24
+ cursor: pointer;
25
+ font-size: 16px;
26
+ }
27
+ #search-button:hover {
28
+ background-color: #45a049;
29
+ }
30
+ #results-container {
31
+ margin-top: 20px;
32
+ }
33
+ .paper-result {
34
+ border: 1px solid #ddd;
35
+ margin-bottom: 20px;
36
+ padding: 15px;
37
+ border-radius: 5px;
38
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
39
+ }
40
+ .paper-title {
41
+ font-weight: bold;
42
+ font-size: 18px;
43
+ margin-bottom: 10px;
44
+ color: #333;
45
+ }
46
+ .paper-authors {
47
+ color: #666;
48
+ margin-bottom: 5px;
49
+ font-style: italic;
50
+ }
51
+ .paper-date {
52
+ color: #888;
53
+ margin-bottom: 10px;
54
+ font-size: 14px;
55
+ }
56
+ .paper-abstract {
57
+ line-height: 1.6;
58
+ white-space: pre-line;
59
+ color: #444;
60
+ }
61
+ .paper-id {
62
+ color: #999;
63
+ font-size: 12px;
64
+ text-align: right;
65
+ margin-top: 10px;
66
+ }
67
+ .loading {
68
+ text-align: center;
69
+ padding: 20px;
70
+ font-style: italic;
71
+ color: #666;
72
+ }
73
+ .error-message {
74
+ color: #d9534f;
75
+ padding: 10px;
76
+ border: 1px solid #d9534f;
77
+ border-radius: 4px;
78
+ background-color: #f9f2f2;
79
+ }
80
+
81
+ /* Styles pour la popup */
82
+ .popup {
83
+ display: none; /* Cachée par défaut */
84
+ position: fixed;
85
+ left: 0;
86
+ top: 0;
87
+ width: 100%;
88
+ height: 100%;
89
+ background: rgba(0, 0, 0, 0.5); /* Fond assombri */
90
+ justify-content: center;
91
+ align-items: center;
92
+ }
93
+
94
+ /* Contenu de la popup */
95
+ .popup-content {
96
+ background: white;
97
+ padding: 20px;
98
+ border-radius: 10px;
99
+ text-align: center;
100
+ width: 65%;
101
+ height: 70%;
102
+ box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
103
+ display: flex;
104
+ flex-direction: column;
105
+ }
106
+
107
+ /* Champ texte défilant */
108
+ .scrollable-text {
109
+ flex-grow: 1;
110
+ margin-top: 10px;
111
+ padding: 10px;
112
+ border: 1px solid #ccc;
113
+ border-radius: 5px;
114
+ height: 100%;
115
+ overflow: auto;
116
+ background: #f9f9f9;
117
+ text-align: left;
118
+ }
119
+
120
+ /* Bouton de fermeture */
121
+ .close {
122
+ align-self: flex-end;
123
+ font-size: 24px;
124
+ cursor: pointer;
125
+ font-weight: bold;
126
+ }
127
+
128
+ .no-scroll {
129
+ overflow: hidden;
130
+ }