Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion apps/portal/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,9 @@
"title": "Robot Game Scorer",
"no-equipment-constraint-title": "No Equipment Constraint:",
"no-equipment-constraint": "When this symbol appears in the top-right corner of a mission, the following constraint is applied: “No equipment may be touching any part of this mission model at the end of the match to score for this mission.”",
"score": "{points} pts"
"score": "{points} pts",
"final-score": "Final Score",
"points": "Points"
},
"rubrics": {
"title": "Rubrics",
Expand Down
6 changes: 4 additions & 2 deletions apps/portal/locale/he.json
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,11 @@
"tools": {
"scorer": {
"title": "מחשבון ניקוד",
"no-equipment-constraint-title": "מגבלת ללא מגע ציוד של הקבוצה:",
"no-equipment-constraint-title": "מגבלת \"ללא מגע ציוד של הקבוצה\":",
"no-equipment-constraint": "כאשר סמל זה מופיע בפינה השמאלית העליונה של משימה, החוק הבא חל: דגם משימה אינו יכול לקבל נקודות אם הוא נוגע בציוד בסיום המקצה.",
"score": "{points} נק'"
"score": "{points} נק'",
"final-score": "ניקוד סופי",
"points": "נקודות"
},
"rubrics": {
"title": "מחווני שיפוט",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
'use client';

export const RubricPrintStyles = () => {
return (
<style jsx global>{`
@media print {
.MuiAppBar-root,
.rubric-header,
.judging-timer,
.MuiFab-root,
.MuiButton-root {
display: none !important;
}

.MuiTableHead-root .MuiTableRow-root:first-child {
display: none !important;
}

@page {
margin: 0.5in;
size: A4;
}

.MuiContainer-root,
.rubric-content {
padding: 0 !important;
margin: 0 !important;
max-width: none !important;
width: 100% !important;
}
.MuiTable-root {
position: relative !important;
left: 0 !important;
right: 0 !important;
width: 80% !important;
margin-left: 10% !important;
margin-right: 10% !important;
}

.MuiTable-root .MuiTableCell-root {
border: 1px solid #333 !important;
padding: 8px !important;
font-size: 11px !important;
line-height: 1.3 !important;
vertical-align: top !important;
}

.MuiTableHead-root .MuiTableCell-root {
background-color: #f5f5f5 !important;
padding: 8px !important;
font-size: 12px !important;
font-weight: 600 !important;
text-align: center !important;
}

.MuiTableCell-root .MuiTypography-h6 {
font-size: 12px !important;
margin: 2px 0 !important;
font-weight: 600 !important;
}

.MuiTableCell-root .MuiTypography-body1,
.MuiTableCell-root .MuiTypography-body2 {
font-size: 11px !important;
line-height: 1.3 !important;
margin: 1px 0 !important;
}

.MuiTextField-root {
pointer-events: none !important;
margin: 2px 0 !important;
}

.MuiTextField-root input,
.MuiTextField-root textarea {
font-size: 10px !important;
padding: 4px !important;
min-height: 20px !important;
}

.MuiIconButton-root {
pointer-events: none !important;
padding: 2px !important;
}

.MuiSvgIcon-root {
color: #000 !important;
font-size: 14px !important;
}

.MuiPaper-root {
box-shadow: none !important;
border-radius: 0 !important;
}
}
`}</style>
);
};
27 changes: 19 additions & 8 deletions apps/portal/src/app/[locale]/tools/rubrics/page.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
'use client';

import { Container } from '@mui/material';
import { Container, Box } from '@mui/material';
import { ResponsiveComponent } from '@lems/shared';
import { RubricTable } from './components/desktop';
import { MobileRubricForm } from './components/mobile/rubric-form';
import { RubricProvider } from './components/rubric-context';
import { JudgingTimer } from './components/judging-timer';
import { RubricHeader } from './components/rubric-header';
import { RubricPrintStyles } from './components/rubric-print-styles';

export default function RubricsPage() {
return (
<RubricProvider>
<Container maxWidth="lg" sx={{ py: 4 }}>
<RubricHeader />
<>
<RubricPrintStyles />

<ResponsiveComponent desktop={<RubricTable />} mobile={<MobileRubricForm />} />
<RubricProvider>
<Container maxWidth="lg" sx={{ py: 4 }}>
<Box className="rubric-header">
<RubricHeader />
</Box>

<JudgingTimer />
</Container>
</RubricProvider>
<Box className="rubric-content">
<ResponsiveComponent desktop={<RubricTable />} mobile={<MobileRubricForm />} />
</Box>

<Box className="judging-timer">
<JudgingTimer />
</Box>
</Container>
</RubricProvider>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use client';

import { useContext } from 'react';
import { Box, Typography, Paper } from '@mui/material';
import { useTranslations } from 'next-intl';
import { MissionContext } from './mission-context';

export const PrintScoreSummary = () => {
const t = useTranslations('pages.tools.scorer');
const { points } = useContext(MissionContext);

if (!points) return null;

return (
<Box
sx={{
display: 'none',
'@media print': {
display: 'block',
marginTop: 4,
pageBreakBefore: 'avoid'
}
}}
>
<Paper
elevation={0}
sx={{
padding: 3,
border: '3px solid #1976d2',
borderRadius: 2,
backgroundColor: '#f8f9fa',
textAlign: 'center',
'@media print': {
border: '3px solid #1976d2 !important',
backgroundColor: '#f8f9fa !important',
WebkitPrintColorAdjust: 'exact',
printColorAdjust: 'exact'
}
}}
>
<Typography
variant="h4"
sx={{
fontWeight: 700,
color: '#1976d2',
fontSize: '24px',
'@media print': {
color: '#1976d2 !important',
fontSize: '24px !important'
}
}}
>
{t('final-score')}: {points} {t('points')}
</Typography>
</Paper>
</Box>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const ScoreFloater = () => {
alignItems="center"
justifyContent="center"
spacing={3}
className="score-floater"
sx={{
p: 4,
position: 'fixed',
Expand All @@ -29,7 +30,10 @@ export const ScoreFloater = () => {
zIndex: 1,
bgcolor: 'primary.main',
borderRadius: 4,
height: 50
height: 50,
'@media print': {
display: 'none !important'
}
}}
>
<Typography sx={{ color: '#FFF' }} fontWeight={500} fontSize="1.25rem">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
'use client';

export const ScorerPrintStyles = () => {
return (
<style jsx global>{`
@media print {
/* Hide app bar */
.MuiAppBar-root {
display: none !important;
}

/* Hide timer FAB */
.MuiFab-root {
display: none !important;
}

/* Hide score floater specifically by class */
.score-floater,
.score-floater *,
[class*='score-floater'] {
display: none !important;
visibility: hidden !important;
opacity: 0 !important;
}

/* Hide ALL Slide components (score floater uses Slide) */
.MuiSlide-root,
.MuiSlide-enter,
.MuiSlide-enter-active,
.MuiSlide-enter-done {
display: none !important;
visibility: hidden !important;
opacity: 0 !important;
}

/* Hide any fixed positioned elements */
*[style*='position: fixed'],
*[style*='position:fixed'] {
display: none !important;
}

/* Hide score floater Stack specifically */
.MuiStack-root[style*='position: fixed'],
.MuiStack-root[style*='position:fixed'],
.MuiPaper-root[style*='position: fixed'],
.MuiPaper-root[style*='position:fixed'] {
display: none !important;
}

/* Hide elements with z-index (all floating elements) */
*[style*='z-index'],
*[style*='zIndex'] {
display: none !important;
}

/* Nuclear option - hide anything with bottom positioning */
*[style*='bottom: 10'],
*[style*='bottom:10'],
*[style*='bottom: 16'],
*[style*='bottom:16'] {
display: none !important;
}

/* Ensure proper page margins */
@page {
margin: 0.5in;
}

/* Prevent page breaks in missions */
.MuiPaper-root {
page-break-inside: avoid;
break-inside: avoid;
}
}
`}</style>
);
};
42 changes: 24 additions & 18 deletions apps/portal/src/app/[locale]/tools/scorer/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,36 @@ import { MissionProvider } from './components/mission-context';
import { ScoreFloater } from './components/score-floater';
import { FieldTimer } from './components/field-timer';
import { ScoresheetForm } from './components/scoresheet-form';
import { ScorerPrintStyles } from './components/scorer-print-styles';
import { PrintScoreSummary } from './components/print-score-summary';

export default async function ScorerPage() {
const t = await getTranslations('pages.tools.scorer');

return (
<MissionProvider>
<Container maxWidth="md" sx={{ mt: 2 }}>
<Box maxWidth="95%" mb={8}>
<Typography variant="h2" gutterBottom sx={{ my: 2 }}>
{t('title')}
</Typography>
<Stack direction="row" spacing={2} alignItems="center" justifyContent="center">
<Image src={NoEquipmentImage} width={50} height={50} alt="איסור ציוד" />
<Stack>
<Typography fontWeight={500}>{t('no-equipment-constraint-title')}</Typography>
<Typography>{t('no-equipment-constraint')}</Typography>
<>
<ScorerPrintStyles />
<MissionProvider>
<Container maxWidth="md" sx={{ mt: 2 }}>
<Box maxWidth="95%" mb={8}>
<Typography variant="h2" gutterBottom sx={{ my: 2 }}>
{t('title')}
</Typography>
<Stack direction="row" spacing={2} alignItems="center" justifyContent="center">
<Image src={NoEquipmentImage} width={50} height={50} alt="איסור ציוד" />
<Stack>
<Typography fontWeight={500}>{t('no-equipment-constraint-title')}</Typography>
<Typography>{t('no-equipment-constraint')}</Typography>
</Stack>
</Stack>
</Stack>

<ScoresheetForm />
</Box>
</Container>
<ScoreFloater />
<FieldTimer />
</MissionProvider>
<ScoresheetForm />
<PrintScoreSummary />
</Box>
</Container>
<ScoreFloater />
<FieldTimer />
</MissionProvider>
</>
);
}