feat: prepare project for cozy-ui migration (#157)
* feat: prepare project for cozy-ui migration Build Configuration - Add Stylus support via @rsbuild/plugin-stylus - Add SVGR support via @rsbuild/plugin-svgr - Update rsbuild.config.ts with custom configuration - Add historyApiFallback for SPA routing ESLint Configuration - Create .eslintrc.json with react-app configuration - Remove eslintConfig from package.json CSS to Stylus Migration Convert all 5 CSS files to Stylus (.styl) format: - src/App.css to src/App.styl - src/index.css to src/index.styl - src/components/Calendar/Calendar.css to src/components/Calendar/Calendar.styl - src/components/Calendar/CustomCalendar.css to src/components/Calendar/CustomCalendar.styl - src/components/Menubar/Menubar.css to src/components/Menubar/Menubar.styl - Update all imports from .css to .styl - Preserve all styling rules and values MUI Styling Cleanup - Replace all MUI sx props with standard style props across 15+ components - Convert MUI spacing units (mr: 2 to marginRight: 16px) - Convert MUI shorthand props (p: 2 to padding: 16px, mb: 1 to marginBottom: 8px) - Remove MUI-specific syntax (&.Mui-checked selectors) - Maintain exact visual appearance FullCalendar Fixes - Comment out problematic CSS rule in CustomCalendar.styl - Fix display issues with timegrid slot labels Files Modified - Config: rsbuild.config.ts, .eslintrc.json, package.json - Styling: 5 CSS to Stylus conversions, 15+ component sx to style updates - Components: All components using MUI sx props updated Development Workflow - Continue using existing development commands - Stylus files are now the source of truth for styling - MUI components work with standard style props - ESLint uses familiar react-app rules Dependencies Added - @rsbuild/plugin-stylus - @rsbuild/plugin-svgr
This commit is contained in:
@@ -203,7 +203,7 @@ export default function EventDisplayModal({
|
||||
<MenuItem key={index} value={index}>
|
||||
<Typography variant="body2">
|
||||
<CircleIcon
|
||||
sx={{
|
||||
style={{
|
||||
color: userPersonnalCalendars[index].color ?? "#3788D8",
|
||||
width: 12,
|
||||
height: 12,
|
||||
@@ -217,7 +217,7 @@ export default function EventDisplayModal({
|
||||
<MenuItem key={index} value={index}>
|
||||
<Typography variant="body2">
|
||||
<CircleIcon
|
||||
sx={{
|
||||
style={{
|
||||
color: calendars[index].color ?? "#3788D8",
|
||||
width: 12,
|
||||
height: 12,
|
||||
@@ -231,7 +231,7 @@ export default function EventDisplayModal({
|
||||
return (
|
||||
<Modal open={open} onClose={onClose}>
|
||||
<Box
|
||||
sx={{
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "5vh",
|
||||
left: "50%",
|
||||
@@ -240,9 +240,9 @@ export default function EventDisplayModal({
|
||||
maxHeight: "80vh",
|
||||
}}
|
||||
>
|
||||
<Card sx={{ p: 2, position: "absolute" }}>
|
||||
<Card style={{ padding: 16, position: "absolute" }}>
|
||||
{/* Close button */}
|
||||
<Box sx={{ position: "absolute", top: 8, right: 8 }}>
|
||||
<Box style={{ position: "absolute", top: 8, right: 8 }}>
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => onClose({}, "backdropClick")}
|
||||
@@ -253,7 +253,7 @@ export default function EventDisplayModal({
|
||||
|
||||
<CardHeader title={isOwn ? "Edit Event" : "Event Details"} />
|
||||
|
||||
<CardContent sx={{ maxHeight: "75vh", overflow: "auto" }}>
|
||||
<CardContent style={{ maxHeight: "75vh", overflow: "auto" }}>
|
||||
{/* Title */}
|
||||
<TextField
|
||||
fullWidth
|
||||
@@ -267,7 +267,7 @@ export default function EventDisplayModal({
|
||||
|
||||
{/* RSVP */}
|
||||
{currentUserAttendee && isOwnCal && (
|
||||
<Card sx={{ my: 1 }}>
|
||||
<Card style={{ margin: "8px 0" }}>
|
||||
<ButtonGroup size="small" fullWidth>
|
||||
<Button
|
||||
color={
|
||||
@@ -408,7 +408,7 @@ export default function EventDisplayModal({
|
||||
{/* Video */}
|
||||
{event.x_openpass_videoconference && (
|
||||
<InfoRow
|
||||
icon={<VideocamIcon sx={{ fontSize: 18 }} />}
|
||||
icon={<VideocamIcon style={{ fontSize: 18 }} />}
|
||||
text="Video conference available"
|
||||
data={event.x_openpass_videoconference}
|
||||
/>
|
||||
@@ -416,7 +416,7 @@ export default function EventDisplayModal({
|
||||
|
||||
{/* Attendees */}
|
||||
{event.attendee?.length > 0 && (
|
||||
<Box sx={{ mb: 1 }}>
|
||||
<Box style={{ marginBottom: 8 }}>
|
||||
<Typography variant="subtitle2">Attendees:</Typography>
|
||||
{organizer.cal_address &&
|
||||
renderAttendeeBadge(organizer, "org", true)}
|
||||
@@ -444,7 +444,7 @@ export default function EventDisplayModal({
|
||||
<Typography
|
||||
variant="body2"
|
||||
color="primary"
|
||||
sx={{ cursor: "pointer", mt: 0.5 }}
|
||||
style={{ cursor: "pointer", marginTop: 4 }}
|
||||
onClick={() => setShowAllAttendees(!showAllAttendees)}
|
||||
>
|
||||
{showAllAttendees
|
||||
@@ -457,7 +457,7 @@ export default function EventDisplayModal({
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Divider sx={{ my: 1 }} />
|
||||
<Divider style={{ margin: "8px 0" }} />
|
||||
|
||||
{/* Extended options */}
|
||||
{showMore && (
|
||||
@@ -527,7 +527,10 @@ export default function EventDisplayModal({
|
||||
{event.error && (
|
||||
<InfoRow
|
||||
icon={
|
||||
<ErrorOutlineIcon color="error" sx={{ fontSize: 18 }} />
|
||||
<ErrorOutlineIcon
|
||||
color="error"
|
||||
style={{ fontSize: 18 }}
|
||||
/>
|
||||
}
|
||||
text={event.error}
|
||||
error
|
||||
@@ -581,7 +584,9 @@ export function InfoRow({
|
||||
data?: string;
|
||||
}) {
|
||||
return (
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: 1, mb: 1 }}>
|
||||
<Box
|
||||
style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }}
|
||||
>
|
||||
{icon}
|
||||
<Typography variant="body2" color={error ? "error" : "textPrimary"}>
|
||||
{isValidUrl(data) ? <Link href={data}>{text}</Link> : text}
|
||||
@@ -605,13 +610,13 @@ export function renderAttendeeBadge(
|
||||
return (
|
||||
<Box
|
||||
key={key}
|
||||
sx={{
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 1.5,
|
||||
mb: 0.5,
|
||||
p: 0.5,
|
||||
borderRadius: 1,
|
||||
gap: 12,
|
||||
marginBottom: 4,
|
||||
padding: 4,
|
||||
borderRadius: 4,
|
||||
}}
|
||||
>
|
||||
<Badge
|
||||
@@ -620,7 +625,7 @@ export function renderAttendeeBadge(
|
||||
badgeContent={
|
||||
classIcon && (
|
||||
<Box
|
||||
sx={{
|
||||
style={{
|
||||
fontSize: 14,
|
||||
lineHeight: 0,
|
||||
backgroundColor: "white",
|
||||
@@ -635,11 +640,11 @@ export function renderAttendeeBadge(
|
||||
>
|
||||
<Avatar {...stringAvatar(a.cn || a.cal_address)} />
|
||||
</Badge>
|
||||
<Box sx={{ display: "flex", flexDirection: "column", minWidth: 0 }}>
|
||||
<Box style={{ display: "flex", flexDirection: "column", minWidth: 0 }}>
|
||||
<Typography
|
||||
variant="body2"
|
||||
noWrap
|
||||
sx={{
|
||||
style={{
|
||||
maxWidth: "180px",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
@@ -651,7 +656,7 @@ export function renderAttendeeBadge(
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="text.secondary"
|
||||
sx={{ fontStyle: "italic" }}
|
||||
style={{ fontStyle: "italic" }}
|
||||
>
|
||||
Organizer
|
||||
</Typography>
|
||||
|
||||
@@ -115,15 +115,15 @@ export default function EventPreviewModal({
|
||||
anchorPosition={anchorPosition ?? undefined}
|
||||
onClose={onClose}
|
||||
>
|
||||
<Card sx={{ width: 300, p: 2, position: "relative" }}>
|
||||
<Card style={{ width: 300, padding: 16, position: "relative" }}>
|
||||
{/* Top-right buttons */}
|
||||
<Box
|
||||
sx={{
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: 8,
|
||||
right: 8,
|
||||
display: "flex",
|
||||
gap: 1,
|
||||
gap: 8,
|
||||
}}
|
||||
>
|
||||
{(window as any).DEBUG && (
|
||||
@@ -205,12 +205,12 @@ export default function EventPreviewModal({
|
||||
</IconButton>
|
||||
</Box>
|
||||
|
||||
<CardContent sx={{ pt: 1.5 }}>
|
||||
<CardContent style={{ paddingTop: 12 }}>
|
||||
{event.title && (
|
||||
<Typography
|
||||
variant="h6"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
style={{
|
||||
wordBreak: "break-word",
|
||||
}}
|
||||
gutterBottom
|
||||
@@ -230,7 +230,7 @@ export default function EventPreviewModal({
|
||||
{/* Location */}
|
||||
{event.location && (
|
||||
<InfoRow
|
||||
icon={<LocationOnIcon sx={{ fontSize: 18 }} />}
|
||||
icon={<LocationOnIcon style={{ fontSize: 18 }} />}
|
||||
text={event.location}
|
||||
/>
|
||||
)}
|
||||
@@ -238,7 +238,7 @@ export default function EventPreviewModal({
|
||||
{/* Video */}
|
||||
{event.x_openpass_videoconference && (
|
||||
<InfoRow
|
||||
icon={<VideocamIcon sx={{ fontSize: 18 }} />}
|
||||
icon={<VideocamIcon style={{ fontSize: 18 }} />}
|
||||
text="Video conference available"
|
||||
data={event.x_openpass_videoconference}
|
||||
/>
|
||||
@@ -246,7 +246,7 @@ export default function EventPreviewModal({
|
||||
|
||||
{/* Attendees */}
|
||||
{event.attendee?.length > 0 && (
|
||||
<Box sx={{ mb: 1 }}>
|
||||
<Box style={{ marginBottom: 8 }}>
|
||||
<Typography variant="subtitle2">Attendees:</Typography>
|
||||
{organizer && renderAttendeeBadge(organizer, "org", true)}
|
||||
{visibleAttendees.map((a, idx) =>
|
||||
@@ -256,7 +256,7 @@ export default function EventPreviewModal({
|
||||
<Typography
|
||||
variant="body2"
|
||||
color="primary"
|
||||
sx={{ cursor: "pointer", mt: 0.5 }}
|
||||
style={{ cursor: "pointer", marginTop: 4 }}
|
||||
onClick={() => setShowAllAttendees(!showAllAttendees)}
|
||||
>
|
||||
{showAllAttendees
|
||||
@@ -272,17 +272,26 @@ export default function EventPreviewModal({
|
||||
{/* Error */}
|
||||
{event.error && (
|
||||
<InfoRow
|
||||
icon={<ErrorOutlineIcon color="error" sx={{ fontSize: 18 }} />}
|
||||
icon={
|
||||
<ErrorOutlineIcon color="error" style={{ fontSize: 18 }} />
|
||||
}
|
||||
text={event.error}
|
||||
error
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Calendar color dot */}
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: 1, mb: 2 }}>
|
||||
<CalendarTodayIcon sx={{ fontSize: 16 }} />
|
||||
<Box
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 8,
|
||||
marginBottom: 16,
|
||||
}}
|
||||
>
|
||||
<CalendarTodayIcon style={{ fontSize: 16 }} />
|
||||
<CircleIcon
|
||||
sx={{
|
||||
style={{
|
||||
color: calendar.color ?? "#3788D8",
|
||||
width: 12,
|
||||
height: 12,
|
||||
@@ -291,12 +300,12 @@ export default function EventPreviewModal({
|
||||
<Typography variant="body2">{calendar.name}</Typography>
|
||||
</Box>
|
||||
|
||||
<Divider sx={{ mb: 1 }} />
|
||||
<Divider style={{ marginBottom: 8 }} />
|
||||
|
||||
{/* RSVP */}
|
||||
{currentUserAttendee && (
|
||||
<Box>
|
||||
<Typography variant="body2" sx={{ mb: 1 }}>
|
||||
<Typography variant="body2" style={{ marginBottom: 8 }}>
|
||||
Will you attend?
|
||||
</Typography>
|
||||
<ButtonGroup size="small" fullWidth>
|
||||
@@ -336,7 +345,7 @@ export default function EventPreviewModal({
|
||||
|
||||
{/* Description */}
|
||||
{event.description && (
|
||||
<Typography variant="body2" sx={{ mt: 1 }}>
|
||||
<Typography variant="body2" style={{ marginTop: 8 }}>
|
||||
{event.description}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
@@ -190,7 +190,7 @@ function EventPopover({
|
||||
<Card>
|
||||
<CardHeader title={event?.uid ? "Duplicate Event" : "Create Event"} />
|
||||
<CardContent
|
||||
sx={{ maxHeight: "85vh", maxWidth: "40vw", overflow: "auto" }}
|
||||
style={{ maxHeight: "85vh", maxWidth: "40vw", overflow: "auto" }}
|
||||
>
|
||||
<TextField
|
||||
fullWidth
|
||||
|
||||
Reference in New Issue
Block a user