Skip to content
This repository was archived by the owner on Jan 28, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d3eeb72
cleaned Repo
husseingalal2002 Jul 26, 2025
83b4b3a
moved top menu to center of the page
TrixiRa Jul 26, 2025
5efec15
removed unused filter components from advanced search
TrixiRa Jul 26, 2025
a9af2b2
design update
husseingalal2002 Jul 26, 2025
aa3a843
Search api updated, autocomplete updated and work more clear results,…
udenizz Jul 26, 2025
0793ca4
update branch
husseingalal2002 Jul 26, 2025
6898d69
Dark mode update search page and graph page and toggle bar for testing
udenizz Jul 26, 2025
215f51f
Merge remote-tracking branch 'origin/New_Collaboration_Graph' into un…
TrixiRa Jul 27, 2025
94bcb9a
incorporating all recent changes for bringing together search ui
TrixiRa Jul 27, 2025
461a8b3
Merge TopicTrends&AutoComplete&SearchApiUpdate into unified_search_ui…
TrixiRa Jul 27, 2025
1a13568
all pages in dark mode now, new animated components, unfinished integ…
TrixiRa Jul 27, 2025
9505a88
Enhance dark mode styles across components, including input placehold…
TrixiRa Jul 27, 2025
aa4e68a
search result cards adapted for dark mode
TrixiRa Jul 27, 2025
ca72b37
Info Box for all pages containing constructed api call for better use…
TrixiRa Jul 27, 2025
fa0b8c8
added animation for search page
TrixiRa Jul 27, 2025
6147921
dark mode for advanced filters drawer
TrixiRa Jul 27, 2025
5ce6c38
unified search ui for search page
TrixiRa Jul 27, 2025
4e60ebe
multi-select dropdown for advanced filters with publication types
TrixiRa Jul 27, 2025
df40f1e
fix multi-select dropdown component w.r.t. api call
TrixiRa Jul 27, 2025
ff1c5c1
unified search ui for world map and position detail page. containts o…
TrixiRa Jul 27, 2025
405b43b
renamed pages for easier overview in our repo
TrixiRa Jul 27, 2025
13700cb
Merge pull request #152 from DigitalProductInnovationAndDevelopment/T…
udenizz Jul 27, 2025
2276eb0
Merge pull request #153 from DigitalProductInnovationAndDevelopment/u…
TrixiRa Jul 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions backend/routes/autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,29 @@ router.get('/', async (req, res) => {
}
}

if (type === 'institution' && query.length >= 2) {
if (type === 'institution' && query.length >= 1) {
try {
const url = `${OPENALEX_API_BASE}/institutions`;
const params = { search: query, per_page: 10 };
// Use OpenAlex autocomplete endpoint for better partial matching
const url = `${OPENALEX_API_BASE}/autocomplete`;
const params = {
q: query,
mailto: 'team@ourresearch.org'
};
const response = await axios.get(url, { params, headers: OPENALEX_HEADERS });
const data = response.data;
const results = (data.results || []).map(inst => ({
id: inst.id,
display_name: inst.display_name
}));
return res.json({ results });

// Filter results to only include institutions
const institutionResults = (data.results || [])
.filter(item => item.entity_type === 'institution')
.map(inst => ({
id: inst.id,
display_name: inst.display_name
}));

return res.json({ results: institutionResults });
} catch (err) {
return res.status(500).json({ results: [], error: 'Failed to fetch from OpenAlex' });
console.error('OpenAlex autocomplete error:', err.message);
return res.status(500).json({ results: [], error: 'Failed to fetch from OpenAlex autocomplete' });
}
}

Expand Down
8 changes: 6 additions & 2 deletions backend/routes/publications.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,7 @@ router.get('/keyword_trends', async (req, res) => {
start_date,
end_date,
per_page = 200,
years,
limit
institution_id
} = req.query;

let filterParts = [];
Expand All @@ -159,6 +158,11 @@ router.get('/keyword_trends', async (req, res) => {
if (keyword) {
filterParts.push(`title_and_abstract.search:${keyword}`);
}
// Add institution filter if provided
if (institution_id) {
filterParts.push(`authorships.institutions.id:I${institution_id}`);
}

// Only add date filters if start_date or end_date is provided
if (start_date) {
filterParts.push(`from_publication_date:${start_date}`);
Expand Down
6 changes: 6 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@testing-library/user-event": "^13.5.0",
"cors": "^2.8.5",
"d3-geo": "^3.1.1",
"ogl": "^1.0.11",
"react": "^18.2.0",
"react-datepicker": "^8.4.0",
"react-dom": "^18.2.0",
Expand Down
20 changes: 10 additions & 10 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React, { useState } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { LandingPageLight } from './pages/light_mode/landing_light';
import SearchPageLight from './pages/light_mode/search_light';
import { AboutPage } from './pages/light_mode/about_light';
import { PositionDetailLight } from './pages/light_mode/position_detail_light';
import GraphViewLight from './pages/light_mode/graph_view_light';
import WorldMapPapersPage from './pages/light_mode/WorldMapPapersPage';
import { LandingPageLight } from './pages/home';
import SearchPageLight from './pages/search';
import { AboutPage } from './pages/about';
import { PositionDetailLight } from './pages/trend_graphs';
import GraphViewLight from './pages/collaboration_graph';
import WorldMapPapersPage from './pages/world_map';

function App() {
const [isDarkMode, setIsDarkMode] = useState(false);
const [isDarkMode, setIsDarkMode] = useState(true);

const toggleDarkMode = () => {
setIsDarkMode(!isDarkMode);
Expand All @@ -21,11 +21,11 @@ function App() {
<main>
<Routes>
<Route path="/" element={<LandingPageLight darkMode={isDarkMode} toggleDarkMode={toggleDarkMode} />} />
<Route path="/search" element={<SearchPageLight darkMode={isDarkMode} toggleDarkMode={toggleDarkMode} />} />
<Route path="/search" element={<SearchPageLight darkMode={isDarkMode} />} />
<Route path="/graph-view" element={<GraphViewLight darkMode={isDarkMode} toggleDarkMode={toggleDarkMode} />} />
<Route path="/about" element={<AboutPage darkMode={isDarkMode} toggleDarkMode={toggleDarkMode} />} />
<Route path="/trends" element={<PositionDetailLight darkMode={isDarkMode} toggleDarkMode={toggleDarkMode} />} />
<Route path="/world-map" element={<WorldMapPapersPage darkMode={isDarkMode} toggleDarkMode={toggleDarkMode} />} />
<Route path="/trends" element={<PositionDetailLight darkMode={true} />} />
<Route path="/world-map" element={<WorldMapPapersPage />} />
</Routes>
</main>
</div>
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/assets/icons/world-map.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions frontend/src/assets/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ body.dark {
color: var(--color-text-dark);
}

/* Dark mode input placeholder styles */
.dark input::placeholder {
color: #888;
opacity: 1;
}

.dark input:-ms-input-placeholder {
color: #888;
}

.dark input::-ms-input-placeholder {
color: #888;
}

/* App layout */
.app {
width: 100%;
Expand Down
60 changes: 43 additions & 17 deletions frontend/src/assets/styles/institutionDropdown.module.css
Original file line number Diff line number Diff line change
@@ -1,61 +1,87 @@
.dropdownContainer {
position: relative;
width: 100%;
max-width: 400px;
margin-bottom: 1rem;
margin-bottom: 0;
}

.label {
font-weight: 600;
margin-bottom: 0.25rem;
display: block;
}

.inputWrapper {
position: relative;
display: flex;
align-items: center;
}

.input {
width: 100%;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px 0 0 4px;
padding: 0.75rem;
border: 1px solid #e5e7eb;
border-radius: 6px;
outline: none;
font-size: 1rem;
background: #222;
color: #fff;
}

.toggleBtn {
border: 1px solid #ccc;
border-left: none;
background: #f7f7f7;
padding: 0.5rem 0.75rem;
border-radius: 0 4px 4px 0;
position: absolute;
right: 32px;
top: 50%;
transform: translateY(-50%);
border: none;
background: transparent;
padding: 0.25rem;
cursor: pointer;
font-size: 1rem;
font-size: 0.75rem;
color: #6b7280;
z-index: 5;
height: 24px;
width: 24px;
display: flex;
align-items: center;
justify-content: center;
}

.dropdownList {
position: absolute;
top: 100%;
left: 0;
right: 0;
max-height: 220px;
overflow-y: auto;
background: #fff;
background: #222;
color: #fff;
border: 1px solid #ccc;
border-top: none;
z-index: 10;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.dropdownItem {
padding: 0.5rem 1rem;
padding: 0.75rem 1rem;
cursor: pointer;
transition: background 0.15s;
background: #222;
color: #fff;
}

.dropdownItem:hover {
background: #f0f0f0;
background: #333;
color: #fff;
}
.loading, .noResults {

.loading,
.noResults {
padding: 0.75rem 1rem;
color: #888;
color: #6b7280;
text-align: center;
font-size: 0.875rem;
}

.selectedValue {
margin-top: 0.5rem;
font-size: 0.95rem;
Expand Down
Loading
Loading