Skip to content

Commit

Permalink
Merge pull request #129 from Clubs-Council-IIITH/doc_versioning
Browse files Browse the repository at this point in the history
Added versioning to CC Static documents
  • Loading branch information
abhiramtilakiiit authored Dec 19, 2024
2 parents 8a9bbe8 + 3b4d64f commit 99c8b7b
Show file tree
Hide file tree
Showing 7 changed files with 219 additions and 57 deletions.
3 changes: 2 additions & 1 deletion src/actions/storagefiles/update/server_action.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import { getClient } from "gql/client";
import { UPDATE_STORAGEFILE } from "gql/mutations/storagefiles";

export async function updateStorageFile(fileId) {
export async function updateStorageFile(fileId, version) {
const response = { ok: false, error: null };

try {
const result = await getClient().mutation(UPDATE_STORAGEFILE, {
fileId,
version,
});

// Handle case where result is null or undefined
Expand Down
48 changes: 42 additions & 6 deletions src/components/docs/DocForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,33 +79,44 @@ export default function DocForm({ editFile = null, newFile = true }) {
// check all fields
if (!data.title || !data.file) {
throw new Error(
"Please fill all the required Fields before submitting.",
"Please fill all the required Fields before submitting."
);
}

const filename = await uploadPDFFile(
data.file[0],
true,
data.title,
maxFileSizeMB,
data.title +
"_v" +
(newFile ? 1 : handleVersionNumbering(editFile)).toString(),
maxFileSizeMB
);
if (!filename) {
throw new Error("File upload failed, check Title and File validity");
}

// Extract out file extension from filename
const fileType = filename.split(".").pop();
const fileName = filename
.split(".")
.slice(0, -1)
.join(".")
.replace(/_v\d+$/, "");

if (newFile) {
// create doc
const res = await createStorageFile({
title: data.title,
filename: filename,
filetype: "pdf",
filename: fileName,
filetype: fileType,
});
if (!res.ok) {
throw res.error;
}
} else {
const newVersion = handleVersionNumbering(editFile);
// update existing doc
const res = await updateStorageFile(editFile._id);
const res = await updateStorageFile(editFile._id, newVersion);
if (!res.ok) {
throw new Error("Updating file to database failed!");
}
Expand Down Expand Up @@ -225,3 +236,28 @@ export default function DocForm({ editFile = null, newFile = true }) {
</>
);
}

const handleVersionNumbering = (oldFile) => {
const latestVersion = oldFile.latestVersion;

// Parse the modified time (IST) and convert it to UTC
const modifiedTimeIST = oldFile.modifiedTime.replace(" ", "T") + "+05:30";
const modifiedDate = new Date(modifiedTimeIST);

if (isNaN(modifiedDate)) {
throw new Error("Invalid date format for modifiedTime");
}

// Get the current UTC time
const currentDate = new Date();

// Calculate the difference in hours
const diffInHours = Math.abs(currentDate - modifiedDate) / 36e5;

// Return the version number based on the time difference
if (diffInHours < 24) {
return latestVersion;
} else {
return latestVersion + 1;
}
};
156 changes: 131 additions & 25 deletions src/components/docs/DocItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,44 @@ import {
Button,
Box,
Typography,
Select,
MenuItem,
} from "@mui/material";

import { useTheme } from "@mui/material/styles";
import useMediaQuery from "@mui/material/useMediaQuery";

import Icon from "components/Icon";
import { getFile } from "utils/files";
import { formatDate } from "components/docs/DocsList";

const buildFileName = (file, version) => {
return file.filename + "_v" + version.toString() + "." + file.filetype;
};

export default function DocItem({
file,
version,
versionChange,
maxVersion,
onClose,
open,
}) {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("md"));

export default function DocItem({ file, onClose, open }) {
const handleDownload = () => {
const fileUrl = getFile(file.filename, true, true);
const fileUrl = getFile(buildFileName(file, version), true, true);
window.open(fileUrl, "_blank");
};
const theme = useTheme();
const fullScreen = useMediaQuery(theme.breakpoints.down("md"));
const handleVersionChange = (event) => {
versionChange(event.target.value);
};

return (
<Dialog
open={open}
fullScreen={fullScreen}
fullScreen={isMobile}
onClose={onClose}
maxWidth="xl"
fullWidth
Expand All @@ -37,45 +55,129 @@ export default function DocItem({ file, onClose, open }) {
m: 0,
p: 2,
display: "flex",
justifyContent: "space-between",
alignItems: "center",
flexDirection: isMobile ? "column" : "row", // Adjust layout for mobile
justifyContent: isMobile ? "center" : "space-between",
alignItems: isMobile ? "center" : "center",
position: "relative",
}}
>
{/* Title */}
<Box
component="div"
sx={{
position: "absolute",
left: "50%",
transform: "translateX(-50%)",
position: isMobile ? "static" : "absolute",
left: isMobile ? "auto" : "50%",
transform: isMobile ? "none" : "translateX(-50%)",
textAlign: "center",
}}
>
{file.title}
</Box>

{/* Buttons on the right */}
<Box sx={{ display: "flex", gap: 2, ml: "auto" }}>
<Button
variant="contained"
startIcon={<Icon variant="download" />}
onClick={handleDownload}
size="small"
{/* Buttons and Dropdown */}
{isMobile ? (
// Render buttons below the title for mobile
<Box
sx={{
display: "flex",
flexDirection: "column",
gap: 1,
mt: 2,
mb: 2,
width: "100%",
}}
>
Download
</Button>
<IconButton onClick={onClose} size="small">
<Icon variant="close" />
</IconButton>
</Box>
{/* Dropdown */}
<Box>
<Select
value={version}
onChange={handleVersionChange}
size="small"
sx={{ minWidth: 100, width: "100%" }}
>
{Array.from({ length: maxVersion }, (_, i) => {
const version = maxVersion - i;
return (
<MenuItem key={version} value={version}>
{`v${version}${
version === maxVersion ? " (Latest)" : ""
}`}
</MenuItem>
);
})}
</Select>
</Box>

{/* Download Button */}
<Button
variant="contained"
startIcon={<Icon variant="download" />}
onClick={handleDownload}
size="small"
sx={{ width: "100%" }}
>
Download
</Button>

<IconButton
onClick={onClose}
size="small"
sx={{
position: "absolute",
top: 10,
right: 8,
}}
>
<Icon variant="close" />
</IconButton>
</Box>
) : (
// Desktop layout
<Box sx={{ display: "flex", gap: 2, ml: "auto" }}>
{/* Dropdown */}
<Box>
<Select
value={version}
onChange={handleVersionChange}
size="small"
sx={{ minWidth: 100 }}
>
{Array.from({ length: maxVersion }, (_, i) => {
const version = maxVersion - i;
return (
<MenuItem key={version} value={version}>
{`v${version}${
version === maxVersion ? " (Latest)" : ""
}`}
</MenuItem>
);
})}
</Select>
</Box>

{/* Download Button */}
<Button
variant="contained"
startIcon={<Icon variant="download" />}
onClick={handleDownload}
size="small"
>
Download
</Button>

<IconButton onClick={onClose} size="small">
<Icon variant="close" />
</IconButton>
</Box>
)}
</DialogTitle>

<DialogContent>
<iframe
src={getFile(file.filename, true, true)}
src={getFile(buildFileName(file, version), true, true)}
style={{
width: "100%",
height: "80vh",
height: "75vh",
border: "none",
}}
title={file.title}
Expand All @@ -85,6 +187,10 @@ export default function DocItem({ file, onClose, open }) {
it to view.
</Typography>
</iframe>

<Typography variant="body2" sx={{ mt: 2 }}>
Last Modified: {formatDate(file.modifiedTime)}
</Typography>
</DialogContent>
</Dialog>
);
Expand Down
39 changes: 16 additions & 23 deletions src/components/docs/DocsList.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";

import {
Paper,
Table,
Expand All @@ -14,43 +16,31 @@ import {
Grid,
} from "@mui/material";
import DocItem from "./DocItem";
import dayjs from "dayjs";
import customParseFormat from "dayjs/plugin/customParseFormat";

import Icon from "components/Icon";
import { formatDateTimeCustom } from "utils/formatTime";

import { useRouter } from "next/navigation";

dayjs.extend(customParseFormat);
export const formatDate = (dateString) => {
return formatDateTimeCustom(
dateString,
"YYYY-MM-DD HH:mm:ss",
"hh:mm A, DD MMMM YYYY IST"
);
};

export default function DocsList({ allFiles, priviliged = false }) {
const [selectedFile, setSelectedFile] = useState(null);
const [version, setVersion] = useState(null);

const router = useRouter();

const handleViewClick = (file) => {
setSelectedFile(file);
setVersion(file.latestVersion);
};
const handleViewClose = () => {
setSelectedFile(null);
};

const formatDate = (dateString) => {
try {
const date = dayjs(
dateString.replace(" IST", ""),
"DD-MM-YYYY hh:mm A",
true,
);
if (!date.isValid()) {
console.error("Invalid date parsing for:", dateString);
return dateString; // Return original string if parsing fails
}
return date.format("hh:mm:ss A, DD MMMM YYYY IST");
} catch (error) {
console.error("Date formatting error:", error);
return dateString; // Return original string if there's an error
}
setVersion(null);
};

return (
Expand Down Expand Up @@ -119,6 +109,9 @@ export default function DocsList({ allFiles, priviliged = false }) {
{selectedFile ? (
<DocItem
file={selectedFile}
version={version}
versionChange={setVersion}
maxVersion={selectedFile.latestVersion}
onClose={handleViewClose}
open={Boolean(selectedFile)}
/>
Expand Down
4 changes: 2 additions & 2 deletions src/gql/mutations/storagefiles.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export const CREATE_STORAGEFILE = gql`
`;

export const UPDATE_STORAGEFILE = gql`
mutation UpdateStorageFile($fileId: String!) {
updateStorageFile(id: $fileId)
mutation UpdateStorageFile($fileId: String!, $version: Int!) {
updateStorageFile(id: $fileId, version: $version)
}
`;

Expand Down
Loading

0 comments on commit 99c8b7b

Please sign in to comment.