Skip to content

Commit 30bdb9a

Browse files
committed
feat: replace dropdown with checkbox
1 parent b1e98ca commit 30bdb9a

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

src/pages/content/index.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import CourseCatalogMain from '@views/components/CourseCatalogMain';
22
import InjectedButton from '@views/components/injected/AddAllButton';
3+
import DaysCheckbox from 'src/views/components/injected/DaysCheckbox';
34
import getSiteSupport, { SiteSupport } from '@views/lib/getSiteSupport';
45
import React from 'react';
56
import { createRoot } from 'react-dom/client';
67

78
const support = getSiteSupport(window.location.href);
89

910
const renderComponent = (Component: React.ComponentType) => {
11+
// Simple console log for component rendering
12+
console.log('Rendering component:', Component.name || 'Anonymous');
13+
1014
const container = document.createElement('div');
1115
container.id = 'extension-root';
1216
document.body.appendChild(container);
@@ -25,3 +29,7 @@ if (support === SiteSupport.COURSE_CATALOG_DETAILS || support === SiteSupport.CO
2529
if (support === SiteSupport.MY_UT) {
2630
renderComponent(InjectedButton);
2731
}
32+
33+
if (support === SiteSupport.COURSE_CATALOG_SEARCH) {
34+
renderComponent(DaysCheckbox);
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import ExtensionRoot from '@views/components/common/ExtensionRoot/ExtensionRoot';
2+
import React, { useEffect, useState } from 'react';
3+
import ReactDOM from 'react-dom';
4+
5+
/**
6+
* Component that transforms the days dropdown into a series of checkboxes
7+
* on the course catalog search page
8+
*
9+
* @returns The rendered checkbox component or null if the container is not found.
10+
*/
11+
export default function DaysCheckbox(): JSX.Element | null {
12+
const [container, setContainer] = useState<HTMLDivElement | null>(null);
13+
const [daysValue, setDaysValue] = useState<string>('000000');
14+
15+
const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
16+
17+
useEffect(() => {
18+
const daysDropdown = document.getElementById('mtg_days_st') as HTMLSelectElement | null;
19+
if (!daysDropdown) {
20+
console.error('Days dropdown not found');
21+
return;
22+
}
23+
24+
const formElement = daysDropdown.closest('.form_element')!;
25+
const checkboxContainer = document.createElement('div');
26+
27+
// Create a hidden input to store the value
28+
const hiddenInput = document.createElement('input');
29+
hiddenInput.type = 'hidden';
30+
hiddenInput.name = 'mtg_days_st';
31+
hiddenInput.id = 'mtg_days_st_hidden';
32+
hiddenInput.value = daysDropdown.value;
33+
34+
// Remove old dropdown
35+
formElement.innerHTML = '';
36+
37+
// Add the label back
38+
const newLabel = document.createElement('label');
39+
newLabel.className = 'primary_label';
40+
newLabel.htmlFor = 'mtg_days_st_hidden';
41+
newLabel.textContent = 'AND days';
42+
43+
formElement.appendChild(newLabel);
44+
formElement.appendChild(hiddenInput);
45+
formElement.appendChild(checkboxContainer);
46+
setContainer(checkboxContainer);
47+
48+
return () => {
49+
checkboxContainer.remove();
50+
};
51+
}, []);
52+
53+
useEffect(() => {
54+
// Update hidden input when daysValue changes
55+
const hiddenInput = document.getElementById('mtg_days_st_hidden') as HTMLInputElement | null;
56+
if (hiddenInput) {
57+
hiddenInput.value = daysValue;
58+
}
59+
}, [daysValue]);
60+
61+
const handleDayChange = (position: number, checked: boolean) => {
62+
setDaysValue(prev => {
63+
const currentValue = prev.split('');
64+
currentValue[position] = checked ? '1' : '0';
65+
return currentValue.join('');
66+
});
67+
};
68+
69+
if (!container) {
70+
return null;
71+
}
72+
73+
return ReactDOM.createPortal(
74+
<ExtensionRoot>
75+
<div className='flex flex-col gap-0.5 mt-1'>
76+
{days.map((day, index) => (
77+
<div key={day} className='flex items-center'>
78+
<input
79+
type='checkbox'
80+
id={`day_${day}`}
81+
checked={daysValue !== '000000' && daysValue.charAt(index) === '1'}
82+
onChange={e => {
83+
handleDayChange(index, e.target.checked);
84+
}}
85+
className='form-checkbox'
86+
/>
87+
<label htmlFor={`day_${day}`} className='ml-1'>
88+
{day}
89+
</label>
90+
</div>
91+
))}
92+
</div>
93+
</ExtensionRoot>,
94+
container
95+
);
96+
}

src/views/lib/getSiteSupport.ts

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const SiteSupport = {
1313
MY_CALENDAR: 'MY_CALENDAR',
1414
REPORT_ISSUE: 'REPORT_ISSUE',
1515
MY_UT: 'MY_UT',
16+
COURSE_CATALOG_SEARCH: 'COURSE_CATALOG_SEARCH',
1617
CLASSLIST: 'CLASSLIST',
1718
} as const;
1819

@@ -45,6 +46,7 @@ export default function getSiteSupport(url: string): SiteSupportType | null {
4546
if (document.querySelector('#details')) {
4647
return SiteSupport.COURSE_CATALOG_DETAILS;
4748
}
49+
return SiteSupport.COURSE_CATALOG_SEARCH;
4850
}
4951
if (url.includes('utdirect.utexas.edu') && (url.includes('waitlist') || url.includes('classlist'))) {
5052
return SiteSupport.WAITLIST;

0 commit comments

Comments
 (0)