diff --git a/src/containers/Admin/TaskDetails.jsx b/src/containers/Admin/TaskDetails.jsx
index baf0d3d2..cc73ab1c 100644
--- a/src/containers/Admin/TaskDetails.jsx
+++ b/src/containers/Admin/TaskDetails.jsx
@@ -2,30 +2,108 @@ import React, { useState } from 'react';
import { Grid, TextField, Button, Box, Typography, CircularProgress, Tabs, Tab } from '@mui/material';
import { JSONTree } from 'react-json-tree';
import GetTaskDetailsAPI from "redux/actions/api/Admin/GetTaskDetails.js";
+import GetAllTranscriptionsAPI from "redux/actions/api/Admin/GetAllTranscriptions.js";
+import GetAllTranslationsAPI from "redux/actions/api/Admin/GetAllTranslations.js";
import { snakeToTitleCase } from '../../utils/utils.js';
function TaskDetails() {
const [taskId, setTaskId] = useState('');
const [tabValue, setTabValue] = useState(0);
const [taskDetails, setTaskDetails] = useState(null);
+ const [transcriptions, setTranscriptions] = useState(null);
+ const [translations, setTranslations] = useState(null);
const [loading, setLoading] = useState(false);
+ const [loadingTranscriptions, setLoadingTranscriptions] = useState(false);
+ const [loadingTranslations, setLoadingTranslations] = useState(false);
const fetchTaskDetails = async () => {
setLoading(true);
setTaskDetails(null);
+ setTranscriptions(null);
+ setTranslations(null);
+
const apiObj = new GetTaskDetailsAPI(taskId);
- fetch(apiObj.apiEndPoint(), apiObj.getHeaders())
- .then(async (res) => {
- if (res.status === 200) {
- const data = await res.json();
- setTaskDetails(data);
- } else if (res.status === 404) {
- setTaskDetails({ error: 'Task not found' });
- } else {
- setTaskDetails({ error: 'Something went wrong' });
- }
- setLoading(false);
- });
+ try {
+ const res = await fetch(apiObj.apiEndPoint(), apiObj.getHeaders());
+ let data;
+ if (res.status === 200) {
+ data = await res.json();
+ } else if (res.status === 404) {
+ data = { error: 'Task not found' };
+ } else {
+ data = { error: 'Something went wrong' };
+ }
+
+ setLoading(false);
+ if (data.error) {
+ setTaskDetails({ error: data.error });
+ return;
+ }
+
+ setTaskDetails(data);
+ const videoId = data.video;
+
+ setTabValue(0);
+
+ if (["TRANSCRIPTION_EDIT", "TRANSCRIPTION_REVIEW"].includes(data.task_type)) {
+ fetchTranscriptions(videoId);
+ } else if (["TRANSLATION_EDIT", "TRANSLATION_REVIEW", "TRANSLATION_VOICEOVER_EDIT", "TRANSLATION_VOICEOVER_REVIEW"].includes(data.task_type)) {
+ fetchTranslations(videoId);
+ }
+
+ } catch (error) {
+ setLoading(false);
+ setTaskDetails({ error: 'Network error' });
+ console.error(error);
+ }
+ };
+
+ const fetchTranscriptions = async (videoId) => {
+ setLoadingTranscriptions(true);
+ const apiObj = new GetAllTranscriptionsAPI(videoId);
+ try {
+ const res = await fetch(apiObj.apiEndPoint(), apiObj.getHeaders());
+ let data;
+ if (res.status === 200) {
+ data = await res.json();
+ } else {
+ data = { error: 'Failed to fetch transcriptions' };
+ }
+
+ if (data.error) {
+ setTranscriptions({ error: data.error });
+ } else {
+ setTranscriptions(data.transcripts);
+ }
+ } catch (error) {
+ setTranscriptions({ error: 'Network error' });
+ console.error(error);
+ }
+ setLoadingTranscriptions(false);
+ };
+
+ const fetchTranslations = async (videoId) => {
+ setLoadingTranslations(true);
+ const apiObj = new GetAllTranslationsAPI(videoId);
+ try {
+ const res = await fetch(apiObj.apiEndPoint(), apiObj.getHeaders());
+ let data;
+ if (res.status === 200) {
+ data = await res.json();
+ } else {
+ data = { error: 'Failed to fetch translations' };
+ }
+
+ if (data.error) {
+ setTranslations({ error: data.error });
+ } else {
+ setTranslations(data);
+ }
+ } catch (error) {
+ setTranslations({ error: 'Network error' });
+ console.error(error);
+ }
+ setLoadingTranslations(false);
};
const theme = {
@@ -39,9 +117,9 @@ function TaskDetails() {
base06: '#f5f4f1',
base07: '#f9f8f5',
base08: '#f92672',
- base09: '#fd971f', //orange
+ base09: '#fd971f',
base0A: '#f4bf75',
- base0B: '#a6e22e', //green
+ base0B: '#a6e22e',
base0C: '#a1efe4',
base0D: '#66d9ef',
base0E: '#ae81ff',
@@ -86,7 +164,7 @@ function TaskDetails() {
>
{value === index && (
- {children}
+ {children}
)}
@@ -119,19 +197,80 @@ function TaskDetails() {
setTabValue(v)} aria-label="task-details-tabs">
+ {["TRANSCRIPTION_EDIT", "TRANSCRIPTION_REVIEW"].includes(taskDetails.task_type) && (
+
+ )}
+ {["TRANSLATION_EDIT", "TRANSLATION_REVIEW", "TRANSLATION_VOICEOVER_EDIT", "TRANSLATION_VOICEOVER_REVIEW"].includes(taskDetails.task_type) && (
+
+ )}
+
- {typeof key === "string" ? snakeToTitleCase(key) : key}}
- valueRenderer={(raw) => {typeof raw === "string" && raw.match(/^"(.*)"$/) ? raw.slice(1, -1) : raw}}
- theme={theme}
- />
+ {taskDetails.error ? (
+ {taskDetails.error}
+ ) : (
+ {typeof key === "string" ? snakeToTitleCase(key) : key}}
+ valueRenderer={(raw) => {typeof raw === "string" && raw.match(/^"(.*)"$/) ? raw.slice(1, -1) : raw}}
+ theme={theme}
+ />
+ )}
+
+ {["TRANSCRIPTION_EDIT", "TRANSCRIPTION_REVIEW"].includes(taskDetails.task_type) && (
+
+ {loadingTranscriptions ? (
+
+
+
+ ) : transcriptions ? (
+ transcriptions.error ? (
+ {transcriptions.error}
+ ) : (
+ {typeof key === "string" ? snakeToTitleCase(key) : key}}
+ valueRenderer={(raw) => {typeof raw === "string" && raw.match(/^"(.*)"$/) ? raw.slice(1, -1) : raw}}
+ theme={theme}
+ />
+ )
+ ) : (
+ No transcriptions available.
+ )}
+
+ )}
+
+ {["TRANSLATION_EDIT", "TRANSLATION_REVIEW", "TRANSLATION_VOICEOVER_EDIT", "TRANSLATION_VOICEOVER_REVIEW"].includes(taskDetails.task_type) && (
+
+ {loadingTranslations ? (
+
+
+
+ ) : translations ? (
+ translations.error ? (
+ {translations.error}
+ ) : (
+ {typeof key === "string" ? snakeToTitleCase(key) : key}}
+ valueRenderer={(raw) => {typeof raw === "string" && raw.match(/^"(.*)"$/) ? raw.slice(1, -1) : raw}}
+ theme={theme}
+ />
+ )
+ ) : (
+ No translations available.
+ )}
+
+ )}
>
)}
diff --git a/src/containers/Admin/VideoDetails.jsx b/src/containers/Admin/VideoDetails.jsx
new file mode 100644
index 00000000..93c01395
--- /dev/null
+++ b/src/containers/Admin/VideoDetails.jsx
@@ -0,0 +1,147 @@
+import React, { useState } from 'react';
+import { Grid, TextField, Button, Tab, Tabs, Box, Typography, CircularProgress } from '@mui/material';
+import { JSONTree } from 'react-json-tree';
+import GetVideoDetailsAPI from "redux/actions/api/Admin/GetVideoDetails.js";
+import { snakeToTitleCase } from '../../utils/utils.js';
+
+function VideoDetails() {
+ const [videoUrl, setVideoUrl] = useState('');
+ const [tabValue, setTabValue] = useState(0);
+ const [taskDetails, setTaskDetails] = useState(null);
+ const [loading, setLoading] = useState(false);
+
+ const fetchVideoDetails = async () => {
+ setLoading(true);
+ setTaskDetails(null);
+
+ const apiObj = new GetVideoDetailsAPI(videoUrl);
+ fetch(apiObj.apiEndPoint(), apiObj.getHeaders())
+ .then(async (res) => {
+ if (res.status === 200) {
+ const data = await res.json();
+ return data;
+ } else if (res.status === 404) {
+ return { error: 'Task not found' };
+ } else {
+ return { error: 'Something went wrong' };
+ }
+ })
+ .then(data => {
+ setLoading(false);
+ setTaskDetails(data);
+ });
+ };
+
+ const theme = {
+ extend: {
+ base00: '#000',
+ base01: '#383830',
+ base02: '#49483e',
+ base03: '#75715e',
+ base04: '#a59f85',
+ base05: '#f8f8f2',
+ base06: '#f5f4f1',
+ base07: '#f9f8f5',
+ base08: '#f92672',
+ base09: '#fd971f',
+ base0A: '#f4bf75',
+ base0B: '#a6e22e',
+ base0C: '#a1efe4',
+ base0D: '#66d9ef',
+ base0E: '#ae81ff',
+ base0F: '#cc6633',
+ },
+ value: ({ style }, nodeType, keyPath) => ({
+ style: {
+ ...style,
+ borderLeft: '2px solid #ccc',
+ marginLeft: '1.375em',
+ paddingLeft: '2em',
+ },
+ }),
+ nestedNode: ({ style }, nodeType, keyPath) => ({
+ style: {
+ ...style,
+ borderLeft: '2px solid #ccc',
+ marginLeft: keyPath.length > 1 ? '1.375em' : 0,
+ textIndent: '-0.375em',
+ },
+ }),
+ arrowContainer: ({ style }, arrowStyle) => ({
+ style: {
+ ...style,
+ paddingRight: '1.375rem',
+ textIndent: '0rem',
+ backgroundColor: 'white',
+ },
+ }),
+ };
+
+ function TabPanel(props) {
+ const { children, value, index, ...other } = props;
+
+ return (
+
+ {value === index && (
+
+ {children}
+
+ )}
+
+ );
+ }
+
+ return (
+
+
+
+ setVideoUrl(event.target.value)}
+ />
+
+
+
+ {loading && (
+
+
+
+ )}
+ {taskDetails && (
+ <>
+
+ setTabValue(v)} aria-label="video-task-details-tabs">
+
+
+
+
+
+
+ {typeof key === "string" ? snakeToTitleCase(key) : key}}
+ valueRenderer={(raw) => {typeof raw === "string" && raw.match(/^"(.*)"$/) ? raw.slice(1, -1) : raw}}
+ theme={theme}
+ />
+
+
+ >
+ )}
+
+ );
+}
+
+export default VideoDetails;
diff --git a/src/containers/Organization/OrgLevelTaskList.jsx b/src/containers/Organization/OrgLevelTaskList.jsx
index 75964686..f9cbeaf5 100644
--- a/src/containers/Organization/OrgLevelTaskList.jsx
+++ b/src/containers/Organization/OrgLevelTaskList.jsx
@@ -55,6 +55,7 @@ import ArrowUpwardIcon from "@mui/icons-material/ArrowUpward";
import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
import ImportExportIcon from "@mui/icons-material/ImportExport";
import AudiotrackOutlinedIcon from '@mui/icons-material/AudiotrackOutlined';
+import { Loader } from "common";
// Utils
import getLocalStorageData from "utils/getLocalStorageData";
@@ -1263,6 +1264,7 @@ const OrgLevelTaskList = () => {
return (
<>
+ {loading && }