Skip to content

Commit 97e1a05

Browse files
adding post questionaire
1 parent 9e5457e commit 97e1a05

8 files changed

Lines changed: 344 additions & 6 deletions

File tree

webcamstudy/asset-manifest.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"files": {
33
"main.css": "https://seresl.unl.edu/webcamstudy/static/css/main.f613a2ce.css",
4-
"main.js": "https://seresl.unl.edu/webcamstudy/static/js/main.a135b3b1.js",
4+
"main.js": "https://seresl.unl.edu/webcamstudy/static/js/main.0b2232e0.js",
55
"static/js/453.e44939a0.chunk.js": "https://seresl.unl.edu/webcamstudy/static/js/453.e44939a0.chunk.js",
66
"static/media/monkey_business.mp4": "https://seresl.unl.edu/webcamstudy/static/media/monkey_business.4c162ec3365ba53d0a3f.mp4",
77
"static/media/soccer-vid.mp4": "https://seresl.unl.edu/webcamstudy/static/media/soccer-vid.4aa09d7760e7c517c175.mp4",
@@ -223,11 +223,11 @@
223223
"static/media/5point_1920x1080.png": "https://seresl.unl.edu/webcamstudy/static/media/5point_1920x1080.16294bbf8c826fc2134e.png",
224224
"index.html": "https://seresl.unl.edu/webcamstudy/index.html",
225225
"main.f613a2ce.css.map": "https://seresl.unl.edu/webcamstudy/static/css/main.f613a2ce.css.map",
226-
"main.a135b3b1.js.map": "https://seresl.unl.edu/webcamstudy/static/js/main.a135b3b1.js.map",
226+
"main.0b2232e0.js.map": "https://seresl.unl.edu/webcamstudy/static/js/main.0b2232e0.js.map",
227227
"453.e44939a0.chunk.js.map": "https://seresl.unl.edu/webcamstudy/static/js/453.e44939a0.chunk.js.map"
228228
},
229229
"entrypoints": [
230230
"static/css/main.f613a2ce.css",
231-
"static/js/main.a135b3b1.js"
231+
"static/js/main.0b2232e0.js"
232232
]
233233
}

webcamstudy/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="https://seresl.unl.edu/webcamstudy/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="https://seresl.unl.edu/webcamstudy/logo192.png"/><link rel="manifest" href="https://seresl.unl.edu/webcamstudy/manifest.json"/><title>Eye Tracking Webcam Study</title><script type="module">import EmbeddedPageSdk from"https://app.realeye.io/sdk/js/testRunnerEmbeddableSdk-1.7.1.js";let reSdk=null;window.addEventListener("DOMContentLoaded",()=>{reSdk=new EmbeddedPageSdk(!1,null,!1)}),window.addEventListener("endmeplease",()=>{reSdk&&reSdk.finishEyeTrackingTest()})</script><script defer="defer" src="https://seresl.unl.edu/webcamstudy/static/js/main.a135b3b1.js"></script><link href="https://seresl.unl.edu/webcamstudy/static/css/main.f613a2ce.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
1+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="https://seresl.unl.edu/webcamstudy/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="https://seresl.unl.edu/webcamstudy/logo192.png"/><link rel="manifest" href="https://seresl.unl.edu/webcamstudy/manifest.json"/><title>Eye Tracking Webcam Study</title><script type="module">import EmbeddedPageSdk from"https://app.realeye.io/sdk/js/testRunnerEmbeddableSdk-1.7.1.js";let reSdk=null,sdkInitialized=!1;window.initRealeyeSDK=()=>{if(sdkInitialized)return;reSdk=new EmbeddedPageSdk(!1,null,!1),sdkInitialized=!0;new MutationObserver(e=>{e.some(e=>Array.from(e.addedNodes).some(e=>e.nodeType===Node.ELEMENT_NODE&&(e.hasAttribute("data-re-aoi-name")||null!==e.querySelector("[data-re-aoi-name]"))))&&reSdk&&setTimeout(()=>{},100)}).observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["data-re-aoi-name"]})},window.addEventListener("endmeplease",()=>{reSdk&&reSdk.finishEyeTrackingTest()})</script><script defer="defer" src="https://seresl.unl.edu/webcamstudy/static/js/main.0b2232e0.js"></script><link href="https://seresl.unl.edu/webcamstudy/static/css/main.f613a2ce.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

webcamstudy/src/App.jsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import VideoTask from "./components/Video/VideoTask";
1010
import FaceTask2x2 from "./components/FaceTask2x2";
1111
import FaceTask3x3 from "./components/FaceTask3x3";
1212
import ValidationGrid from "./components/validation_grid/ValidationGrid";
13+
import PostQuestionnaire from "./components/PostQuestionnaire";
1314

1415
// Utility to shuffle an array
1516
function shuffle(array) {
@@ -33,6 +34,7 @@ function App() {
3334
videoTask: null,
3435
faceTask2x2: null,
3536
faceTask3x3: null,
37+
postQuestionnaire: null,
3638
});
3739

3840
// State to track study timing
@@ -72,9 +74,10 @@ function App() {
7274
"FaceTask2x2",
7375
"FaceTask3x3",
7476
];
77+
const alwaysLast = ["PostQuestionnaire"];
7578
const randomized = shuffle(toRandomize);
7679
setRandomizedOrder(randomized);
77-
setTaskFiles([...alwaysFirst, ...randomized]);
80+
setTaskFiles([...alwaysFirst, ...randomized, ...alwaysLast]);
7881
};
7982

8083
const handleTaskComplete = (taskType, data) => {
@@ -244,6 +247,22 @@ function App() {
244247
});
245248
}
246249

250+
// Add post-questionnaire responses
251+
if (studyData.postQuestionnaire) {
252+
jsonData.postQuestionnaire = {
253+
difficulty: studyData.postQuestionnaire.difficulty,
254+
hasVisualImpairments: studyData.postQuestionnaire.hasVisualImpairments,
255+
visualImpairmentsSpecify: studyData.postQuestionnaire.visualImpairmentsSpecify || "",
256+
hadReadingProblems: studyData.postQuestionnaire.hadReadingProblems,
257+
readingProblemsSpecify: studyData.postQuestionnaire.readingProblemsSpecify || "",
258+
completedTimely: studyData.postQuestionnaire.completedTimely,
259+
thingsLiked: studyData.postQuestionnaire.thingsLiked || "",
260+
thingsDisliked: studyData.postQuestionnaire.thingsDisliked || "",
261+
otherComments: studyData.postQuestionnaire.otherComments || "",
262+
timestamp: studyData.postQuestionnaire.timestamp,
263+
};
264+
}
265+
247266
// Download JSON file
248267
const jsonString = JSON.stringify(jsonData, null, 2);
249268
const blob = new Blob([jsonString], {
@@ -344,6 +363,12 @@ function App() {
344363
);
345364
case "ValidationGrid":
346365
return <ValidationGrid onComplete={incrementTask} />;
366+
case "PostQuestionnaire":
367+
return (
368+
<PostQuestionnaire
369+
onSubmit={(data) => handleTaskComplete("postQuestionnaire", data)}
370+
/>
371+
);
347372
default:
348373
return <div>Unknown task</div>;
349374
}
@@ -378,6 +403,7 @@ function App() {
378403
"FaceTask3x3",
379404
"TextTask",
380405
"ValidationGrid",
406+
"PostQuestionnaire",
381407
].includes(currentTaskName) &&
382408
isVideoTaskComplete())));
383409

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
import React, { useState } from 'react';
2+
import ContinueButton from './ContinueButton';
3+
4+
const PostQuestionnaire = ({ onSubmit }) => {
5+
const [formData, setFormData] = useState({
6+
difficulty: '',
7+
hasVisualImpairments: '',
8+
visualImpairmentsSpecify: '',
9+
hadReadingProblems: '',
10+
readingProblemsSpecify: '',
11+
completedTimely: '',
12+
thingsLiked: '',
13+
thingsDisliked: '',
14+
otherComments: ''
15+
});
16+
17+
const handleInputChange = (field, value) => {
18+
setFormData(prev => ({
19+
...prev,
20+
[field]: value
21+
}));
22+
};
23+
24+
const handleSubmit = (e) => {
25+
e.preventDefault();
26+
const finalData = {
27+
...formData,
28+
timestamp: new Date().toISOString()
29+
};
30+
onSubmit?.(finalData);
31+
};
32+
33+
const isFormValid = formData.difficulty &&
34+
formData.hasVisualImpairments &&
35+
formData.hadReadingProblems &&
36+
formData.completedTimely;
37+
38+
return (
39+
<div style={styles.container}>
40+
<h2 style={styles.title}>Post-Study Questionnaire</h2>
41+
<form onSubmit={handleSubmit} style={styles.form}>
42+
43+
<div style={styles.fieldRow}>
44+
<label style={styles.sideLabel}>Overall, how difficult did you find the study?</label>
45+
<div style={styles.radioGroup}>
46+
{[1, 2, 3, 4, 5].map(level => (
47+
<label key={level} style={styles.radioLabel}>
48+
<input
49+
type="radio"
50+
name="difficulty"
51+
value={level}
52+
checked={formData.difficulty === String(level)}
53+
onChange={(e) => handleInputChange('difficulty', e.target.value)}
54+
style={styles.radio}
55+
required
56+
/>
57+
{level} {level === 1 ? '(Very Easy)' : level === 5 ? '(Very Hard)' : ''}
58+
</label>
59+
))}
60+
</div>
61+
</div>
62+
63+
<div style={styles.fieldRow}>
64+
<label style={styles.sideLabel}>Do you have any visual impairments?</label>
65+
<div style={styles.optionsContainer}>
66+
<div style={styles.radioGroup}>
67+
{['Yes', 'No'].map(answer => (
68+
<label key={answer} style={styles.radioLabel}>
69+
<input
70+
type="radio"
71+
name="hasVisualImpairments"
72+
value={answer}
73+
checked={formData.hasVisualImpairments === answer}
74+
onChange={(e) => handleInputChange('hasVisualImpairments', e.target.value)}
75+
style={styles.radio}
76+
required
77+
/>
78+
{answer}
79+
</label>
80+
))}
81+
</div>
82+
{formData.hasVisualImpairments === 'Yes' && (
83+
<textarea
84+
placeholder="Please specify"
85+
value={formData.visualImpairmentsSpecify}
86+
onChange={(e) => handleInputChange('visualImpairmentsSpecify', e.target.value)}
87+
style={styles.textarea}
88+
rows={3}
89+
/>
90+
)}
91+
</div>
92+
</div>
93+
94+
<div style={styles.fieldRow}>
95+
<label style={styles.sideLabel}>Did you have any problems reading the text?</label>
96+
<div style={styles.optionsContainer}>
97+
<div style={styles.radioGroup}>
98+
{['Yes', 'No'].map(answer => (
99+
<label key={answer} style={styles.radioLabel}>
100+
<input
101+
type="radio"
102+
name="hadReadingProblems"
103+
value={answer}
104+
checked={formData.hadReadingProblems === answer}
105+
onChange={(e) => handleInputChange('hadReadingProblems', e.target.value)}
106+
style={styles.radio}
107+
required
108+
/>
109+
{answer}
110+
</label>
111+
))}
112+
</div>
113+
{formData.hadReadingProblems === 'Yes' && (
114+
<textarea
115+
placeholder="Please specify"
116+
value={formData.readingProblemsSpecify}
117+
onChange={(e) => handleInputChange('readingProblemsSpecify', e.target.value)}
118+
style={styles.textarea}
119+
rows={3}
120+
/>
121+
)}
122+
</div>
123+
</div>
124+
125+
<div style={styles.fieldRow}>
126+
<label style={styles.sideLabel}>Did you complete the tasks in a reasonably timely manner?</label>
127+
<div style={styles.radioGroup}>
128+
{['Yes', 'No'].map(answer => (
129+
<label key={answer} style={styles.radioLabel}>
130+
<input
131+
type="radio"
132+
name="completedTimely"
133+
value={answer}
134+
checked={formData.completedTimely === answer}
135+
onChange={(e) => handleInputChange('completedTimely', e.target.value)}
136+
style={styles.radio}
137+
required
138+
/>
139+
{answer}
140+
</label>
141+
))}
142+
</div>
143+
</div>
144+
145+
<div style={styles.fieldRow}>
146+
<label style={styles.sideLabel}>What are things you liked about this study?</label>
147+
<textarea
148+
value={formData.thingsLiked}
149+
onChange={(e) => handleInputChange('thingsLiked', e.target.value)}
150+
style={styles.textarea}
151+
rows={4}
152+
placeholder="Please share what you liked about the study"
153+
/>
154+
</div>
155+
156+
<div style={styles.fieldRow}>
157+
<label style={styles.sideLabel}>What are things you disliked about this study?</label>
158+
<textarea
159+
value={formData.thingsDisliked}
160+
onChange={(e) => handleInputChange('thingsDisliked', e.target.value)}
161+
style={styles.textarea}
162+
rows={4}
163+
placeholder="Please share what you disliked about the study"
164+
/>
165+
</div>
166+
167+
<div style={styles.fieldRow}>
168+
<label style={styles.sideLabel}>Please write any other comments or concerns</label>
169+
<textarea
170+
value={formData.otherComments}
171+
onChange={(e) => handleInputChange('otherComments', e.target.value)}
172+
style={styles.textarea}
173+
rows={4}
174+
placeholder="Any additional comments or concerns"
175+
/>
176+
</div>
177+
178+
<ContinueButton type="submit" disabled={!isFormValid} />
179+
</form>
180+
</div>
181+
);
182+
};
183+
184+
const styles = {
185+
container: {
186+
display: 'flex',
187+
flexDirection: 'column',
188+
alignItems: 'center',
189+
justifyContent: 'flex-start',
190+
minHeight: '100vh',
191+
width: '100%',
192+
fontFamily: 'Arial, sans-serif',
193+
backgroundColor: '#fff',
194+
overflowY: 'auto',
195+
padding: '20px',
196+
boxSizing: 'border-box',
197+
},
198+
title: {
199+
marginBottom: '30px',
200+
fontSize: '24px',
201+
color: '#2c3e50',
202+
},
203+
form: {
204+
width: '100%',
205+
maxWidth: '800px',
206+
display: 'flex',
207+
flexDirection: 'column',
208+
gap: '15px',
209+
},
210+
fieldRow: {
211+
display: 'flex',
212+
alignItems: 'flex-start',
213+
gap: '20px',
214+
minHeight: '40px',
215+
},
216+
sideLabel: {
217+
fontSize: '16px',
218+
fontWeight: 'bold',
219+
color: '#2c3e50',
220+
minWidth: '200px',
221+
paddingTop: '8px',
222+
textAlign: 'right',
223+
},
224+
optionsContainer: {
225+
flex: 1,
226+
display: 'flex',
227+
flexDirection: 'column',
228+
gap: '8px',
229+
},
230+
textarea: {
231+
flex: 1,
232+
padding: '10px',
233+
fontSize: '14px',
234+
border: '1px solid #ccc',
235+
borderRadius: '4px',
236+
outline: 'none',
237+
fontFamily: 'Arial, sans-serif',
238+
resize: 'vertical',
239+
minHeight: '80px',
240+
},
241+
radioGroup: {
242+
display: 'flex',
243+
flexDirection: 'column',
244+
gap: '6px',
245+
},
246+
radioLabel: {
247+
display: 'flex',
248+
alignItems: 'center',
249+
gap: '8px',
250+
fontSize: '14px',
251+
cursor: 'pointer',
252+
},
253+
radio: {
254+
margin: 0,
255+
},
256+
};
257+
258+
export default PostQuestionnaire;
259+

webcamstudy/static/css/main.f613a2ce.css.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webcamstudy/static/js/main.0b2232e0.js

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)