Skip to content
This repository was archived by the owner on Jan 28, 2026. It is now read-only.

Commit 7b08e3c

Browse files
authored
Merge pull request #156 from DigitalProductInnovationAndDevelopment/remove_add_authors_institutions
Remove add authors institutions
2 parents 2276eb0 + 7e84044 commit 7b08e3c

16 files changed

Lines changed: 1239 additions & 207 deletions

File tree

backend/routes/publications.js

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ router.get('/', async (req, res) => {
2222
...(search && { search })
2323
};
2424

25-
const response = await axios.get(url, {
25+
const response = await axios.get(url, {
2626
params,
2727
headers: OPENALEX_HEADERS
2828
});
@@ -298,6 +298,81 @@ router.get('/keyword_trends', async (req, res) => {
298298
}
299299
});
300300

301+
302+
303+
// Route to get conference information for a list of DOIs
304+
router.get('/conference-info', async (req, res) => {
305+
try {
306+
console.log('Conference-info route called');
307+
const { dois } = req.query;
308+
console.log('DOIs received:', dois);
309+
310+
if (!dois) {
311+
return res.status(400).json({ error: 'DOIs parameter is required' });
312+
}
313+
314+
// Split the DOIs string and extract just the DOI part from URLs
315+
const doiList = Array.isArray(dois) ? dois : dois.split(',');
316+
const extractedDois = doiList.map(doiUrl => {
317+
// Extract just the DOI part from the full URL
318+
const doiMatch = doiUrl.match(/https:\/\/doi\.org\/(.+)/);
319+
return doiMatch ? doiMatch[1] : doiUrl;
320+
});
321+
322+
console.log('Extracted DOIs:', extractedDois);
323+
const results = [];
324+
325+
// Process each DOI with individual API calls
326+
for (const doi of extractedDois) {
327+
try {
328+
console.log(`Processing DOI: ${doi}`);
329+
const url = `https://api.crossref.org/works/${doi}`;
330+
console.log(`CrossRef URL: ${url}`);
331+
332+
const response = await axios.get(url);
333+
console.log(`Response status: ${response.status}`);
334+
335+
if (response.status !== 200) {
336+
throw new Error(`HTTP error! status: ${response.status}`);
337+
}
338+
339+
const data = response.data;
340+
const msg = data.message;
341+
console.log(`Conference name: ${msg.event?.name}`);
342+
343+
const info = {
344+
doi: doi,
345+
title: msg.title?.[0] || null,
346+
container: msg['container-title']?.[0] || null,
347+
type: msg.type || null,
348+
publisher: msg.publisher || null,
349+
year: msg.issued?.['date-parts']?.[0]?.[0] || null,
350+
event: {
351+
name: msg.event?.name || null
352+
}
353+
};
354+
355+
results.push(info);
356+
357+
// Small delay to avoid overwhelming the API
358+
await new Promise(resolve => setTimeout(resolve, 100));
359+
} catch (error) {
360+
console.error(`Error processing DOI ${doi}:`, error);
361+
results.push({
362+
doi: doi,
363+
error: 'Failed to fetch conference information'
364+
});
365+
}
366+
}
367+
368+
console.log('Results:', results);
369+
res.json({ results });
370+
} catch (error) {
371+
console.error('Error in conference-info route:', error);
372+
res.status(500).json({ error: 'Failed to fetch conference information' });
373+
}
374+
});
375+
301376
//get a single publication
302377
router.get('/:id', async (req, res) => {
303378
try {

frontend/src/assets/styles/global.css

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,12 @@ body.dark {
3939

4040
/* App layout */
4141
.app {
42-
width: 100%;
42+
width: 100vw;
4343
min-height: 100vh;
44+
margin: 0;
45+
padding: 0;
46+
overflow-x: hidden;
47+
overflow-y: auto;
4448
}
4549

4650
.main-content {
@@ -51,9 +55,9 @@ body.dark {
5155

5256
/* Utility classes */
5357
.container {
54-
max-width: var(--breakpoint-desktop);
55-
margin: 0 auto;
56-
padding: 0 var(--spacing-md);
58+
width: 100vw;
59+
margin: 0;
60+
padding: 0;
5761
}
5862

5963
.text-center {
@@ -82,35 +86,37 @@ body.dark {
8286

8387
html,
8488
body {
85-
overflow-y: scroll !important;
86-
/* Always show vertical scrollbar */
87-
height: 100%;
89+
overflow-x: hidden !important;
90+
overflow-y: auto !important;
91+
/* Allow vertical scrolling, prevent horizontal overflow */
92+
height: 100vh;
93+
width: 100vw;
8894
margin: 0;
8995
padding: 0;
9096
}
9197

9298
/* For Webkit browsers (Chrome, Safari, Edge) */
9399
html::-webkit-scrollbar,
94100
body::-webkit-scrollbar {
95-
width: 12px;
101+
width: 0px;
102+
display: none;
96103
}
97104

98105
html::-webkit-scrollbar-thumb,
99106
body::-webkit-scrollbar-thumb {
100-
background: #ccc;
101-
border-radius: 6px;
107+
display: none;
102108
}
103109

104110
html::-webkit-scrollbar-track,
105111
body::-webkit-scrollbar-track {
106-
background: #f1f1f1;
112+
display: none;
107113
}
108114

109115
/* For Firefox */
110116
html,
111117
body {
112-
scrollbar-width: auto;
113-
scrollbar-color: #ccc #f1f1f1;
118+
scrollbar-width: none;
119+
scrollbar-color: transparent transparent;
114120
}
115121

116122
/* === DESIGN SYSTEM TOKENS (HSL) === */
@@ -323,11 +329,9 @@ body {
323329

324330
/* Container */
325331
.container {
326-
max-width: 1200px;
327-
margin-left: auto;
328-
margin-right: auto;
329-
padding-left: 1rem;
330-
padding-right: 1rem;
332+
width: 100%;
333+
margin: 0;
334+
padding: 0;
331335
}
332336

333337
/* Responsive text center */
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
import { useRef, useEffect } from "react";
2+
import "./lightning.css";
3+
4+
const Lightning = ({
5+
hue = 230,
6+
xOffset = 0,
7+
speed = 1,
8+
intensity = 1,
9+
size = 1,
10+
}) => {
11+
const canvasRef = useRef(null);
12+
13+
useEffect(() => {
14+
const canvas = canvasRef.current;
15+
if (!canvas) return;
16+
17+
const resizeCanvas = () => {
18+
canvas.width = canvas.clientWidth;
19+
canvas.height = canvas.clientHeight;
20+
};
21+
resizeCanvas();
22+
window.addEventListener("resize", resizeCanvas);
23+
24+
const gl = canvas.getContext("webgl");
25+
if (!gl) {
26+
console.error("WebGL not supported");
27+
return;
28+
}
29+
30+
const vertexShaderSource = `
31+
attribute vec2 aPosition;
32+
void main() {
33+
gl_Position = vec4(aPosition, 0.0, 1.0);
34+
}
35+
`;
36+
37+
const fragmentShaderSource = `
38+
precision mediump float;
39+
uniform vec2 iResolution;
40+
uniform float iTime;
41+
uniform float uHue;
42+
uniform float uXOffset;
43+
uniform float uSpeed;
44+
uniform float uIntensity;
45+
uniform float uSize;
46+
47+
#define OCTAVE_COUNT 10
48+
49+
vec3 hsv2rgb(vec3 c) {
50+
vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);
51+
return c.z * mix(vec3(1.0), rgb, c.y);
52+
}
53+
54+
float hash11(float p) {
55+
p = fract(p * .1031);
56+
p *= p + 33.33;
57+
p *= p + p;
58+
return fract(p);
59+
}
60+
61+
float hash12(vec2 p) {
62+
vec3 p3 = fract(vec3(p.xyx) * .1031);
63+
p3 += dot(p3, p3.yzx + 33.33);
64+
return fract((p3.x + p3.y) * p3.z);
65+
}
66+
67+
mat2 rotate2d(float theta) {
68+
float c = cos(theta);
69+
float s = sin(theta);
70+
return mat2(c, -s, s, c);
71+
}
72+
73+
float noise(vec2 p) {
74+
vec2 ip = floor(p);
75+
vec2 fp = fract(p);
76+
float a = hash12(ip);
77+
float b = hash12(ip + vec2(1.0, 0.0));
78+
float c = hash12(ip + vec2(0.0, 1.0));
79+
float d = hash12(ip + vec2(1.0, 1.0));
80+
81+
vec2 t = smoothstep(0.0, 1.0, fp);
82+
return mix(mix(a, b, t.x), mix(c, d, t.x), t.y);
83+
}
84+
85+
float fbm(vec2 p) {
86+
float value = 0.0;
87+
float amplitude = 0.5;
88+
for (int i = 0; i < OCTAVE_COUNT; ++i) {
89+
value += amplitude * noise(p);
90+
p *= rotate2d(0.45);
91+
p *= 2.0;
92+
amplitude *= 0.5;
93+
}
94+
return value;
95+
}
96+
97+
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
98+
vec2 uv = fragCoord / iResolution.xy;
99+
uv = 2.0 * uv - 1.0;
100+
uv.x *= iResolution.x / iResolution.y;
101+
uv.x += uXOffset;
102+
103+
uv += 2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0;
104+
105+
float dist = abs(uv.x);
106+
vec3 baseColor = hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8));
107+
vec3 col = baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity;
108+
col = pow(col, vec3(1.0));
109+
fragColor = vec4(col, 1.0);
110+
}
111+
112+
void main() {
113+
mainImage(gl_FragColor, gl_FragCoord.xy);
114+
}
115+
`;
116+
117+
const compileShader = (
118+
source,
119+
type
120+
) => {
121+
const shader = gl.createShader(type);
122+
if (!shader) return null;
123+
gl.shaderSource(shader, source);
124+
gl.compileShader(shader);
125+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
126+
console.error("Shader compile error:", gl.getShaderInfoLog(shader));
127+
gl.deleteShader(shader);
128+
return null;
129+
}
130+
return shader;
131+
};
132+
133+
const vertexShader = compileShader(vertexShaderSource, gl.VERTEX_SHADER);
134+
const fragmentShader = compileShader(
135+
fragmentShaderSource,
136+
gl.FRAGMENT_SHADER
137+
);
138+
if (!vertexShader || !fragmentShader) return;
139+
140+
const program = gl.createProgram();
141+
if (!program) return;
142+
gl.attachShader(program, vertexShader);
143+
gl.attachShader(program, fragmentShader);
144+
gl.linkProgram(program);
145+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
146+
console.error("Program linking error:", gl.getProgramInfoLog(program));
147+
return;
148+
}
149+
gl.useProgram(program);
150+
151+
const vertices = new Float32Array([
152+
-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1,
153+
]);
154+
const vertexBuffer = gl.createBuffer();
155+
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
156+
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
157+
158+
const aPosition = gl.getAttribLocation(program, "aPosition");
159+
gl.enableVertexAttribArray(aPosition);
160+
gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);
161+
162+
const iResolutionLocation = gl.getUniformLocation(program, "iResolution");
163+
const iTimeLocation = gl.getUniformLocation(program, "iTime");
164+
const uHueLocation = gl.getUniformLocation(program, "uHue");
165+
const uXOffsetLocation = gl.getUniformLocation(program, "uXOffset");
166+
const uSpeedLocation = gl.getUniformLocation(program, "uSpeed");
167+
const uIntensityLocation = gl.getUniformLocation(program, "uIntensity");
168+
const uSizeLocation = gl.getUniformLocation(program, "uSize");
169+
170+
const startTime = performance.now();
171+
const render = () => {
172+
resizeCanvas();
173+
gl.viewport(0, 0, canvas.width, canvas.height);
174+
gl.uniform2f(iResolutionLocation, canvas.width, canvas.height);
175+
const currentTime = performance.now();
176+
gl.uniform1f(iTimeLocation, (currentTime - startTime) / 1000.0);
177+
gl.uniform1f(uHueLocation, hue);
178+
gl.uniform1f(uXOffsetLocation, xOffset);
179+
gl.uniform1f(uSpeedLocation, speed);
180+
gl.uniform1f(uIntensityLocation, intensity);
181+
gl.uniform1f(uSizeLocation, size);
182+
gl.drawArrays(gl.TRIANGLES, 0, 6);
183+
requestAnimationFrame(render);
184+
};
185+
requestAnimationFrame(render);
186+
187+
return () => {
188+
window.removeEventListener("resize", resizeCanvas);
189+
};
190+
}, [hue, xOffset, speed, intensity, size]);
191+
192+
return <canvas ref={canvasRef} className="lightning-container" />;
193+
};
194+
195+
export default Lightning;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.lightning-container {
2+
width: 100%;
3+
height: 100%;
4+
position: relative;
5+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.text-type {
2+
display: inline-block;
3+
white-space: pre-wrap;
4+
}
5+
6+
.text-type__cursor {
7+
margin-left: 0.25rem;
8+
display: inline-block;
9+
opacity: 1;
10+
}
11+
12+
.text-type__cursor--hidden {
13+
display: none;
14+
}

0 commit comments

Comments
 (0)