Skip to content

Commit b34a807

Browse files
committed
asd
1 parent f9d97ef commit b34a807

File tree

4 files changed

+59
-1157
lines changed

4 files changed

+59
-1157
lines changed

apps/registry/app/[username]/jobs-graph/page.js

Lines changed: 59 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,10 @@
11
'use client';
22

3-
import dynamic from 'next/dynamic';
43
import axios from 'axios';
54
import { useEffect, useState, useCallback, useRef, useMemo } from 'react';
6-
import Hero from '../../../src/ui/Hero';
7-
import Loading from '../../components/Loading';
8-
import {
9-
forceSimulation,
10-
forceCollide,
11-
forceManyBody,
12-
forceCenter,
13-
forceLink,
14-
} from 'd3-force';
5+
import { forceCollide, forceManyBody } from 'd3-force';
156
import ForceGraph2D from 'react-force-graph-2d';
167

17-
// const ForceGraph2D = dynamic(() => import('react-force-graph-2d'), {
18-
// ssr: false,
19-
// });
20-
21-
const DEFAULT_WIDTH = 800;
22-
const DEFAULT_HEIGHT = 600;
23-
248
// Format skills array into a readable string
259
const formatSkills = (skills) => {
2610
if (!skills) return '';
@@ -98,7 +82,6 @@ export default function Jobs({ params }) {
9882

9983
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
10084
const graphRef = useRef();
101-
const canvasRef = useRef(null);
10285
const [activeNode, setActiveNode] = useState(null);
10386
const [hoveredNode, setHoveredNode] = useState(null);
10487
const [pinnedNode, setPinnedNode] = useState(null);
@@ -115,48 +98,51 @@ export default function Jobs({ params }) {
11598
const [filteredNodes, setFilteredNodes] = useState(new Set());
11699

117100
const [showSalaryGradient, setShowSalaryGradient] = useState(false);
118-
const [salaryRange, setSalaryRange] = useState({ min: Infinity, max: -Infinity });
101+
const [salaryRange, setSalaryRange] = useState({
102+
min: Infinity,
103+
max: -Infinity,
104+
});
119105

120106
// Parse salary from various string formats
121107
const parseSalary = useCallback((salary) => {
122108
if (!salary) return null;
123109
if (typeof salary === 'number') return salary;
124-
110+
125111
const str = salary.toString().toLowerCase();
126112
// Extract all numbers from the string
127113
const numbers = str.match(/\d+(?:\.\d+)?/g);
128114
if (!numbers) return null;
129-
115+
130116
// Convert numbers considering k/K multiplier
131-
const values = numbers.map(num => {
117+
const values = numbers.map((num) => {
132118
const multiplier = str.includes('k') ? 1000 : 1;
133119
return parseFloat(num) * multiplier;
134120
});
135-
121+
136122
// If range, return average
137123
if (values.length > 1) {
138124
values.sort((a, b) => a - b);
139125
return (values[0] + values[values.length - 1]) / 2;
140126
}
141-
127+
142128
return values[0];
143129
}, []);
144130

145131
// Calculate salary range when jobs data changes
146132
useEffect(() => {
147133
if (!jobInfo) return;
148-
134+
149135
let min = Infinity;
150136
let max = -Infinity;
151-
152-
Object.values(jobInfo).forEach(job => {
137+
138+
Object.values(jobInfo).forEach((job) => {
153139
const salary = parseSalary(job.salary);
154140
if (salary) {
155141
min = Math.min(min, salary);
156142
max = Math.max(max, salary);
157143
}
158144
});
159-
145+
160146
if (min !== Infinity && max !== -Infinity) {
161147
setSalaryRange({ min, max });
162148
}
@@ -220,19 +206,26 @@ export default function Jobs({ params }) {
220206
// Memoize node colors for salary view
221207
const nodeSalaryColors = useMemo(() => {
222208
if (!showSalaryGradient || !jobInfo) return new Map();
223-
209+
224210
const colors = new Map();
225211
Object.entries(jobInfo).forEach(([id, job]) => {
226212
const salary = parseSalary(job.salary);
227213
if (salary) {
228-
const percentage = (salary - salaryRange.min) / (salaryRange.max - salaryRange.min);
214+
const percentage =
215+
(salary - salaryRange.min) / (salaryRange.max - salaryRange.min);
229216
const lightBlue = [219, 234, 254]; // bg-blue-100
230-
const darkBlue = [30, 64, 175]; // bg-blue-800
231-
232-
const r = Math.round(lightBlue[0] + (darkBlue[0] - lightBlue[0]) * percentage);
233-
const g = Math.round(lightBlue[1] + (darkBlue[1] - lightBlue[1]) * percentage);
234-
const b = Math.round(lightBlue[2] + (darkBlue[2] - lightBlue[2]) * percentage);
235-
217+
const darkBlue = [30, 64, 175]; // bg-blue-800
218+
219+
const r = Math.round(
220+
lightBlue[0] + (darkBlue[0] - lightBlue[0]) * percentage,
221+
);
222+
const g = Math.round(
223+
lightBlue[1] + (darkBlue[1] - lightBlue[1]) * percentage,
224+
);
225+
const b = Math.round(
226+
lightBlue[2] + (darkBlue[2] - lightBlue[2]) * percentage,
227+
);
228+
236229
colors.set(id, `rgb(${r}, ${g}, ${b})`);
237230
} else {
238231
colors.set(id, '#e2e8f0'); // Light gray for no salary
@@ -245,11 +238,11 @@ export default function Jobs({ params }) {
245238
(node) => {
246239
if (node.group === -1) return '#fff';
247240
if (filterText && !filteredNodes.has(node.id)) return '#f8fafc';
248-
241+
249242
if (showSalaryGradient) {
250243
return nodeSalaryColors.get(node.id) || '#e2e8f0';
251244
}
252-
245+
253246
return readJobs.has(node.id) ? '#f1f5f9' : '#fef9c3';
254247
},
255248
[readJobs, filterText, filteredNodes, showSalaryGradient, nodeSalaryColors],
@@ -259,26 +252,41 @@ export default function Jobs({ params }) {
259252
(node) => {
260253
if (node.group === -1) return '#fff';
261254
if (filterText && !filteredNodes.has(node.id)) return '#f8fafc';
262-
255+
263256
if (showSalaryGradient && jobInfo[node.id]) {
264257
const salary = parseSalary(jobInfo[node.id].salary);
265258
if (salary) {
266-
const percentage = (salary - salaryRange.min) / (salaryRange.max - salaryRange.min);
259+
const percentage =
260+
(salary - salaryRange.min) / (salaryRange.max - salaryRange.min);
267261
const lightBlue = [219, 234, 254]; // bg-blue-100
268-
const darkBlue = [30, 64, 175]; // bg-blue-800
269-
270-
const r = Math.round(lightBlue[0] + (darkBlue[0] - lightBlue[0]) * percentage);
271-
const g = Math.round(lightBlue[1] + (darkBlue[1] - lightBlue[1]) * percentage);
272-
const b = Math.round(lightBlue[2] + (darkBlue[2] - lightBlue[2]) * percentage);
273-
262+
const darkBlue = [30, 64, 175]; // bg-blue-800
263+
264+
const r = Math.round(
265+
lightBlue[0] + (darkBlue[0] - lightBlue[0]) * percentage,
266+
);
267+
const g = Math.round(
268+
lightBlue[1] + (darkBlue[1] - lightBlue[1]) * percentage,
269+
);
270+
const b = Math.round(
271+
lightBlue[2] + (darkBlue[2] - lightBlue[2]) * percentage,
272+
);
273+
274274
return `rgb(${r}, ${g}, ${b})`;
275275
}
276276
return '#e2e8f0'; // Light gray for no salary
277277
}
278-
278+
279279
return readJobs.has(node.id) ? '#f1f5f9' : '#fef9c3';
280280
},
281-
[readJobs, filterText, filteredNodes, showSalaryGradient, jobInfo, parseSalary, salaryRange],
281+
[
282+
readJobs,
283+
filterText,
284+
filteredNodes,
285+
showSalaryGradient,
286+
jobInfo,
287+
parseSalary,
288+
salaryRange,
289+
],
282290
);
283291

284292
// Function to preload and cache image
@@ -453,7 +461,9 @@ export default function Jobs({ params }) {
453461
onChange={(e) => setShowSalaryGradient(e.target.checked)}
454462
/>
455463
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
456-
<span className="ml-2 text-sm font-medium text-gray-900">Salary View</span>
464+
<span className="ml-2 text-sm font-medium text-gray-900">
465+
Salary View
466+
</span>
457467
</label>
458468
</div>
459469
</div>

0 commit comments

Comments
 (0)