-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CheckItem component and update Vote component with new styles #41
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import React from "react"; | ||
|
||
export default function CheckItem({ label, checked }) { | ||
if (checked) { | ||
return ( | ||
<mdui-checkbox disabled checked checked-icon="done"> | ||
{label} | ||
</mdui-checkbox> | ||
); | ||
} | ||
return ( | ||
<mdui-checkbox disabled unchecked-icon="close"> | ||
{label} | ||
</mdui-checkbox> | ||
); | ||
} | ||
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -15,6 +15,7 @@ import moment from "moment-timezone"; | |||||||||||||||||||||||||||||||||||
import { breakpoint, confirm, snackbar } from "mdui"; | ||||||||||||||||||||||||||||||||||||
import { redirect } from "react-router-dom"; | ||||||||||||||||||||||||||||||||||||
import { capitalizeWords } from "./admin/utils"; | ||||||||||||||||||||||||||||||||||||
import CheckItem from "./CheckItem"; | ||||||||||||||||||||||||||||||||||||
export default function Vote() { | ||||||||||||||||||||||||||||||||||||
const refs = useRef([]); | ||||||||||||||||||||||||||||||||||||
const urlParams = new URLSearchParams(window.location.search); | ||||||||||||||||||||||||||||||||||||
|
@@ -235,14 +236,12 @@ export default function Vote() { | |||||||||||||||||||||||||||||||||||
<p /> | ||||||||||||||||||||||||||||||||||||
<div className="flex-row"> | ||||||||||||||||||||||||||||||||||||
<mdui-text-field | ||||||||||||||||||||||||||||||||||||
required | ||||||||||||||||||||||||||||||||||||
label="Vorname(n)" | ||||||||||||||||||||||||||||||||||||
placeholder="Max Erika" | ||||||||||||||||||||||||||||||||||||
value={firstName} | ||||||||||||||||||||||||||||||||||||
onInput={(e) => setFirstName(capitalizeWords(e.target.value))} | ||||||||||||||||||||||||||||||||||||
></mdui-text-field> | ||||||||||||||||||||||||||||||||||||
<mdui-text-field | ||||||||||||||||||||||||||||||||||||
required | ||||||||||||||||||||||||||||||||||||
label="Nachname" | ||||||||||||||||||||||||||||||||||||
placeholder="Mustermann" | ||||||||||||||||||||||||||||||||||||
value={lastName} | ||||||||||||||||||||||||||||||||||||
|
@@ -252,15 +251,13 @@ export default function Vote() { | |||||||||||||||||||||||||||||||||||
<p /> | ||||||||||||||||||||||||||||||||||||
<div className="flex-row"> | ||||||||||||||||||||||||||||||||||||
<mdui-text-field | ||||||||||||||||||||||||||||||||||||
required | ||||||||||||||||||||||||||||||||||||
type="number" | ||||||||||||||||||||||||||||||||||||
label="Klasse" | ||||||||||||||||||||||||||||||||||||
placeholder="11" | ||||||||||||||||||||||||||||||||||||
value={grade} | ||||||||||||||||||||||||||||||||||||
onInput={(e) => setGrade(e.target.value)} | ||||||||||||||||||||||||||||||||||||
></mdui-text-field> | ||||||||||||||||||||||||||||||||||||
<mdui-text-field | ||||||||||||||||||||||||||||||||||||
required | ||||||||||||||||||||||||||||||||||||
type="number" | ||||||||||||||||||||||||||||||||||||
label="Klassenlistennr." | ||||||||||||||||||||||||||||||||||||
prefix="#" | ||||||||||||||||||||||||||||||||||||
|
@@ -273,7 +270,6 @@ export default function Vote() { | |||||||||||||||||||||||||||||||||||
{extraFields?.map((e, i) => ( | ||||||||||||||||||||||||||||||||||||
<div key={i}> | ||||||||||||||||||||||||||||||||||||
<mdui-text-field | ||||||||||||||||||||||||||||||||||||
required | ||||||||||||||||||||||||||||||||||||
label={e} | ||||||||||||||||||||||||||||||||||||
value={extraFieldsValues[i]} | ||||||||||||||||||||||||||||||||||||
onInput={(e) => | ||||||||||||||||||||||||||||||||||||
|
@@ -291,7 +287,10 @@ export default function Vote() { | |||||||||||||||||||||||||||||||||||
<div key={index}> | ||||||||||||||||||||||||||||||||||||
<div className="mdui-prosa"> | ||||||||||||||||||||||||||||||||||||
{selectCount > 1 && ( | ||||||||||||||||||||||||||||||||||||
<h2 ref={(el) => (refs.current[index] = el)}> | ||||||||||||||||||||||||||||||||||||
<h2 | ||||||||||||||||||||||||||||||||||||
style={{ textAlign: "center" }} | ||||||||||||||||||||||||||||||||||||
ref={(el) => (refs.current[index] = el)} | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Avoid ref assignments in JSX expressions The ref assignment in the JSX expression could lead to unexpected behavior. Consider moving it to useEffect. +const headingRefs = useRef([]);
+
+useEffect(() => {
+ refs.current = headingRefs.current;
+}, []);
-ref={(el) => (refs.current[index] = el)}
+ref={(el) => (headingRefs.current[index] = el)}
🧰 Tools🪛 Biome (1.9.4)[error] 292-293: The assignment should not be in an expression. The use of assignments in expressions is confusing. (lint/suspicious/noAssignInExpressions) |
||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||
{index + 1}. Wahl | ||||||||||||||||||||||||||||||||||||
</h2> | ||||||||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||||||||
|
@@ -306,8 +305,12 @@ export default function Vote() { | |||||||||||||||||||||||||||||||||||
style={{ | ||||||||||||||||||||||||||||||||||||
cursor: | ||||||||||||||||||||||||||||||||||||
selected[index] !== e.id && selected.includes(e.id) | ||||||||||||||||||||||||||||||||||||
? "default" | ||||||||||||||||||||||||||||||||||||
? "not-allowed" | ||||||||||||||||||||||||||||||||||||
: "pointer", | ||||||||||||||||||||||||||||||||||||
backgroundColor: | ||||||||||||||||||||||||||||||||||||
selected[index] !== e.id && | ||||||||||||||||||||||||||||||||||||
selected.includes(e.id) && | ||||||||||||||||||||||||||||||||||||
"rgba(0, 0, 0, 0.5)", | ||||||||||||||||||||||||||||||||||||
}} | ||||||||||||||||||||||||||||||||||||
class={`option-card ${ | ||||||||||||||||||||||||||||||||||||
selected[index] === e.id ? "selected" : "" | ||||||||||||||||||||||||||||||||||||
|
@@ -329,20 +332,37 @@ export default function Vote() { | |||||||||||||||||||||||||||||||||||
: !selected.includes(e.id) && select(index, e.id); | ||||||||||||||||||||||||||||||||||||
}} | ||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||
<b>{e.title}</b> | ||||||||||||||||||||||||||||||||||||
<div className="teacher">{e.teacher}</div> | ||||||||||||||||||||||||||||||||||||
<div className="description">{e.description}</div> | ||||||||||||||||||||||||||||||||||||
<div className="max">max. {e.max} SchülerInnen</div> | ||||||||||||||||||||||||||||||||||||
<b className="title"> | ||||||||||||||||||||||||||||||||||||
{e.title} | ||||||||||||||||||||||||||||||||||||
<mdui-badge | ||||||||||||||||||||||||||||||||||||
style={{ | ||||||||||||||||||||||||||||||||||||
backgroundColor: "transparent", | ||||||||||||||||||||||||||||||||||||
color: "white", | ||||||||||||||||||||||||||||||||||||
}} | ||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||
<mdui-icon name="group"></mdui-icon> | ||||||||||||||||||||||||||||||||||||
{e.max} | ||||||||||||||||||||||||||||||||||||
</mdui-badge> | ||||||||||||||||||||||||||||||||||||
</b> | ||||||||||||||||||||||||||||||||||||
{e.teacher && ( | ||||||||||||||||||||||||||||||||||||
<div className="teacher"> | ||||||||||||||||||||||||||||||||||||
<mdui-icon name="person"></mdui-icon> | ||||||||||||||||||||||||||||||||||||
{e.teacher} | ||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||||||||
{e.description && ( | ||||||||||||||||||||||||||||||||||||
<div className="description">{e.description}</div> | ||||||||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||||||||
</mdui-card> | ||||||||||||||||||||||||||||||||||||
))} | ||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||
<p /> | ||||||||||||||||||||||||||||||||||||
<mdui-divider></mdui-divider> | ||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||
))} | ||||||||||||||||||||||||||||||||||||
<p /> | ||||||||||||||||||||||||||||||||||||
<br /> | ||||||||||||||||||||||||||||||||||||
<mdui-divider></mdui-divider> | ||||||||||||||||||||||||||||||||||||
<p /> | ||||||||||||||||||||||||||||||||||||
<br /> | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
<div | ||||||||||||||||||||||||||||||||||||
className="button-container" | ||||||||||||||||||||||||||||||||||||
ref={(el) => (refs.current[selectCount] = el)} | ||||||||||||||||||||||||||||||||||||
|
@@ -384,14 +404,53 @@ export default function Vote() { | |||||||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||||||||
{submitDisabled() ? ( | ||||||||||||||||||||||||||||||||||||
<mdui-button disabled end-icon="arrow_forward"> | ||||||||||||||||||||||||||||||||||||
Weiter | ||||||||||||||||||||||||||||||||||||
Überprüfen | ||||||||||||||||||||||||||||||||||||
</mdui-button> | ||||||||||||||||||||||||||||||||||||
) : ( | ||||||||||||||||||||||||||||||||||||
<mdui-button onClick={confirmSubmit} end-icon="arrow_forward"> | ||||||||||||||||||||||||||||||||||||
Weiter | ||||||||||||||||||||||||||||||||||||
Überprüfen | ||||||||||||||||||||||||||||||||||||
</mdui-button> | ||||||||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||
<p /> | ||||||||||||||||||||||||||||||||||||
<div | ||||||||||||||||||||||||||||||||||||
className="checks" | ||||||||||||||||||||||||||||||||||||
style={{ | ||||||||||||||||||||||||||||||||||||
display: "flex", | ||||||||||||||||||||||||||||||||||||
flexWrap: "wrap", | ||||||||||||||||||||||||||||||||||||
justifyContent: "center", | ||||||||||||||||||||||||||||||||||||
}} | ||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||
<CheckItem | ||||||||||||||||||||||||||||||||||||
label={"Vorname(n)"} | ||||||||||||||||||||||||||||||||||||
checked={firstName?.trim() && firstName.length >= 2} | ||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||
<CheckItem | ||||||||||||||||||||||||||||||||||||
label={"Nachname"} | ||||||||||||||||||||||||||||||||||||
checked={lastName?.trim() && lastName.length >= 2} | ||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||
<div className="break" /> | ||||||||||||||||||||||||||||||||||||
<CheckItem label={"Klasse"} checked={grade} /> | ||||||||||||||||||||||||||||||||||||
<CheckItem label={"Klassenlistennr."} checked={listIndex} /> | ||||||||||||||||||||||||||||||||||||
<div className="break" /> | ||||||||||||||||||||||||||||||||||||
{extraFields?.map((e, i) => ( | ||||||||||||||||||||||||||||||||||||
<> | ||||||||||||||||||||||||||||||||||||
<CheckItem | ||||||||||||||||||||||||||||||||||||
key={i} | ||||||||||||||||||||||||||||||||||||
label={e} | ||||||||||||||||||||||||||||||||||||
checked={extraFieldsValues[i]?.trim()} | ||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||
<div className="break" /> | ||||||||||||||||||||||||||||||||||||
</> | ||||||||||||||||||||||||||||||||||||
))} | ||||||||||||||||||||||||||||||||||||
Comment on lines
+443
to
+451
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add missing key prop to mapped elements The fragment in the extraFields map is missing a key prop, which could cause React reconciliation issues. -<>
+<React.Fragment key={i}>
<CheckItem
- key={i}
label={e}
checked={extraFieldsValues[i]?.trim()}
/>
<div className="break" />
-</>
+</React.Fragment> 📝 Committable suggestion
Suggested change
🧰 Tools🪛 Biome (1.9.4)[error] 443-445: Missing key property for this element in iterable. The order of the items may change, and having a key can help React identify which item was moved. (lint/correctness/useJsxKeyInIterable) |
||||||||||||||||||||||||||||||||||||
{Array.from({ length: selectCount }).map((e, index) => ( | ||||||||||||||||||||||||||||||||||||
<CheckItem | ||||||||||||||||||||||||||||||||||||
key={index} | ||||||||||||||||||||||||||||||||||||
label={`${index + 1}. Wahl`} | ||||||||||||||||||||||||||||||||||||
checked={selected[index] !== "null"} | ||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||
))} | ||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||
Comment on lines
+422
to
+459
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Centralize validation logic The validation logic is duplicated between + const validationRules = {
+ firstName: (value) => value?.trim() && value.length >= 2,
+ lastName: (value) => value?.trim() && value.length >= 2,
+ grade: (value) => Boolean(value),
+ listIndex: (value) => Boolean(value),
+ extraFields: (values, fields) =>
+ values?.length === fields?.length &&
+ values?.every(value => value?.trim()),
+ selections: (selected) => !selected.includes("null")
+ };
+ const validationState = {
+ firstName: validationRules.firstName(firstName),
+ lastName: validationRules.lastName(lastName),
+ grade: validationRules.grade(grade),
+ listIndex: validationRules.listIndex(listIndex),
+ extraFields: validationRules.extraFields(extraFieldsValues, extraFields),
+ selections: validationRules.selections(selected)
+ };
- const submitDisabled = () => {
- if (
- selected.includes("null") ||
- !firstName?.trim() ||
- // ... existing conditions
- ) {
- return true;
- }
- return false;
- };
+ const submitDisabled = () => {
+ return !Object.values(validationState).every(Boolean) || preview;
+ };
🧰 Tools🪛 Biome (1.9.4)[error] 449-451: Missing key property for this element in iterable. The order of the items may change, and having a key can help React identify which item was moved. (lint/correctness/useJsxKeyInIterable) |
||||||||||||||||||||||||||||||||||||
</mdui-card> | ||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add TypeScript types and prop validation
The component lacks type definitions for its props. Consider adding TypeScript interfaces or prop-types validation.
For non-TypeScript environments, add prop-types:
🧰 Tools
🪛 eslint
[error] 3-3: 'label' is missing in props validation
(react/prop-types)
[error] 3-3: 'checked' is missing in props validation
(react/prop-types)