Skip to content

Commit cfa7c53

Browse files
authored
Merge pull request #29 from ericahan22/copilot/fix-28
Fix popup positioning issue in day-view calendar
2 parents a72027c + 1a77044 commit cfa7c53

File tree

3 files changed

+56
-9
lines changed

3 files changed

+56
-9
lines changed

frontend/eslint.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,11 @@ export default tseslint.config([
1919
ecmaVersion: 2020,
2020
globals: globals.browser,
2121
},
22+
rules: {
23+
'@typescript-eslint/no-unused-vars': [
24+
'error',
25+
{ argsIgnorePattern: '^_' }
26+
]
27+
},
2228
},
2329
])

frontend/src/components/EventsCalendar.tsx

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ interface EventsCalendarProps {
4848
}
4949

5050
// Custom toolbar for < and > month buttons
51+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5152
const CustomToolbar: React.FC<ToolbarProps<any, object>> = ({
5253
label,
5354
onNavigate,
@@ -165,19 +166,59 @@ const EventsCalendar: React.FC<EventsCalendarProps> = ({ events }) => {
165166

166167
const popupWidth = 320;
167168
const popupHeight = 200;
168-
let x = rect.left - containerRect.left + rect.width + 10;
169-
let y = rect.top - containerRect.top;
169+
170+
// Calculate all possible positions relative to event
171+
const positions = {
172+
right: { x: rect.right + 10, y: rect.top },
173+
left: { x: rect.left - popupWidth - 10, y: rect.top },
174+
bottom: { x: rect.left, y: rect.bottom + 10 },
175+
top: { x: rect.left, y: rect.top - popupHeight - 10 }
176+
};
177+
178+
// Score each position based on how well it fits
179+
let bestPosition = null;
180+
let bestScore = -1;
181+
182+
for (const [name, pos] of Object.entries(positions)) {
183+
let score = 0;
184+
185+
// Check if popup fits in viewport
186+
if (pos.x >= 0 && pos.x + popupWidth <= window.innerWidth) score += 10;
187+
if (pos.y >= 0 && pos.y + popupHeight <= window.innerHeight) score += 10;
170188

171-
// Handle overflow
172-
if (x + popupWidth > containerRect.width) {
173-
x = rect.left - containerRect.left - popupWidth - 10;
189+
// Check if popup fits in container
190+
const containerX = pos.x - containerRect.left;
191+
const containerY = pos.y - containerRect.top;
192+
if (containerX >= 0 && containerX + popupWidth <= containerRect.width) score += 5;
193+
if (containerY >= 0 && containerY + popupHeight <= containerRect.height) score += 5;
194+
195+
// Prefer right and bottom positions for better UX
196+
if (name === 'right') score += 2;
197+
if (name === 'bottom') score += 1;
198+
199+
if (score > bestScore) {
200+
bestScore = score;
201+
bestPosition = pos;
202+
}
174203
}
175-
if (y + popupHeight > containerRect.height) {
176-
y = containerRect.height - popupHeight - 10;
204+
205+
// Convert to container-relative coordinates or fallback to center
206+
let finalPosition;
207+
if (bestPosition && bestScore > 0) {
208+
finalPosition = {
209+
x: bestPosition.x - containerRect.left,
210+
y: bestPosition.y - containerRect.top
211+
};
212+
} else {
213+
// Fallback to center if no good position found
214+
finalPosition = {
215+
x: Math.max(0, (containerRect.width - popupWidth) / 2),
216+
y: Math.max(0, (containerRect.height - popupHeight) / 2)
217+
};
177218
}
178219

179220
setSelectedEvent(event);
180-
setPopupPosition({ x, y });
221+
setPopupPosition(finalPosition);
181222
};
182223

183224
const closePopup = () => {

frontend/tsconfig.tsbuildinfo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"root":["./src/App.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/components/ClubsGrid.tsx","./src/components/EventsCalendar.tsx","./src/components/EventsGrid.tsx","./src/components/SearchInput.tsx","./src/components/ui/button.tsx","./src/components/ui/card.tsx","./src/components/ui/input.tsx","./src/components/ui/select.tsx","./src/hooks/index.ts","./src/hooks/useCategoryParam.ts","./src/hooks/useClubs.ts","./src/hooks/useEvents.ts","./src/hooks/useTheme.ts","./src/lib/dateUtils.ts","./src/lib/theme.tsx","./src/lib/utils.ts","./src/pages/ClubsPage.tsx","./src/pages/EventsPage.tsx"],"version":"5.8.3"}
1+
{"root":["./src/App.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/components/ClubsGrid.tsx","./src/components/EventsCalendar.tsx","./src/components/EventsGrid.tsx","./src/components/SearchInput.tsx","./src/components/ui/button.tsx","./src/components/ui/card.tsx","./src/components/ui/input.tsx","./src/components/ui/select.tsx","./src/hooks/index.ts","./src/hooks/useCategoryParam.ts","./src/hooks/useClubs.ts","./src/hooks/useEvents.ts","./src/hooks/useTheme.ts","./src/lib/dateUtils.ts","./src/lib/theme.tsx","./src/lib/utils.ts","./src/pages/ClubsPage.tsx","./src/pages/EventsPage.tsx"],"version":"5.8.3"}

0 commit comments

Comments
 (0)