Merged PR 2070: media tab and player
Related work items: #21254, #21255, #21256
This commit is contained in:
+103
-90
@@ -34,7 +34,7 @@ export const getIP = (req) => {
|
||||
|
||||
console.info(
|
||||
"\n====================\n Client IP address: " + ip,
|
||||
"\n=====================\n"
|
||||
"\n=====================\n",
|
||||
);
|
||||
};
|
||||
|
||||
@@ -42,7 +42,7 @@ export const consoleLogger = (err) => {
|
||||
console.log(
|
||||
"\n\n/////////////////////////////////////////////////\nRaw Error " +
|
||||
err +
|
||||
"\n\n/////////////////////////////////////////////////\n"
|
||||
"\n\n/////////////////////////////////////////////////\n",
|
||||
);
|
||||
var errStr =
|
||||
"\n\n/////////////////////////////////////////////////\nServer Error " +
|
||||
@@ -102,7 +102,7 @@ export const getToken = () => {
|
||||
.post(
|
||||
`${accessTokenEndpoint}${tenantId}/oauth2/v2.0/token`,
|
||||
tokenBody,
|
||||
tokenConfig
|
||||
tokenConfig,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.then((data) => {
|
||||
@@ -191,7 +191,7 @@ export const azureHeadersPagedCustom = (access_token, showNumberOfRecords) => {
|
||||
export const hashAPIPath = (queryPath) => {
|
||||
var hashlink = CryptoJS.HmacSHA256(
|
||||
queryPath,
|
||||
CryptoJS.enc.Hex.parse(WORDKEY)
|
||||
CryptoJS.enc.Hex.parse(WORDKEY),
|
||||
);
|
||||
hashlink = hashlink.toString(CryptoJS.enc.Hex);
|
||||
return (queryPath.indexOf("?") > -1 ? "&hash=" : "?hash=") + hashlink;
|
||||
@@ -216,7 +216,7 @@ export const getBasicSearch = (searchString) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getbasicsearch_api?searchString=" +
|
||||
searchString
|
||||
searchString,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -244,7 +244,7 @@ export const getIncidentbyID = (searchString) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getincidentbyid_api?searchString=" +
|
||||
searchString
|
||||
searchString,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -258,7 +258,7 @@ export const getIncidentbyID = (searchString) => {
|
||||
export const getIsPublishedbyID = (searchString) => {
|
||||
return axios
|
||||
.get(
|
||||
"/api/endpoint/getispublishedbyid_api?searchString=" + searchString
|
||||
"/api/endpoint/getispublishedbyid_api?searchString=" + searchString,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -274,7 +274,7 @@ export const getPartSavedAppeal = (searchString) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getpartsavedappeal_api?searchString=" +
|
||||
searchString
|
||||
searchString,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -290,7 +290,7 @@ export const getBasicDNSURLSearch = (searchString) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getbasicdnsurlsearch_api?searchString=" +
|
||||
searchString
|
||||
searchString,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -313,12 +313,24 @@ export const getSIPSEvents = async (caseid) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const getSIPSMedia = async (caseid) => {
|
||||
return axios
|
||||
.get(BASE_URL + "/api/endpoint/getsipsmedia_api?caseid=" + caseid)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
})
|
||||
.catch((error) => {
|
||||
consoleLogger(error);
|
||||
return error.response;
|
||||
});
|
||||
};
|
||||
|
||||
export const getAddressSearchPaged = (
|
||||
searchString,
|
||||
pageNumber,
|
||||
orderBy,
|
||||
fieldSort,
|
||||
showNumberOfRecords
|
||||
showNumberOfRecords,
|
||||
) => {
|
||||
return axios
|
||||
.get(
|
||||
@@ -331,7 +343,7 @@ export const getAddressSearchPaged = (
|
||||
"&fieldSort=" +
|
||||
fieldSort +
|
||||
"&showNumberOfRecords=" +
|
||||
showNumberOfRecords
|
||||
showNumberOfRecords,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -347,7 +359,7 @@ export const getBasicSearchPaged = (
|
||||
pageNumber,
|
||||
orderBy,
|
||||
fieldSort,
|
||||
showNumberOfRecords
|
||||
showNumberOfRecords,
|
||||
) => {
|
||||
return axios
|
||||
.get(
|
||||
@@ -360,7 +372,7 @@ export const getBasicSearchPaged = (
|
||||
"&fieldSort=" +
|
||||
fieldSort +
|
||||
"&showNumberOfRecords=" +
|
||||
showNumberOfRecords
|
||||
showNumberOfRecords,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -413,7 +425,7 @@ export const getBasicDNSSearchPaged = (
|
||||
pageNumber,
|
||||
orderBy,
|
||||
fieldSort,
|
||||
showNumberOfRecords
|
||||
showNumberOfRecords,
|
||||
) => {
|
||||
return axios
|
||||
.get(
|
||||
@@ -424,7 +436,7 @@ export const getBasicDNSSearchPaged = (
|
||||
"&fieldSort=" +
|
||||
fieldSort +
|
||||
"&showNumberOfRecords=" +
|
||||
showNumberOfRecords
|
||||
showNumberOfRecords,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -438,7 +450,7 @@ export const getAdvancedSearch = (searchString) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getadvancedsearch_api?searchstring=" +
|
||||
JSON.stringify(searchString)
|
||||
JSON.stringify(searchString),
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -458,7 +470,7 @@ export const getAdvancedSearchPaged = (
|
||||
pageNumber,
|
||||
orderBy,
|
||||
fieldSort,
|
||||
showNumberOfRecords
|
||||
showNumberOfRecords,
|
||||
) => {
|
||||
return axios
|
||||
.get(
|
||||
@@ -471,7 +483,7 @@ export const getAdvancedSearchPaged = (
|
||||
"&fieldSort=" +
|
||||
fieldSort +
|
||||
"&showNumberOfRecords=" +
|
||||
showNumberOfRecords
|
||||
showNumberOfRecords,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -490,7 +502,7 @@ export const getBasicSearchDetails = async (
|
||||
appealTypeName,
|
||||
caseReference,
|
||||
primaryIdAttribute,
|
||||
incidentID
|
||||
incidentID,
|
||||
) => {
|
||||
return axios
|
||||
.get(
|
||||
@@ -500,7 +512,7 @@ export const getBasicSearchDetails = async (
|
||||
"&primaryIdAttribute=" +
|
||||
primaryIdAttribute +
|
||||
"&incidentID=" +
|
||||
incidentID
|
||||
incidentID,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -512,7 +524,7 @@ export const getBasicPartSavedDetails = (
|
||||
appealTypeName,
|
||||
caseReference,
|
||||
primaryIdAttribute,
|
||||
incidentID
|
||||
incidentID,
|
||||
) => {
|
||||
//console.log(
|
||||
// "///////api call: ",
|
||||
@@ -532,7 +544,7 @@ export const getBasicPartSavedDetails = (
|
||||
"&primaryIdAttribute=" +
|
||||
primaryIdAttribute +
|
||||
"&incidentID=" +
|
||||
incidentID
|
||||
incidentID,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -544,7 +556,7 @@ export const getBasicSearchDetailsPaged = async (
|
||||
appealTypeName,
|
||||
caseReference,
|
||||
primaryIdAttribute,
|
||||
incidentIDs
|
||||
incidentIDs,
|
||||
) => {
|
||||
if (!incidentIDs || incidentIDs.length === 0) return [];
|
||||
|
||||
@@ -566,11 +578,11 @@ export const getBasicSearchDetailsPaged = async (
|
||||
.join(" or ");
|
||||
|
||||
const url = `/api/endpoint/getbasicsearchdetailspaged_api?appealTypeName=${appealTypeName}&primaryIdAttribute=${primaryIdAttribute}&incidentID=${encodeURIComponent(
|
||||
filter
|
||||
filter,
|
||||
)}`;
|
||||
|
||||
console.log(
|
||||
`Fetching ${incidentIDs.length} incidents for appeal type: ${appealTypeName}`
|
||||
`Fetching ${incidentIDs.length} incidents for appeal type: ${appealTypeName}`,
|
||||
);
|
||||
|
||||
try {
|
||||
@@ -586,7 +598,7 @@ export const getSearchDocumentDetails = (incidentID) => {
|
||||
return axios
|
||||
.get(
|
||||
"/api/endpoint/getsearchdocumentdetails_api?incidentid=" +
|
||||
incidentID
|
||||
incidentID,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -598,7 +610,7 @@ export const getSearchDocumentDetails = (incidentID) => {
|
||||
export const getSearchDocumentTypes = (incidentID) => {
|
||||
return axios
|
||||
.get(
|
||||
"/api/endpoint/getsearchdocumentTypes_api?incidentid=" + incidentID
|
||||
"/api/endpoint/getsearchdocumentTypes_api?incidentid=" + incidentID,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -611,7 +623,7 @@ export const getAppealPDFDocs = (incidentID) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getappealpdfdocuments_api?incidentid=" +
|
||||
incidentID
|
||||
incidentID,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -625,7 +637,7 @@ export const getSearchDocumentDetailsPaged = (
|
||||
orderBy,
|
||||
fieldSort,
|
||||
showNumberOfRecords,
|
||||
documentType
|
||||
documentType,
|
||||
) => {
|
||||
//console.log("to api:", documentType);
|
||||
return axios
|
||||
@@ -641,7 +653,7 @@ export const getSearchDocumentDetailsPaged = (
|
||||
"&showNumberOfRecords=" +
|
||||
showNumberOfRecords +
|
||||
"&documentType=" +
|
||||
documentType
|
||||
documentType,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -653,7 +665,7 @@ export const getLinkedCases = (parentIncidentid) => {
|
||||
return axios
|
||||
.get(
|
||||
"/api/endpoint/getlinkedcases_api?parentincidentid=" +
|
||||
parentIncidentid
|
||||
parentIncidentid,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -745,7 +757,7 @@ export const getMandatoryFields = (whichForm) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getmandatoryfields_api?whichForm=" +
|
||||
whichForm
|
||||
whichForm,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -767,7 +779,7 @@ export const getPersonalAccount = (contactid) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getpersonalaccount_api?contactid=" +
|
||||
contactid
|
||||
contactid,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -787,7 +799,7 @@ export const getPersonalAccount = (contactid) => {
|
||||
export const getAppealID = (
|
||||
caseReference,
|
||||
updateFormCollection,
|
||||
primaryAttribute
|
||||
primaryAttribute,
|
||||
) => {
|
||||
//console.log(
|
||||
// "is this the collection?:",
|
||||
@@ -803,11 +815,11 @@ export const getAppealID = (
|
||||
"&primaryAttribute=" +
|
||||
primaryAttribute +
|
||||
"&caseReference=" +
|
||||
caseReference
|
||||
caseReference,
|
||||
)
|
||||
.then((res) => {
|
||||
const result = Object.entries(res.data.value[0]).filter(
|
||||
([key]) => !key.startsWith("_")
|
||||
([key]) => !key.startsWith("_"),
|
||||
)[0][1];
|
||||
// console.log("result:", res.data);
|
||||
var appealID = result;
|
||||
@@ -824,7 +836,7 @@ export const getLogin = (emailAddress, pwd) => {
|
||||
"/api/endpoint/getlogin_api?emailAddress=" +
|
||||
emailAddress +
|
||||
"&pwd=" +
|
||||
pwd
|
||||
pwd,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -837,7 +849,7 @@ export const getMyCases = (loggedInUserId) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getmycases_api?loggedInUserId=" +
|
||||
loggedInUserId
|
||||
loggedInUserId,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -852,7 +864,7 @@ export const getMyInvolvements = async (loggedInUserId) => {
|
||||
const res = await axios.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getmyinvolvements_api?loggedInUserId=" +
|
||||
loggedInUserId
|
||||
loggedInUserId,
|
||||
);
|
||||
return res.data;
|
||||
} catch (error) {
|
||||
@@ -876,7 +888,7 @@ export const getMyRepresentations = (loggedInUserId) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getmyrepresentations_api?loggedInUserId=" +
|
||||
loggedInUserId
|
||||
loggedInUserId,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -888,7 +900,7 @@ export const getMyRepresentationsProxy = (loggedInUserId) => {
|
||||
return axios
|
||||
.get(
|
||||
"/api/endpoint/getmyrepresentationsproxy_api?loggedInUserId=" +
|
||||
loggedInUserId
|
||||
loggedInUserId,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -908,7 +920,8 @@ export const getRepresentations = (incidentID) => {
|
||||
export const getRepresentationsProxy = (incidentID) => {
|
||||
return axios
|
||||
.get(
|
||||
"/api/endpoint/getrepresentationsproxy_api?incidentID=" + incidentID
|
||||
"/api/endpoint/getrepresentationsproxy_api?incidentID=" +
|
||||
incidentID,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -921,7 +934,7 @@ export const getWatchedCases = (loggedInUserId) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getwatchedcases_api?loggedInUserId=" +
|
||||
loggedInUserId
|
||||
loggedInUserId,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -933,7 +946,7 @@ export const getWatchedCasesProxy = (loggedInUserId) => {
|
||||
return axios
|
||||
.get(
|
||||
"/api/endpoint/getwatchedcasesproxy_api?loggedInUserId=" +
|
||||
loggedInUserId
|
||||
loggedInUserId,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -945,7 +958,7 @@ export const getAwaitingSubmissionProxy = (loggedInUserId) => {
|
||||
return axios
|
||||
.get(
|
||||
"/api/endpoint/getawaitingsubmissionproxy_api?loggedInUserId=" +
|
||||
loggedInUserId
|
||||
loggedInUserId,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -958,7 +971,7 @@ export const getAwaitingSubmission = (loggedInUserId) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getawaitingsubmission_api?loggedInUserId=" +
|
||||
loggedInUserId
|
||||
loggedInUserId,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -988,8 +1001,8 @@ export const getAwaitingSubmissionFromBlob = (containerName) => {
|
||||
containerName +
|
||||
hashAPIPath(
|
||||
"/api/file/getawaitingsubmissionfromblob?container=" +
|
||||
containerName
|
||||
)
|
||||
containerName,
|
||||
),
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -1015,7 +1028,7 @@ export const getRepsFromBlob = (containerName) => {
|
||||
BASE_URL +
|
||||
"/api/file/getrepsblob?container=" +
|
||||
containerName +
|
||||
hashAPIPath("/api/file/getrepsblob?container=" + containerName)
|
||||
hashAPIPath("/api/file/getrepsblob?container=" + containerName),
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -1042,7 +1055,7 @@ export const getRepsFromBlobProxy = async (containerName) => {
|
||||
try {
|
||||
const res = await axios.get(
|
||||
// BASE_URL +
|
||||
"/api/file/getrepsblobproxy?container=" + containerName
|
||||
"/api/file/getrepsblobproxy?container=" + containerName,
|
||||
// +
|
||||
// hashAPIPath(
|
||||
// "/api/file/getawaitingsubmissionfromblob?container=" +
|
||||
@@ -1061,14 +1074,14 @@ export const getAwaitingSubmissionFromBlobProxy = async (containerName) => {
|
||||
containerName,
|
||||
"/api/file/getawaitingsubmissionfromblobproxy?container=" +
|
||||
containerName,
|
||||
"\n///////////////////////\n"
|
||||
"\n///////////////////////\n",
|
||||
);
|
||||
|
||||
try {
|
||||
const res = await axios.get(
|
||||
BASE_URL +
|
||||
"/api/file/getawaitingsubmissionfromblobproxy?container=" +
|
||||
containerName
|
||||
containerName,
|
||||
// +
|
||||
// hashAPIPath(
|
||||
// "/api/file/getawaitingsubmissionfromblob?container=" +
|
||||
@@ -1129,7 +1142,7 @@ export const getPortalModuleDetailsProxy = (appealType, caseReference) => {
|
||||
"/api/endpoint/getportalmoduledetailsproxy_api?appealType=" +
|
||||
appealType +
|
||||
"&caseReference=" +
|
||||
caseReference.replace(/\'/g, "''")
|
||||
caseReference.replace(/\'/g, "''"),
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -1141,7 +1154,7 @@ export const getEmailAccountCheck = (emailAddress) => {
|
||||
return axios
|
||||
.get(
|
||||
"/api/endpoint/getemailaccountcheck_api?emailAddress=" +
|
||||
emailAddress
|
||||
emailAddress,
|
||||
)
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
@@ -1213,7 +1226,7 @@ export const createNewCase = (
|
||||
lpaID,
|
||||
contactid,
|
||||
createBody,
|
||||
containerName
|
||||
containerName,
|
||||
) => {
|
||||
appealTypeId = parseInt(appealTypeId);
|
||||
|
||||
@@ -1250,7 +1263,7 @@ export const createNewCaseBlob = (
|
||||
contactid,
|
||||
createBody,
|
||||
containerName,
|
||||
lpaName
|
||||
lpaName,
|
||||
) => {
|
||||
appealTypeId = parseInt(appealTypeId);
|
||||
|
||||
@@ -1302,14 +1315,14 @@ export const updateCase = async (
|
||||
updateBody,
|
||||
updateFormCollection,
|
||||
primaryAttribute,
|
||||
caseReference
|
||||
caseReference,
|
||||
) => {
|
||||
var data = updateBody;
|
||||
|
||||
var appealObj = await getAppealID(
|
||||
caseReference,
|
||||
updateFormCollection,
|
||||
primaryAttribute
|
||||
primaryAttribute,
|
||||
);
|
||||
|
||||
var queryUrl =
|
||||
@@ -1340,14 +1353,14 @@ export const updateCaseBlob = async (
|
||||
updateBody,
|
||||
updateFormCollection,
|
||||
primaryAttribute,
|
||||
caseReference
|
||||
caseReference,
|
||||
) => {
|
||||
var data = updateBody;
|
||||
|
||||
var appealObj = await getAppealID(
|
||||
caseReference,
|
||||
updateFormCollection,
|
||||
primaryAttribute
|
||||
primaryAttribute,
|
||||
);
|
||||
|
||||
var queryUrl =
|
||||
@@ -1415,7 +1428,7 @@ export const getCaseByID = (incidentID) => {
|
||||
// );
|
||||
return axios
|
||||
.get(
|
||||
BASE_URL + "/api/endpoint/getcasebyid_api?incidentID=" + incidentID
|
||||
BASE_URL + "/api/endpoint/getcasebyid_api?incidentID=" + incidentID,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -1473,7 +1486,7 @@ export const deleteAwaitingSubmissions = (incidentID) => {
|
||||
|
||||
export const deleteAwaitingSubmissionsFromBlob = (
|
||||
containerID,
|
||||
casefolderID
|
||||
casefolderID,
|
||||
) => {
|
||||
var queryUrl =
|
||||
"/api/file/deleteblobcase?container=" +
|
||||
@@ -1499,7 +1512,7 @@ export const deleteAwaitingSubmissionsFromBlob = (
|
||||
export const deleteMyRepresentationsFromBlob = (
|
||||
containerID,
|
||||
casefolderID,
|
||||
repfile
|
||||
repfile,
|
||||
) => {
|
||||
var queryUrl =
|
||||
"/api/file/deleteblobrep?container=" +
|
||||
@@ -1563,7 +1576,7 @@ export const uploadFiles = async (
|
||||
formValues,
|
||||
filesObj,
|
||||
containerID,
|
||||
casefolderID
|
||||
casefolderID,
|
||||
) => {
|
||||
let files = filesObj;
|
||||
|
||||
@@ -1644,7 +1657,7 @@ export const uploadRepFiles = async (
|
||||
formValues,
|
||||
filesObj,
|
||||
containerID,
|
||||
casefolderID
|
||||
casefolderID,
|
||||
) => {
|
||||
let files = filesObj;
|
||||
|
||||
@@ -1721,7 +1734,7 @@ export const generateAppealPDF = async (
|
||||
containerID,
|
||||
casefolderID,
|
||||
appealType,
|
||||
fileList
|
||||
fileList,
|
||||
) => {
|
||||
//let files = filesObj;
|
||||
|
||||
@@ -1779,8 +1792,8 @@ export const getFilesFromBlob = (containerName, casefolderID) => {
|
||||
"/api/file/getbloblist?container=" +
|
||||
containerName +
|
||||
"&casefolderID=" +
|
||||
casefolderID
|
||||
)
|
||||
casefolderID,
|
||||
),
|
||||
)
|
||||
.then((res) => {
|
||||
//console.log("//////////----", res.data);
|
||||
@@ -1798,7 +1811,7 @@ export const getFilesFromBlobproxy = (containerName, casefolderID) => {
|
||||
"/api/file/getbloblistproxy?container=" +
|
||||
containerName +
|
||||
"&casefolderID=" +
|
||||
casefolderID
|
||||
casefolderID,
|
||||
)
|
||||
.then((res) => {
|
||||
//console.log("//////////----", res.data);
|
||||
@@ -1812,7 +1825,7 @@ export const getFilesFromBlobproxy = (containerName, casefolderID) => {
|
||||
export const getFilesFromBlobHashed = (
|
||||
containerName,
|
||||
getblobshash,
|
||||
casefolderID
|
||||
casefolderID,
|
||||
) => {
|
||||
return axios
|
||||
.get(
|
||||
@@ -1820,7 +1833,7 @@ export const getFilesFromBlobHashed = (
|
||||
containerName +
|
||||
"&casefolderID=" +
|
||||
casefolderID +
|
||||
getblobshash
|
||||
getblobshash,
|
||||
)
|
||||
.then((res) => {
|
||||
//console.log("//////////----", res.data);
|
||||
@@ -1835,7 +1848,7 @@ export const deleteBlob = async (
|
||||
containerName,
|
||||
blobName,
|
||||
deleteblobhash,
|
||||
casefolderID
|
||||
casefolderID,
|
||||
) => {
|
||||
try {
|
||||
const res = await axios.get(
|
||||
@@ -1845,7 +1858,7 @@ export const deleteBlob = async (
|
||||
encodeURIComponent(casefolderID) +
|
||||
"&blobname=" +
|
||||
encodeURIComponent(blobName) +
|
||||
deleteblobhash
|
||||
deleteblobhash,
|
||||
);
|
||||
return res.data;
|
||||
} catch (error) {
|
||||
@@ -1858,7 +1871,7 @@ export const deleteRepBlob = async (
|
||||
blobName,
|
||||
deleteblobhash,
|
||||
casefolderID,
|
||||
filenamePrefix
|
||||
filenamePrefix,
|
||||
) => {
|
||||
try {
|
||||
const res = await axios.get(
|
||||
@@ -1868,7 +1881,7 @@ export const deleteRepBlob = async (
|
||||
encodeURIComponent(casefolderID + "/" + filenamePrefix) +
|
||||
"&blobname=" +
|
||||
encodeURIComponent(blobName) +
|
||||
deleteblobhash
|
||||
deleteblobhash,
|
||||
);
|
||||
return res.data;
|
||||
} catch (error) {
|
||||
@@ -1884,14 +1897,14 @@ export const downloadBlob = (containerName, blobName) => {
|
||||
containerName.toLowerCase() +
|
||||
"&blobname=" +
|
||||
blobName,
|
||||
{ responseType: "blob" }
|
||||
{ responseType: "blob" },
|
||||
)
|
||||
.then((response) => {
|
||||
//console.log("Downloaded blob content:");
|
||||
|
||||
res.setHeader(
|
||||
"content-disposition",
|
||||
"attachment; filename=" + blobName
|
||||
"attachment; filename=" + blobName,
|
||||
);
|
||||
//console.log("has downloaded");
|
||||
|
||||
@@ -1928,8 +1941,8 @@ export const getProgressFromBlob = async (containerName, casereference) => {
|
||||
"/api/file/getprogressobjblob?container=" +
|
||||
encodeURIComponent(containerName) +
|
||||
"&casefolderID=" +
|
||||
encodeURIComponent(casereference)
|
||||
)
|
||||
encodeURIComponent(casereference),
|
||||
),
|
||||
);
|
||||
return res.data;
|
||||
} catch (error) {
|
||||
@@ -1941,7 +1954,7 @@ export const sendEmail = async (
|
||||
templateId,
|
||||
emailAddress,
|
||||
personalisation,
|
||||
reference
|
||||
reference,
|
||||
) => {
|
||||
var mailData = {
|
||||
"templateId": templateId,
|
||||
@@ -2042,7 +2055,7 @@ export const createContainerProxy = (containerName) => {
|
||||
export const sendCaseCompleteMessage = async (
|
||||
containerID,
|
||||
caseReference,
|
||||
inv
|
||||
inv,
|
||||
) => {
|
||||
var queryUrl =
|
||||
"/api/file/createappealcompletemessage_api?container=" +
|
||||
@@ -2071,7 +2084,7 @@ export const sendCaseCompleteMessage = async (
|
||||
|
||||
export const sendCaseCompleteMessageProxy = async (
|
||||
containerID,
|
||||
caseReference
|
||||
caseReference,
|
||||
) => {
|
||||
var queryUrl =
|
||||
"/api/file/createappealcompletemessageproxy_api?container=" +
|
||||
@@ -2098,7 +2111,7 @@ export const sendCaseCompleteMessageProxy = async (
|
||||
export const sendRepCompleteMessage = async (
|
||||
containerID,
|
||||
caseReference,
|
||||
fileName
|
||||
fileName,
|
||||
) => {
|
||||
var queryUrl =
|
||||
"/api/file/createrepcompletemessage_api?container=" +
|
||||
@@ -2210,7 +2223,7 @@ export const getPreferredLanguage = async (email) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getpreferredlanguage_api?emailAddress=" +
|
||||
email
|
||||
email,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -2226,7 +2239,7 @@ export const getAppealPDFDocument = async (incidentid) => {
|
||||
.get(
|
||||
BASE_URL +
|
||||
"/api/endpoint/getappealpdfdocuments_api?incidentid=" +
|
||||
incidentid
|
||||
incidentid,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -2251,7 +2264,7 @@ export const getNewAppealsPage = async (
|
||||
pageNumber,
|
||||
orderBy,
|
||||
fieldSort,
|
||||
showNumberOfRecords
|
||||
showNumberOfRecords,
|
||||
) => {
|
||||
return axios
|
||||
.get(
|
||||
@@ -2264,7 +2277,7 @@ export const getNewAppealsPage = async (
|
||||
"&fieldSort=" +
|
||||
fieldSort +
|
||||
"&showNumberOfRecords=" +
|
||||
showNumberOfRecords
|
||||
showNumberOfRecords,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
@@ -2282,7 +2295,7 @@ export const getNewDocumentsPaged = async (
|
||||
showNumberOfRecords,
|
||||
documentType,
|
||||
documentOrigin,
|
||||
selectedWeeks
|
||||
selectedWeeks,
|
||||
) => {
|
||||
console.log(
|
||||
"/api/admin/getlatestdocuments_api?pageNumber=" +
|
||||
@@ -2298,7 +2311,7 @@ export const getNewDocumentsPaged = async (
|
||||
"&numberWeeks=" +
|
||||
selectedWeeks +
|
||||
"&documentOrigin=" +
|
||||
documentOrigin
|
||||
documentOrigin,
|
||||
);
|
||||
return axios
|
||||
.get(
|
||||
@@ -2315,7 +2328,7 @@ export const getNewDocumentsPaged = async (
|
||||
"&numberWeeks=" +
|
||||
selectedWeeks +
|
||||
"&documentOrigin=" +
|
||||
documentOrigin
|
||||
documentOrigin,
|
||||
)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
|
||||
@@ -41,7 +41,9 @@ const Case = (props) => {
|
||||
docsOffline={props.props.docsOffline}
|
||||
documentDetailsObj={props.documentDetailsObj}
|
||||
showFilteredDocs={props.showFilteredDocs}
|
||||
showLoginCheck={props.showLoginCheck}
|
||||
eventsObj={props.eventsObj}
|
||||
mediaObj={props.mediaObj}
|
||||
/>
|
||||
{showRepresentations == true && (
|
||||
<RepresentationList
|
||||
|
||||
@@ -0,0 +1,646 @@
|
||||
// // import { setEventDetails } from "../../store/searchOutput/action";
|
||||
// // import { setCurrentPage } from "../../store/currentView/action";
|
||||
// // import { connect } from "react-redux";
|
||||
// // import useTranslation from "next-translate/useTranslation";
|
||||
// // import { formatDates } from "../utils";
|
||||
|
||||
// // const MediaDetails = (props) => {
|
||||
// // let { t } = useTranslation();
|
||||
|
||||
// // const MediaView = (mediaArr) => {
|
||||
// // mediaArr = mediaArr.value;
|
||||
|
||||
// // return mediaArr.map((item, key) => {
|
||||
// // <div>{item.pinswg_name}</div>;
|
||||
// // });
|
||||
// // };
|
||||
|
||||
// // const mediaArr = props.mediaObj?.value || [];
|
||||
|
||||
// // // event publishiing flag set to true displa
|
||||
|
||||
// // function hasOwnPropertyAndNotNull(obj, property) {
|
||||
// // return obj.hasOwnProperty(property) && obj[property] !== null;
|
||||
// // }
|
||||
|
||||
// // //console.log(eventsArr.length > 0);
|
||||
|
||||
// // return (
|
||||
// // mediaArr.length > 0 && (
|
||||
// // <div className="govuk-grid-row">
|
||||
// // <div className="card">
|
||||
// // <div className="card-body">
|
||||
// // <h2 className="govuk-heading-m ">
|
||||
// // {t("case:event-title")}Media
|
||||
// // </h2>
|
||||
// // {mediaArr.map(
|
||||
// // (item, key) =>
|
||||
// // item.pinswg_publishtoweb && (
|
||||
// // <>
|
||||
// // {" "}
|
||||
// // <div className="">
|
||||
// // <div className="">
|
||||
// // <div>
|
||||
// // <b>
|
||||
// // {" "}
|
||||
// // {t(
|
||||
// // "case:event-name-label",
|
||||
// // )}
|
||||
// // </b>
|
||||
// // : {item.pinswg_name}
|
||||
// // </div>
|
||||
// // {hasOwnPropertyAndNotNull(
|
||||
// // item,
|
||||
// // "pinswg_description",
|
||||
// // ) && (
|
||||
// // <div>
|
||||
// // <b>
|
||||
// // {t(
|
||||
// // "case:event-event-name-label",
|
||||
// // )}
|
||||
// // </b>
|
||||
// // :{" "}
|
||||
// // {
|
||||
// // item.pinswg_description
|
||||
// // }
|
||||
// // </div>
|
||||
// // )}
|
||||
// // </div>
|
||||
// // </div>
|
||||
// // </>
|
||||
// // ),
|
||||
// // )}{" "}
|
||||
// // </div>
|
||||
// // </div>
|
||||
// // </div>
|
||||
// // )
|
||||
// // );
|
||||
// // };
|
||||
|
||||
// // const mapStateToProps = (state) => {
|
||||
// // return {
|
||||
// // ...state,
|
||||
// // };
|
||||
// // };
|
||||
|
||||
// // const mapDispatchToProps = (dispatch) => {
|
||||
// // return {
|
||||
// // setEventDetails: (mediaObj) => {
|
||||
// // dispatch(setEventDetails(mediaObj));
|
||||
// // },
|
||||
// // setCurrentPage: (currentPage) => {
|
||||
// // dispatch(setCurrentPage(currentPage));
|
||||
// // },
|
||||
// // };
|
||||
// // };
|
||||
|
||||
// // export default connect(mapStateToProps, mapDispatchToProps)(MediaDetails);
|
||||
// import { useEffect, useMemo, useState } from "react";
|
||||
// import { connect } from "react-redux";
|
||||
// import useTranslation from "next-translate/useTranslation";
|
||||
// import { useRouter } from "next/router";
|
||||
|
||||
// const extractYouTubeId = (input) => {
|
||||
// if (!input) return null;
|
||||
// if (/^[a-zA-Z0-9_-]{11}$/.test(input)) return input;
|
||||
|
||||
// try {
|
||||
// const url = new URL(input);
|
||||
// if (url.hostname.includes("youtu.be"))
|
||||
// return url.pathname.slice(1) || null;
|
||||
|
||||
// const v = url.searchParams.get("v");
|
||||
// if (v) return v;
|
||||
|
||||
// const embedMatch = url.pathname.match(/\/embed\/([^/]+)/);
|
||||
// if (embedMatch?.[1]) return embedMatch[1];
|
||||
|
||||
// const shortsMatch = url.pathname.match(/\/shorts\/([^/]+)/);
|
||||
// if (shortsMatch?.[1]) return shortsMatch[1];
|
||||
|
||||
// return null;
|
||||
// } catch {
|
||||
// return null;
|
||||
// }
|
||||
// };
|
||||
|
||||
// export default function MediaDetails({ mediaObj, whichTab }) {
|
||||
// const router = useRouter();
|
||||
// const mediaArr = mediaObj?.value || [];
|
||||
|
||||
// const videoItems = useMemo(() => {
|
||||
// const isWelsh = router.locale === "cy";
|
||||
|
||||
// return (mediaArr || [])
|
||||
// .filter((x) => x?.pinswg_publishtoweb)
|
||||
// .map((item) => {
|
||||
// const url = isWelsh
|
||||
// ? item.pinswg_mediaLinkCY
|
||||
// : item.pinswg_mediaLinkEN;
|
||||
// const videoId = extractYouTubeId(url);
|
||||
// if (!videoId) return null;
|
||||
|
||||
// return {
|
||||
// key:
|
||||
// item.pinswg_documentid ||
|
||||
// `${item.pinswg_name}-${videoId}`,
|
||||
// videoId,
|
||||
// name: item.pinswg_name || "Video",
|
||||
// description: item.pinswg_description || "",
|
||||
// thumbnail: `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`,
|
||||
// };
|
||||
// })
|
||||
// .filter(Boolean);
|
||||
// }, [mediaArr, router.locale]);
|
||||
|
||||
// const [watchedIds, setWatchedIds] = useState(new Set());
|
||||
// const [selectedIndex, setSelectedIndex] = useState(0);
|
||||
|
||||
// // Forces a fresh iframe instance whenever we need to hard-stop playback
|
||||
// const [playerInstance, setPlayerInstance] = useState(0);
|
||||
|
||||
// const isActive = whichTab === "case-media";
|
||||
// const selected = videoItems[selectedIndex] || null;
|
||||
|
||||
// // When leaving the media tab, hard-stop playback by unmounting (and bumping instance)
|
||||
// useEffect(() => {
|
||||
// if (!isActive) {
|
||||
// setPlayerInstance((n) => n + 1);
|
||||
// }
|
||||
// }, [isActive]);
|
||||
|
||||
// // When list/locale changes, reset to first (no autoplay)
|
||||
// useEffect(() => {
|
||||
// setSelectedIndex(0);
|
||||
// setPlayerInstance((n) => n + 1);
|
||||
// }, [videoItems.length, router.locale]);
|
||||
|
||||
// if (!videoItems.length) return null;
|
||||
|
||||
// const embedBase = "https://www.youtube-nocookie.com/embed";
|
||||
|
||||
// // IMPORTANT:
|
||||
// // - autoplay=0 for initial load
|
||||
// // - autoplay=1 only when user clicks an item
|
||||
// const [autoplay, setAutoplay] = useState(false);
|
||||
|
||||
// useEffect(() => {
|
||||
// // whenever we leave tab or reset player, don't autoplay next time
|
||||
// if (!isActive) setAutoplay(false);
|
||||
// }, [isActive]);
|
||||
|
||||
// const embedSrc = selected
|
||||
// ? `${embedBase}/${selected.videoId}?rel=0&modestbranding=1&playsinline=1&autoplay=${autoplay ? "1" : "0"}`
|
||||
// : "";
|
||||
|
||||
// return (
|
||||
// <div className="govuk-grid-row">
|
||||
// <div className="card">
|
||||
// <div className="card-body">
|
||||
// <h2 className="govuk-heading-m">Media</h2>
|
||||
|
||||
// {/* Player: only render when tab is active */}
|
||||
// {isActive && (
|
||||
// <div className="videoWrapper govuk-!-margin-bottom-4">
|
||||
// <iframe
|
||||
// key={`${selected?.videoId}-${playerInstance}`}
|
||||
// src={embedSrc}
|
||||
// title={selected?.name || "YouTube video"}
|
||||
// frameBorder="0"
|
||||
// allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
// allowFullScreen
|
||||
// />
|
||||
// </div>
|
||||
// )}
|
||||
|
||||
// <h3 className="govuk-heading-s">Videos</h3>
|
||||
// <ul className="govuk-list govuk-list--spaced">
|
||||
// {videoItems.map((v, idx) => {
|
||||
// const isSelected = idx === selectedIndex;
|
||||
// return (
|
||||
// <li key={v.key}>
|
||||
// <button
|
||||
// type="button"
|
||||
// className={`videoTabButton ${isSelected ? "active" : ""}`}
|
||||
// onClick={() => {
|
||||
// setSelectedIndex(idx);
|
||||
// setAutoplay(true); // play only on user action
|
||||
// setPlayerInstance((n) => n + 1); // ensure clean switch / stop previous
|
||||
// setWatchedIds((prev) =>
|
||||
// new Set(prev).add(v.videoId),
|
||||
// );
|
||||
// }}
|
||||
// >
|
||||
// <div className="videoTabContent">
|
||||
// <div className="thumbnailWrapper">
|
||||
// <img
|
||||
// src={v.thumbnail}
|
||||
// alt=""
|
||||
// className="videoThumbnail"
|
||||
// loading="lazy"
|
||||
// />
|
||||
// <span
|
||||
// className="playIcon"
|
||||
// aria-hidden="true"
|
||||
// >
|
||||
// ▶
|
||||
// </span>
|
||||
|
||||
// {/* Duration badge (see section 2) */}
|
||||
// {v.duration && (
|
||||
// <span className="durationBadge">
|
||||
// {v.duration}
|
||||
// </span>
|
||||
// )}
|
||||
|
||||
// {/* Watched indicator (see section 3) */}
|
||||
// {watchedIds.has(v.videoId) && (
|
||||
// <span className="watchedBadge">
|
||||
// Watched
|
||||
// </span>
|
||||
// )}
|
||||
// </div>
|
||||
|
||||
// <span className="videoTitle">
|
||||
// {v.name}
|
||||
// </span>
|
||||
// </div>
|
||||
// </button>
|
||||
// </li>
|
||||
// );
|
||||
// })}
|
||||
// </ul>
|
||||
// </div>
|
||||
// </div>
|
||||
|
||||
// <style jsx>{`
|
||||
// .videoWrapper {
|
||||
// position: relative;
|
||||
// padding-bottom: 56.25%;
|
||||
// height: 0;
|
||||
// overflow: hidden;
|
||||
// border: 1px solid #b1b4b6;
|
||||
// border-radius: 4px;
|
||||
// }
|
||||
// .videoWrapper iframe {
|
||||
// position: absolute;
|
||||
// top: 0;
|
||||
// left: 0;
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
// }
|
||||
// .videoTabButton {
|
||||
// width: 100%;
|
||||
// text-align: left;
|
||||
// background: transparent;
|
||||
// border: 1px solid #b1b4b6;
|
||||
// border-radius: 4px;
|
||||
// padding: 10px 12px;
|
||||
// cursor: pointer;
|
||||
// }
|
||||
// .videoTabButton:hover {
|
||||
// background: #f3f2f1;
|
||||
// }
|
||||
// .videoTabButton.active {
|
||||
// border-color: #1d70b8;
|
||||
// box-shadow: inset 0 0 0 1px #1d70b8;
|
||||
// background: #eef4ff;
|
||||
// }
|
||||
// .videoTabContent {
|
||||
// display: flex;
|
||||
// gap: 12px;
|
||||
// align-items: center;
|
||||
// }
|
||||
|
||||
// .videoThumbnail {
|
||||
// width: 120px;
|
||||
// aspect-ratio: 16 / 9;
|
||||
// object-fit: cover;
|
||||
// border-radius: 4px;
|
||||
// border: 1px solid #b1b4b6;
|
||||
// background: #000;
|
||||
// }
|
||||
|
||||
// .videoTitle {
|
||||
// font-weight: 600;
|
||||
// }
|
||||
|
||||
// @media (max-width: 40.0625em) {
|
||||
// .videoThumbnail {
|
||||
// width: 90px;
|
||||
// }
|
||||
// }
|
||||
// .thumbnailWrapper {
|
||||
// position: relative;
|
||||
// width: 120px;
|
||||
// flex-shrink: 0;
|
||||
// }
|
||||
|
||||
// .videoThumbnail {
|
||||
// width: 100%;
|
||||
// aspect-ratio: 16 / 9;
|
||||
// object-fit: cover;
|
||||
// border-radius: 4px;
|
||||
// border: 1px solid #b1b4b6;
|
||||
// background: #000;
|
||||
// }
|
||||
|
||||
// /* ▶ Play icon */
|
||||
// .playIcon {
|
||||
// position: absolute;
|
||||
// inset: 0;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// justify-content: center;
|
||||
// font-size: 32px;
|
||||
// color: white;
|
||||
// text-shadow: 0 0 6px rgba(0, 0, 0, 0.7);
|
||||
// pointer-events: none;
|
||||
// }
|
||||
|
||||
// /* ⏱ Duration badge */
|
||||
// .durationBadge {
|
||||
// position: absolute;
|
||||
// bottom: 6px;
|
||||
// right: 6px;
|
||||
// background: rgba(0, 0, 0, 0.8);
|
||||
// color: white;
|
||||
// font-size: 12px;
|
||||
// padding: 2px 6px;
|
||||
// border-radius: 3px;
|
||||
// }
|
||||
|
||||
// /* 👁 Watched badge */
|
||||
// .watchedBadge {
|
||||
// position: absolute;
|
||||
// top: 6px;
|
||||
// left: 6px;
|
||||
// background: #00703c; /* GOV green */
|
||||
// color: white;
|
||||
// font-size: 11px;
|
||||
// padding: 2px 6px;
|
||||
// border-radius: 3px;
|
||||
// }
|
||||
|
||||
// .videoTabContent {
|
||||
// display: flex;
|
||||
// gap: 12px;
|
||||
// align-items: center;
|
||||
// }
|
||||
|
||||
// .videoTitle {
|
||||
// font-weight: 600;
|
||||
// }
|
||||
// `}</style>
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import useTranslation from "next-translate/useTranslation";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
/**
|
||||
* MediaDetails
|
||||
* - Renders a YouTube player + a list of videos from mediaObj.value
|
||||
* - Loads first item by default (no autoplay)
|
||||
* - Plays only when user selects an item
|
||||
* - Stops playback when leaving the "case-media" parent tab (pass whichTab)
|
||||
* - Shows thumbnail with play overlay
|
||||
* - Optional duration badge (if you supply v.duration)
|
||||
* - "Watched" badge once a video has been played (session only)
|
||||
*/
|
||||
|
||||
const extractYouTubeId = (input) => {
|
||||
if (!input) return null;
|
||||
|
||||
// Already looks like a YouTube ID?
|
||||
if (/^[a-zA-Z0-9_-]{11}$/.test(input)) return input;
|
||||
|
||||
try {
|
||||
const url = new URL(input);
|
||||
|
||||
// youtu.be/<id>
|
||||
if (url.hostname.includes("youtu.be")) {
|
||||
return url.pathname.replace("/", "") || null;
|
||||
}
|
||||
|
||||
// youtube.com/watch?v=<id>
|
||||
const v = url.searchParams.get("v");
|
||||
if (v) return v;
|
||||
|
||||
// youtube.com/embed/<id>
|
||||
const embedMatch = url.pathname.match(/\/embed\/([^/]+)/);
|
||||
if (embedMatch?.[1]) return embedMatch[1];
|
||||
|
||||
// youtube.com/shorts/<id>
|
||||
const shortsMatch = url.pathname.match(/\/shorts\/([^/]+)/);
|
||||
if (shortsMatch?.[1]) return shortsMatch[1];
|
||||
|
||||
return null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const MediaDetails = ({ mediaObj, whichTab, title, useNoCookie = true }) => {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
|
||||
const mediaArr = mediaObj?.value || [];
|
||||
const isActive = whichTab ? whichTab === "case-media" : true;
|
||||
|
||||
// Build list of playable items (publishable only)
|
||||
const videoItems = useMemo(() => {
|
||||
const isWelsh = router.locale === "cy";
|
||||
|
||||
return (mediaArr || [])
|
||||
.filter((x) => x?.pinswg_publishtoweb)
|
||||
.map((item) => {
|
||||
const link = isWelsh
|
||||
? item.pinswg_mediaLinkCY
|
||||
: item.pinswg_mediaLinkEN;
|
||||
|
||||
const videoId = extractYouTubeId(link);
|
||||
if (!videoId) return null;
|
||||
|
||||
return {
|
||||
key:
|
||||
item.pinswg_documentid ||
|
||||
item.pinswg_mediaid ||
|
||||
`${item.pinswg_name}-${videoId}`,
|
||||
videoId,
|
||||
name: item.pinswg_name || "Video",
|
||||
description: item.pinswg_description || "",
|
||||
// If you later store duration in CRM, map it here (e.g. "03:42")
|
||||
duration: item.pinswg_duration || null,
|
||||
thumbnailHQ: `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`,
|
||||
thumbnailMax: `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`,
|
||||
raw: item,
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
}, [mediaArr, router.locale]);
|
||||
|
||||
const [selectedIndex, setSelectedIndex] = useState(0);
|
||||
|
||||
// Default false so first item loads but does not play.
|
||||
const [autoplay, setAutoplay] = useState(false);
|
||||
|
||||
// Bump this to force iframe remount (hard stop playback).
|
||||
const [playerInstance, setPlayerInstance] = useState(0);
|
||||
|
||||
// Track which videos have been played (session only).
|
||||
const [watchedIds, setWatchedIds] = useState(() => new Set());
|
||||
|
||||
// When list or locale changes: reset selection and do not autoplay
|
||||
useEffect(() => {
|
||||
setSelectedIndex(0);
|
||||
setAutoplay(false);
|
||||
setPlayerInstance((n) => n + 1);
|
||||
}, [videoItems.length, router.locale]);
|
||||
|
||||
// When leaving the media tab: hard stop playback
|
||||
useEffect(() => {
|
||||
if (!isActive) {
|
||||
setAutoplay(false);
|
||||
setPlayerInstance((n) => n + 1);
|
||||
}
|
||||
}, [isActive]);
|
||||
|
||||
const selected = videoItems[selectedIndex] || null;
|
||||
|
||||
const domain = useNoCookie
|
||||
? "https://www.youtube-nocookie.com"
|
||||
: "https://www.youtube.com";
|
||||
|
||||
const embedSrc = selected
|
||||
? `${domain}/embed/${selected.videoId}?rel=0&modestbranding=1&playsinline=1&autoplay=${
|
||||
autoplay ? "1" : "0"
|
||||
}`
|
||||
: "";
|
||||
|
||||
if (!videoItems.length) return null;
|
||||
|
||||
return (
|
||||
<div className="govuk-grid-row">
|
||||
<div className="card">
|
||||
<div className="card-body">
|
||||
<h2 className="govuk-heading-m">{t("case:media-title")}</h2>
|
||||
|
||||
{/* Player: unmount when not active (guarantees playback stops) */}
|
||||
{isActive && (
|
||||
<div className="videoWrapper govuk-!-margin-bottom-4">
|
||||
<iframe
|
||||
key={`${selected?.videoId}-${playerInstance}`}
|
||||
src={embedSrc}
|
||||
title={selected?.name || "YouTube video"}
|
||||
frameBorder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Selected info */}
|
||||
{selected && (
|
||||
<div className="govuk-!-margin-bottom-4">
|
||||
<div className="govuk-body">
|
||||
<b>{t("case:event-name-label")}</b>:{" "}
|
||||
{selected.name}
|
||||
</div>
|
||||
|
||||
{!!selected.description && (
|
||||
<div className="govuk-body">
|
||||
<b>{t("case:event-event-name-label")}</b>:{" "}
|
||||
{selected.description}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Video list */}
|
||||
<h3 className="govuk-heading-s">
|
||||
{t("case:video-heading")}
|
||||
</h3>
|
||||
|
||||
<ul className="govuk-list govuk-list--spaced">
|
||||
{videoItems.map((v, idx) => {
|
||||
const isSelected = idx === selectedIndex;
|
||||
|
||||
return (
|
||||
<li key={v.key}>
|
||||
<button
|
||||
type="button"
|
||||
className={`videoTabButton ${
|
||||
isSelected ? "active" : ""
|
||||
}`}
|
||||
aria-current={
|
||||
isSelected ? "true" : undefined
|
||||
}
|
||||
onClick={() => {
|
||||
setSelectedIndex(idx);
|
||||
|
||||
// Start playback only when user selects
|
||||
setAutoplay(true);
|
||||
|
||||
// Force remount to stop previous + start clean
|
||||
setPlayerInstance((n) => n + 1);
|
||||
|
||||
// Mark watched
|
||||
setWatchedIds((prev) => {
|
||||
const next = new Set(prev);
|
||||
next.add(v.videoId);
|
||||
return next;
|
||||
});
|
||||
}}
|
||||
>
|
||||
<div className="videoTabContent">
|
||||
<div className="thumbnailWrapper">
|
||||
<img
|
||||
src={v.thumbnailMax}
|
||||
onError={(e) => {
|
||||
// fallback for videos without maxres
|
||||
e.currentTarget.src =
|
||||
v.thumbnailHQ;
|
||||
}}
|
||||
alt=""
|
||||
className="videoThumbnail"
|
||||
loading="lazy"
|
||||
/>
|
||||
<span
|
||||
className="playIcon"
|
||||
aria-hidden="true"
|
||||
>
|
||||
▶
|
||||
</span>
|
||||
|
||||
{!!v.duration && (
|
||||
<span className="durationBadge">
|
||||
{v.duration}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{watchedIds.has(v.videoId) && (
|
||||
<span className="watchedBadge">
|
||||
Watched
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<span className="videoTitle">
|
||||
{v.name}
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MediaDetails;
|
||||
@@ -8,6 +8,7 @@ import { connect } from "react-redux";
|
||||
import transLookup from "../../data/lookuptranslations.json";
|
||||
import Documents from "./documents";
|
||||
import EventsDetails from "./events";
|
||||
import MediaDetails from "./media";
|
||||
|
||||
import {
|
||||
createWatchedCases,
|
||||
@@ -81,8 +82,10 @@ const CaseSummary = (props) => {
|
||||
ticketnumber,
|
||||
} = props;
|
||||
|
||||
const showLoginCheck =
|
||||
currentType == "directResultsObj" ? "true" : currentView.showLogin;
|
||||
// const showLoginCheck =
|
||||
// currentType == "directResultsObj" ? "true" : currentView.showLogin;
|
||||
|
||||
let showLoginCheck = props.showLoginCheck;
|
||||
const { data: session, status } = useSession();
|
||||
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
@@ -416,7 +419,7 @@ const CaseSummary = (props) => {
|
||||
>
|
||||
<a
|
||||
className="govuk-tabs__tab"
|
||||
href="#case-events"
|
||||
href="#case-eia"
|
||||
onClick={() => setWhichTab("case-eia")}
|
||||
>
|
||||
{" "}
|
||||
@@ -444,6 +447,26 @@ const CaseSummary = (props) => {
|
||||
</a>
|
||||
</li>
|
||||
)}
|
||||
{isObjectNotEmpty(props, "mediaObj") && (
|
||||
<li
|
||||
className={
|
||||
whichTab == "case-media"
|
||||
? "govuk-tabs__list-item govuk-tabs__list-item--selected"
|
||||
: "govuk-tabs__list-item "
|
||||
}
|
||||
>
|
||||
<a
|
||||
className="govuk-tabs__tab"
|
||||
href="#case-media"
|
||||
onClick={() =>
|
||||
setWhichTab("case-media")
|
||||
}
|
||||
>
|
||||
{" "}
|
||||
{t("case:summary-tab-media-label")}{" "}
|
||||
</a>
|
||||
</li>
|
||||
)}
|
||||
<li
|
||||
className={
|
||||
whichTab == "case-documents"
|
||||
@@ -1741,6 +1764,22 @@ const CaseSummary = (props) => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isObjectNotEmpty(props, "mediaObj") && (
|
||||
<div
|
||||
className={
|
||||
whichTab == "case-media"
|
||||
? "govuk-tabs__panel "
|
||||
: "govuk-tabs__panel govuk-tabs__panel--hidden"
|
||||
}
|
||||
id="case-media"
|
||||
>
|
||||
<MediaDetails
|
||||
mediaObj={props.mediaObj}
|
||||
whichTab={whichTab}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
className={
|
||||
whichTab == "case-documents"
|
||||
|
||||
@@ -64,6 +64,7 @@ const Header = (props) => {
|
||||
"/myportal/contactus",
|
||||
"/unsubscribe/[watchlistid]",
|
||||
"/unsubscribeall/[watchlistid]",
|
||||
"/status",
|
||||
];
|
||||
|
||||
const hasContactLink = [
|
||||
@@ -84,14 +85,14 @@ const Header = (props) => {
|
||||
|
||||
const handleLogout = () => {
|
||||
console.info("////////////\n" + "logout" + "\n////////////");
|
||||
window.localStorage.clear(),
|
||||
(window.localStorage.clear(),
|
||||
destroyCookie(null, "next-auth.csrf-token", { path: "/" }),
|
||||
destroyCookie(null, "next-auth.callback-url", { path: "/" }),
|
||||
destroyCookie(null, "pedw_locale", { path: "/" }),
|
||||
destroyCookie(null, "pinsUser", { path: "/" }),
|
||||
signOut({
|
||||
callbackUrl: locale == "cy" ? "/cy/allgofnodi" : "/logout",
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
//const switchLocale = locale === "en" ? "cy" : "en";
|
||||
|
||||
+3
-1
@@ -24,8 +24,10 @@ const MainHome = (props) => {
|
||||
<div className="flex-container grid-row govuk-body ">
|
||||
{showLogin != "true" && (
|
||||
<>
|
||||
<LoginSoon />
|
||||
{/* <LoginSoon />
|
||||
<CaseSearch /> */}
|
||||
<CaseSearch />
|
||||
<Login session={session} siteurl={siteurl} />
|
||||
</>
|
||||
)}
|
||||
{showLogin == "true" && (
|
||||
|
||||
+98
-26
@@ -1,46 +1,118 @@
|
||||
import useTranslation from "next-translate/useTranslation";
|
||||
import router from "next/router";
|
||||
import Link from "next/link";
|
||||
import CaseNoticeBanner from "./case/caseNoticeBanner";
|
||||
|
||||
export default function ServiceBanner(props) {
|
||||
let { t, lang } = useTranslation();
|
||||
|
||||
const showSigninFromEnv = true;
|
||||
const showNoticeFromEnv = false;
|
||||
|
||||
// keep backwards-compat with existing usage
|
||||
const showSignin = props?.noSignin === true ? false : showSigninFromEnv;
|
||||
|
||||
const signInButton = () => {
|
||||
router.push(
|
||||
`${
|
||||
router.locale == "cy" ? "/awd/mewngofnodi" : "/auth/signin"
|
||||
}?callbackUrl=${encodeURIComponent(
|
||||
window.location.href
|
||||
)}&error=EmailSignin`
|
||||
window.location.href,
|
||||
)}&error=EmailSignin`,
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div className="servicebanner">
|
||||
<h1>
|
||||
<img
|
||||
className={
|
||||
router.locale == "cy"
|
||||
? "govuk-!-margin-top-4 serviceTitle cy"
|
||||
: "govuk-!-margin-top-4 serviceTitle"
|
||||
}
|
||||
src={
|
||||
router.locale == "cy"
|
||||
? "/assets/images/planning-casework-cy.svg"
|
||||
: "/assets/images/planning-casework-en.svg"
|
||||
}
|
||||
alt="Planning casework"
|
||||
/>
|
||||
</h1>
|
||||
{props.noSignin != true && (
|
||||
<div className="serviceBanner_userDetails">
|
||||
<button
|
||||
onClick={() => signInButton()}
|
||||
className="govuk-header__link "
|
||||
<>
|
||||
<div className="servicebanner">
|
||||
<h1>
|
||||
<img
|
||||
className={
|
||||
router.locale == "cy"
|
||||
? "govuk-!-margin-top-4 serviceTitle cy"
|
||||
: "govuk-!-margin-top-4 serviceTitle"
|
||||
}
|
||||
src={
|
||||
router.locale == "cy"
|
||||
? "/assets/images/planning-casework-cy.svg"
|
||||
: "/assets/images/planning-casework-en.svg"
|
||||
}
|
||||
alt="Planning casework"
|
||||
/>
|
||||
</h1>
|
||||
|
||||
{showSignin && props.noSignin != true && (
|
||||
<div className="serviceBanner_userDetails">
|
||||
<button
|
||||
onClick={() => signInButton()}
|
||||
className="govuk-header__link "
|
||||
>
|
||||
{t("common:signin-label")}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{showNoticeFromEnv && (
|
||||
<div>
|
||||
<div
|
||||
className="govuk-warning-text noticebanner govuk-!-margin-bottom-0"
|
||||
key={1}
|
||||
>
|
||||
{t("common:signin-label")}
|
||||
</button>
|
||||
<strong className="govuk-warning-text__text">
|
||||
<span className="govuk-visually-hidden">
|
||||
Announcement
|
||||
</span>
|
||||
</strong>
|
||||
<div>
|
||||
<div className=" govuk-body-s">
|
||||
<h2 className="govuk-heading-s">
|
||||
{router.locale == "cy"
|
||||
? "Cyhoeddiad"
|
||||
: "Announcement"}
|
||||
</h2>
|
||||
</div>
|
||||
<div className="govuk-body-s">
|
||||
{router.locale == "cy" ? (
|
||||
<>
|
||||
<p>
|
||||
Oherwydd gwaith cynnal a chadw
|
||||
hanfodol, rydym yn disgwyl rhywfaint
|
||||
o darfu ar ein gwasanaethau Porth
|
||||
Gwaith Achos rhwng 9-13 Chwefror
|
||||
2026.{" "}
|
||||
</p>
|
||||
<p>
|
||||
Ymddiheurwn am yr anghyfleustra. Am
|
||||
ymholiadau brys yn ystod y cyfnod
|
||||
hwn, cysylltwch â{" "}
|
||||
<a href="mailto:pedw.gwaithachos@llyw.cymru">
|
||||
pedw.gwaithachos@llyw.cymru
|
||||
</a>
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p>
|
||||
Due to essential maintenance, we are
|
||||
expecting some disruption to our
|
||||
Casework Portal services between
|
||||
9-13 February 2026.
|
||||
</p>
|
||||
<p>
|
||||
We apologise for the inconvenience.
|
||||
For urgent enquries during this time
|
||||
please contact{" "}
|
||||
<a href="mailto:pedw.casework@gov.wales">
|
||||
pedw.casework@gov.wales
|
||||
</a>
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"summary-tab-map-label": " Map",
|
||||
"summary-tab-events-label": " Digwyddiadau",
|
||||
"summary-tab-documents-label": "Dogfennau",
|
||||
"summary-tab-media-label": "Cyfryngau",
|
||||
"summary-reference-label": "Cyfeirnod",
|
||||
"summary-applicant-label": "Apelydd",
|
||||
"summary-applicantonly-label": "Ymgeisydd",
|
||||
@@ -139,5 +140,7 @@
|
||||
"summary-reporting-decision-sub-title": "Adrodd/Penderfyniad",
|
||||
"summary-report-issued-to-welsh-ministers": "Adroddiad a Gyhoeddwyd i Weinidogion Cymru",
|
||||
"summary-decision-issued-to-applicant": "Penderfyniad a Gyhoeddwyd i'r Ymgeisydd",
|
||||
"summary-decision-outcome": "Canlyniad y Penderfyniad"
|
||||
"summary-decision-outcome": "Canlyniad y Penderfyniad",
|
||||
"media-title": "Cyfryngau",
|
||||
"video-heading": "Fideos"
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
"summary-tab-map-label": "Map",
|
||||
"summary-tab-events-label": "Events",
|
||||
"summary-tab-documents-label": "Documents",
|
||||
"summary-tab-media-label": "Media",
|
||||
"summary-reference-label": "Reference",
|
||||
"summary-applicant-label": "Appellant",
|
||||
"summary-applicantonly-label": "Applicant",
|
||||
@@ -140,5 +141,7 @@
|
||||
"summary-reporting-decision-sub-title": "Reporting/Decision",
|
||||
"summary-report-issued-to-welsh-ministers": "Report Issued to Welsh Ministers",
|
||||
"summary-decision-issued-to-applicant": "Decision Issued to Applicant",
|
||||
"summary-decision-outcome": "Decision Outcome"
|
||||
"summary-decision-outcome": "Decision Outcome",
|
||||
"media-title": "Media",
|
||||
"video-heading": "Fideos"
|
||||
}
|
||||
+6
-6
@@ -9,12 +9,12 @@ export function middleware(request) {
|
||||
process.env.NODE_ENV === "production" ? "" : `'unsafe-eval'`
|
||||
};
|
||||
style-src 'self' 'unsafe-eval' 'unsafe-inline';
|
||||
img-src 'self' 'unsafe-inline' https://www.gov.wales https://gov.wales https://fonts.gstatic.com https://www.googletagmanager.com blob: data:;
|
||||
img-src 'self' 'unsafe-inline' https://www.gov.wales https://gov.wales https://fonts.gstatic.com https://www.googletagmanager.com blob: data: https://img.youtube.com;
|
||||
connect-src 'self' http://127.0.0.1 https://uksouth-1.in.applicationinsights.azure.com https://ukwest-0.in.applicationinsights.azure.com https://js.monitor.azure.com https://region1.google-analytics.com;
|
||||
font-src 'self' https://pro.fontawesome.com/ https://fonts.gstatic.com/ ;
|
||||
object-src 'none';
|
||||
base-uri 'self';
|
||||
frame-src https://datamap.gov.wales/;
|
||||
frame-src https://datamap.gov.wales/ https://www.youtube.com https://www.youtube-nocookie.com;
|
||||
form-action 'self' ` +
|
||||
process.env.NEXTAUTH_URL +
|
||||
`;
|
||||
@@ -49,7 +49,7 @@ export function middleware(request) {
|
||||
// CSP policy
|
||||
requestHeaders.set(
|
||||
"Content-Security-Policy",
|
||||
contentSecurityPolicyHeaderValue
|
||||
contentSecurityPolicyHeaderValue,
|
||||
);
|
||||
|
||||
const response = NextResponse.next({
|
||||
@@ -59,7 +59,7 @@ export function middleware(request) {
|
||||
});
|
||||
response.headers.set(
|
||||
"Content-Security-Policy",
|
||||
contentSecurityPolicyHeaderValue
|
||||
contentSecurityPolicyHeaderValue,
|
||||
);
|
||||
|
||||
// XSS protection (legacy)
|
||||
@@ -77,13 +77,13 @@ export function middleware(request) {
|
||||
// Permissions lockdown
|
||||
response.headers.set(
|
||||
"Permissions-Policy",
|
||||
"geolocation=(), camera=(), microphone=(), fullscreen=(self)"
|
||||
"geolocation=(), camera=(), microphone=(), fullscreen=(self)",
|
||||
);
|
||||
|
||||
// Enforce HTTPS via HSTS
|
||||
response.headers.set(
|
||||
"Strict-Transport-Security",
|
||||
"max-age=63072000; includeSubDomains; preload"
|
||||
"max-age=63072000; includeSubDomains; preload",
|
||||
);
|
||||
|
||||
return response;
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
import axios from "axios";
|
||||
import CryptoJS from "crypto-js";
|
||||
import { azureHeaders, consoleLogger, getToken } from "../../../actions";
|
||||
|
||||
const WORDKEY = process.env.HASHKEY;
|
||||
|
||||
const WEBAPI_URL =
|
||||
process.env.RELAY_ROOT ||
|
||||
"https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/";
|
||||
|
||||
const hashAPIPath = (queryPath) => {
|
||||
var hashlink = CryptoJS.HmacSHA256(
|
||||
queryPath,
|
||||
CryptoJS.enc.Hex.parse(WORDKEY),
|
||||
);
|
||||
hashlink = hashlink.toString(CryptoJS.enc.Hex);
|
||||
|
||||
//return "&hash=" + hashlink;
|
||||
|
||||
return (queryPath.indexOf("?") > -1 ? "&hash=" : "?hash=") + hashlink;
|
||||
};
|
||||
|
||||
// export default async function ApiProxy(req, res) {
|
||||
// var caseid = req.query.caseid;
|
||||
// var token = await getToken();
|
||||
|
||||
// var queryUrl =
|
||||
// "pinswg_sipsevents?$filter=_pinswg_sipseventsid_value eq " +
|
||||
// caseid +
|
||||
// "&$count=true";
|
||||
|
||||
// return axios
|
||||
// .get(
|
||||
// WEBAPI_URL + queryUrl + hashAPIPath(queryUrl),
|
||||
// azureHeaders(token.access_token),
|
||||
// )
|
||||
// .then(({ data }) => {
|
||||
// res.status(200).json(data);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// consoleLogger(error);
|
||||
// res.status(400).json(error);
|
||||
// });
|
||||
// }
|
||||
|
||||
export default function ApiProx(req, res) {
|
||||
const data = {
|
||||
"@odata.count": 4,
|
||||
"value": [
|
||||
{
|
||||
"pinswg_publishtoweb@OData.Community.Display.V1.FormattedValue":
|
||||
"Yes",
|
||||
"pinswg_publishtoweb": true,
|
||||
"pinswg_uploadstatus": 846040000,
|
||||
"pinswg_name":
|
||||
"Puffin Paradise? Exploring Wales’ Cutest Wildlife Spot (Skomer Travel Guide)",
|
||||
"pinswg_description":
|
||||
"Skomer Island is a tiny uninhabited isle off the coast of Pembrokeshire in western Wales. Although it's just ten minutes from the mainland by ferry, it's home to over 40,000 puffins, the largest colony in the world of Manx Shearwaters, and lots of seals.",
|
||||
"pinswg_latestpublishedversion": "1.0",
|
||||
"pinswg_latestpublisheddate@OData.Community.Display.V1.FormattedValue":
|
||||
"2/2/2026",
|
||||
"pinswg_latestpublisheddate": "2026-02-02T10:20:46Z",
|
||||
"pinswg_documentpublisheddate": "2026-02-02T10:20:46Z",
|
||||
"pinswg_documentid": "9d4550b7-2000-f111-aa10-002248008e24",
|
||||
"createdon@OData.Community.Display.V1.FormattedValue":
|
||||
"2/2/2026 10:19 AM",
|
||||
"createdon": "2026-02-02T10:19:55Z",
|
||||
"pinswg_hashlink":
|
||||
"/api/documents/download/A22258739?hash=51d64c1330ed2fe1fb9aff4658b8eedadf1b062d2b0313b39bc5af786228324b",
|
||||
"pinswg_mediaLinkEN":
|
||||
"https://www.youtube.com/watch?v=H7S6CfF_7PI",
|
||||
"pinswg_mediaLinkCY":
|
||||
"https://www.youtube.com/watch?v=H7S6CfF_7PI",
|
||||
},
|
||||
{
|
||||
"pinswg_publishtoweb@OData.Community.Display.V1.FormattedValue":
|
||||
"Yes",
|
||||
"pinswg_publishtoweb": true,
|
||||
"pinswg_uploadstatus": 846040000,
|
||||
"pinswg_name": "Redstone Cross - side roads",
|
||||
"pinswg_description": "Redstone Cross - side roads",
|
||||
"pinswg_latestpublishedversion": "1.0",
|
||||
"pinswg_latestpublisheddate@OData.Community.Display.V1.FormattedValue":
|
||||
"2/2/2026",
|
||||
"pinswg_latestpublisheddate": "2026-02-02T10:20:46Z",
|
||||
"pinswg_documentpublisheddate": "2026-02-02T10:20:46Z",
|
||||
"pinswg_documentid": "9d4550b7-2000-f111-aa10-002248008e24",
|
||||
"createdon@OData.Community.Display.V1.FormattedValue":
|
||||
"2/2/2026 10:19 AM",
|
||||
"createdon": "2026-02-02T10:19:55Z",
|
||||
"pinswg_hashlink":
|
||||
"/api/documents/download/A22258739?hash=51d64c1330ed2fe1fb9aff4658b8eedadf1b062d2b0313b39bc5af786228324b",
|
||||
"pinswg_mediaLinkEN":
|
||||
"https://www.youtube.com/watch?v=OhxeLV_jPyE",
|
||||
"pinswg_mediaLinkCY":
|
||||
"https://www.youtube.com/watch?v=OhxeLV_jPyE",
|
||||
},
|
||||
{
|
||||
"pinswg_publishtoweb@OData.Community.Display.V1.FormattedValue":
|
||||
"Yes",
|
||||
"pinswg_publishtoweb": true,
|
||||
"pinswg_uploadstatus": 846040000,
|
||||
"pinswg_name":
|
||||
"Apprenticeships: Dinorwig Power Station (bilingual)",
|
||||
"pinswg_description": "blah blah blah",
|
||||
"pinswg_latestpublishedversion": "1.0",
|
||||
"pinswg_latestpublisheddate@OData.Community.Display.V1.FormattedValue":
|
||||
"2/2/2026",
|
||||
"pinswg_latestpublisheddate": "2026-02-02T10:20:46Z",
|
||||
"pinswg_documentpublisheddate": "2026-02-02T10:20:46Z",
|
||||
"pinswg_documentid": "9d4550b7-2000-f111-aa10-002248008e24",
|
||||
"createdon@OData.Community.Display.V1.FormattedValue":
|
||||
"2/2/2026 10:19 AM",
|
||||
"createdon": "2026-02-02T10:19:55Z",
|
||||
"pinswg_hashlink":
|
||||
"/api/documents/download/A22258739?hash=51d64c1330ed2fe1fb9aff4658b8eedadf1b062d2b0313b39bc5af786228324b",
|
||||
"pinswg_mediaLinkEN":
|
||||
"https://www.youtube.com/watch?v=9nsmadjgW94",
|
||||
"pinswg_mediaLinkCY":
|
||||
"https://www.youtube.com/watch?v=9nsmadjgW94",
|
||||
},
|
||||
{
|
||||
"pinswg_publishtoweb@OData.Community.Display.V1.FormattedValue":
|
||||
"Yes",
|
||||
"pinswg_publishtoweb": true,
|
||||
"pinswg_uploadstatus": 846040000,
|
||||
"pinswg_name":
|
||||
"Climate Action Wales - Cardiff Cycle Workshop - Sustainable Cycling in Cardiff",
|
||||
"pinswg_description": "blah blah blah",
|
||||
"pinswg_latestpublishedversion": "1.0",
|
||||
"pinswg_latestpublisheddate@OData.Community.Display.V1.FormattedValue":
|
||||
"2/2/2026",
|
||||
"pinswg_latestpublisheddate": "2026-02-02T10:20:46Z",
|
||||
"pinswg_documentpublisheddate": "2026-02-02T10:20:46Z",
|
||||
"pinswg_documentid": "9d4550b7-2000-f111-aa10-002248008e24",
|
||||
"createdon@OData.Community.Display.V1.FormattedValue":
|
||||
"2/2/2026 10:19 AM",
|
||||
"createdon": "2026-02-02T10:19:55Z",
|
||||
"pinswg_hashlink":
|
||||
"/api/documents/download/A22258739?hash=51d64c1330ed2fe1fb9aff4658b8eedadf1b062d2b0313b39bc5af786228324b",
|
||||
"pinswg_mediaLinkEN":
|
||||
"https://www.youtube.com/watch?v=tRW3tm2Mby8",
|
||||
"pinswg_mediaLinkCY":
|
||||
"https://www.youtube.com/watch?v=tRW3tm2Mby8",
|
||||
},
|
||||
],
|
||||
};
|
||||
return res.status(200).json(data);
|
||||
}
|
||||
+10
-8
@@ -84,7 +84,9 @@ const SignIn = (props) => {
|
||||
<div className="govuk-body-m">
|
||||
<legend className="govuk-fieldset__legend govuk-fieldset__legend--l">
|
||||
<h1 className="govuk-fieldset__heading govuk-heading-m">
|
||||
{t("auth:auth-page-title")}{" "}
|
||||
{t(
|
||||
"auth:auth-page-title",
|
||||
)}{" "}
|
||||
</h1>
|
||||
</legend>
|
||||
|
||||
@@ -122,7 +124,7 @@ const SignIn = (props) => {
|
||||
htmlFor="email"
|
||||
>
|
||||
{t(
|
||||
"auth:auth-email-label"
|
||||
"auth:auth-email-label",
|
||||
)}
|
||||
</label>
|
||||
|
||||
@@ -142,7 +144,7 @@ const SignIn = (props) => {
|
||||
}
|
||||
>
|
||||
{t(
|
||||
"auth:auth-signin-button-label"
|
||||
"auth:auth-signin-button-label",
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
@@ -163,10 +165,10 @@ const SignIn = (props) => {
|
||||
};
|
||||
|
||||
export async function getServerSideProps(context) {
|
||||
if (process.env.SHOWLOGIN == false) {
|
||||
if (process.env.SHOWLOGIN === "false" || process.env.SHOWLOGIN === false) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: "/404",
|
||||
destination: "/status",
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
@@ -177,7 +179,7 @@ export async function getServerSideProps(context) {
|
||||
"\n//////////////////////\n",
|
||||
"Sign in callbackurl: " + context.query.callbackUrl,
|
||||
context.locale,
|
||||
"\n//////////////////////\n"
|
||||
"\n//////////////////////\n",
|
||||
);
|
||||
let formURL = context.req.headers.host;
|
||||
//console.log("formUrl:", formURL);
|
||||
@@ -207,7 +209,7 @@ export async function getServerSideProps(context) {
|
||||
|
||||
// Append the query parameters to the new URL
|
||||
params.forEach((value, key) =>
|
||||
toUrlObj.searchParams.append(key, value)
|
||||
toUrlObj.searchParams.append(key, value),
|
||||
);
|
||||
|
||||
return toUrlObj.toString(); // Return the full new URL as a string
|
||||
@@ -216,7 +218,7 @@ export async function getServerSideProps(context) {
|
||||
typeof context.query.callbackUrl != "undefined" &&
|
||||
(formURL = appendParamsAndPathToNewUrl(
|
||||
context.query.callbackUrl,
|
||||
formURL
|
||||
formURL,
|
||||
));
|
||||
|
||||
//formURL = appendParamsAndPathToNewUrl(context.query.callbackUrl, formURL);
|
||||
|
||||
@@ -236,10 +236,10 @@ export async function getServerSideProps(context) {
|
||||
};
|
||||
}
|
||||
|
||||
if (process.env.SHOWLOGIN == false) {
|
||||
if (process.env.SHOWLOGIN === "false" || process.env.SHOWLOGIN === false) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: "/404",
|
||||
destination: "/status",
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
@@ -250,7 +250,7 @@ export async function getServerSideProps(context) {
|
||||
"\n//////////////////////\n",
|
||||
"Sign in callbackurl: " + context.req.headers.host,
|
||||
context.locale,
|
||||
csrfToken + "\n//////////////////////\n"
|
||||
csrfToken + "\n//////////////////////\n",
|
||||
);
|
||||
let formURL = context.req.headers.host;
|
||||
console.log("formUrl:", formURL);
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
getPersonalAccount,
|
||||
getPortalLogin,
|
||||
getSIPSEvents,
|
||||
getSIPSMedia,
|
||||
} from "../../actions";
|
||||
import Breadcrumbs from "../../components/breadcrumbs";
|
||||
import Case from "../../components/case";
|
||||
@@ -24,6 +25,7 @@ import {
|
||||
setEventDetails,
|
||||
setSearchDetails,
|
||||
setSearchResults,
|
||||
setMediaDetails,
|
||||
} from "../../store/searchOutput/action";
|
||||
import { wrapper } from "../../store/store";
|
||||
import ServiceBanner from "../../components/servicebanner";
|
||||
@@ -104,11 +106,12 @@ const CaseHome = (props) => {
|
||||
representationsObj={
|
||||
props.searchResultsObj.representationsObj
|
||||
}
|
||||
showLoginCheck={true}
|
||||
showLoginCheck={props.showLoginCheck}
|
||||
messagesObj={props.messagesObj}
|
||||
showFilteredDocs={props.showFilteredDocs}
|
||||
showMaps={props.showMaps}
|
||||
eventsObj={props.searchResultsObj.eventsObj}
|
||||
mediaObj={props.searchResultsObj.mediaObj}
|
||||
/>
|
||||
</div>
|
||||
<Footer
|
||||
@@ -159,14 +162,22 @@ export const getServerSideProps = wrapper.getServerSideProps(
|
||||
const searchDetailsObj = await getSearchDetails(searchResultsObj);
|
||||
|
||||
var eventsObj = {};
|
||||
var mediaObj = {};
|
||||
|
||||
if (searchResultsObj.value[0].pinswg_appealcasetype == 846040002) {
|
||||
eventsObj = await getSIPSEvents(
|
||||
searchDetailsObj[0].value[0].pinswg_sipsid
|
||||
searchDetailsObj[0].value[0].pinswg_sipsid,
|
||||
);
|
||||
store.dispatch(setEventDetails(eventsObj));
|
||||
}
|
||||
|
||||
if (searchResultsObj.value[0].pinswg_appealcasetype == 846040002) {
|
||||
mediaObj = await getSIPSMedia(
|
||||
searchDetailsObj[0].value[0].pinswg_sipsid,
|
||||
);
|
||||
store.dispatch(setMediaDetails(mediaObj));
|
||||
}
|
||||
|
||||
//console.log(
|
||||
// "\n======================================\n",
|
||||
// searchResultsObj,
|
||||
@@ -182,7 +193,7 @@ export const getServerSideProps = wrapper.getServerSideProps(
|
||||
|
||||
console.log(
|
||||
searchResultsObj["@odata.count"] > 1 ||
|
||||
searchResultsObj["@odata.count"] < 1
|
||||
searchResultsObj["@odata.count"] < 1,
|
||||
);
|
||||
|
||||
if (searchResultsObj["@odata.count"] < 1) {
|
||||
@@ -223,7 +234,7 @@ export const getServerSideProps = wrapper.getServerSideProps(
|
||||
searchDetailsObj[0].value[0]
|
||||
.pinswg_specialistcaseprocess
|
||||
: "",
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -234,17 +245,18 @@ export const getServerSideProps = wrapper.getServerSideProps(
|
||||
searchResultsObj: searchResultsObj,
|
||||
searchDetailsObj: searchDetailsObj,
|
||||
eventsObj: eventsObj,
|
||||
mediaObj: mediaObj,
|
||||
},
|
||||
currentType: "directResultsObj",
|
||||
docsOffline: process.env.DOCAPI_OFFLINE || false,
|
||||
messagesObj: await getCaseMessage(
|
||||
searchResultsObj.value[0].incidentid
|
||||
searchResultsObj.value[0].incidentid,
|
||||
),
|
||||
showFilteredDocs: process.env.SHOWFILTERDOCS || false,
|
||||
showMaps: process.env.SHOWMAPS,
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
|
||||
+70
-5
@@ -1,28 +1,93 @@
|
||||
import useTranslation from "next-translate/useTranslation";
|
||||
import Head from "next/head";
|
||||
import CookieBanner from "../components/cookieBanner";
|
||||
import Header from "../components/header";
|
||||
import Footer from "../components/footer";
|
||||
import router from "next/router";
|
||||
|
||||
const FourOhFour = (props) => {
|
||||
const StatusPage = (props) => {
|
||||
let { t, lang } = useTranslation();
|
||||
const { footerLinks, pages } = props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Head>
|
||||
<title>Status Up</title>
|
||||
<title>Site Status</title>
|
||||
</Head>
|
||||
<div id="page_wrapper">
|
||||
<CookieBanner />
|
||||
<Header />
|
||||
<div className="govuk-width-container govuk-!-padding-bottom-9">
|
||||
<main className="govuk-main-wrapper govuk-!-padding-top-9 govuk-!-padding-bottom-9">
|
||||
<div className="govuk-grid-row">
|
||||
<div className="govuk-grid-column-two-thirds ">
|
||||
<h1>Status Up</h1>
|
||||
<div
|
||||
className="govuk-warning-text noticebanner govuk-!-margin-bottom-0"
|
||||
key={1}
|
||||
>
|
||||
<strong className="govuk-warning-text__text">
|
||||
<span className="govuk-visually-hidden">
|
||||
Announcement
|
||||
</span>
|
||||
</strong>
|
||||
<div>
|
||||
<div className=" govuk-body-s">
|
||||
<h2 className="govuk-heading-s">
|
||||
{router.locale == "cy"
|
||||
? "Cyhoeddiad"
|
||||
: "Announcement"}
|
||||
</h2>
|
||||
</div>
|
||||
<div className="govuk-body-s">
|
||||
{router.locale == "cy" ? (
|
||||
<>
|
||||
<p>
|
||||
Oherwydd gwaith cynnal a
|
||||
chadw hanfodol, rydym yn
|
||||
disgwyl rhywfaint o darfu ar
|
||||
ein gwasanaethau Porth
|
||||
Gwaith Achos rhwng 9-13
|
||||
Chwefror 2026.{" "}
|
||||
</p>
|
||||
<p>
|
||||
Ymddiheurwn am yr
|
||||
anghyfleustra. Am ymholiadau
|
||||
brys yn ystod y cyfnod hwn,
|
||||
cysylltwch â{" "}
|
||||
<a href="mailto:pedw.gwaithachos@llyw.cymru">
|
||||
pedw.gwaithachos@llyw.cymru
|
||||
</a>
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p>
|
||||
Due to essential
|
||||
maintenance, we are
|
||||
expecting some disruption to
|
||||
our Casework Portal services
|
||||
between 9-13 February 2026.
|
||||
</p>
|
||||
<p>
|
||||
We apologise for the
|
||||
inconvenience. For urgent
|
||||
enquries during this time
|
||||
please contact{" "}
|
||||
<a href="mailto:pedw.casework@gov.wales">
|
||||
pedw.casework@gov.wales
|
||||
</a>
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<Footer footerLinks={footerLinks} ticketnumber={props} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FourOhFour;
|
||||
export default StatusPage;
|
||||
|
||||
@@ -8,6 +8,7 @@ export const searchResultsActionTypes = {
|
||||
SETREPRESENTATIONS: "SETREPRESENTATIONS",
|
||||
SETDNSCOORDS: "SETDNSCOORDS",
|
||||
SETEVENTDETAILS: "SETEVENTDETAILS",
|
||||
SETMEDIADETAILS: "SETMEDIADETAILS",
|
||||
};
|
||||
|
||||
export const getSearchResultshObj = () => (dispatch) => {
|
||||
@@ -63,3 +64,10 @@ export const setEventDetails = (eventsDetails) => (dispatch) => {
|
||||
eventDetailsObj: eventsDetails,
|
||||
});
|
||||
};
|
||||
|
||||
export const setMediaDetails = (mediaDetails) => (dispatch) => {
|
||||
return dispatch({
|
||||
type: searchResultsActionTypes.SETMEDIADETAILS,
|
||||
mediaDetailsObj: mediaDetails,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ const searchResultsInitialState = {
|
||||
representationsObj: {},
|
||||
dnsCoordsObj: {},
|
||||
eventDetailsObj: {},
|
||||
mediaDetailsObj: {},
|
||||
};
|
||||
|
||||
export default function reducer(state = searchResultsInitialState, action) {
|
||||
@@ -42,6 +43,11 @@ export default function reducer(state = searchResultsInitialState, action) {
|
||||
...state,
|
||||
eventDetailsObj: action.eventDetailsObj,
|
||||
};
|
||||
case searchResultsActionTypes.SETMEDIADETAILS:
|
||||
return {
|
||||
...state,
|
||||
mediaDetailsObj: action.mediaDetailsObj,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -3164,4 +3164,108 @@ ul.subFieldList {
|
||||
-webkit-box-decoration-break: clone;
|
||||
box-decoration-break: clone;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
#case-media {
|
||||
.videoWrapper {
|
||||
position: relative;
|
||||
padding-bottom: 56.25%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
border: 1px solid #b1b4b6;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.videoWrapper iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.videoTabButton {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
background: transparent;
|
||||
border: 1px solid #b1b4b6;
|
||||
border-radius: 4px;
|
||||
padding: 10px 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.videoTabButton:hover {
|
||||
background: #f3f2f1;
|
||||
}
|
||||
|
||||
.videoTabButton.active {
|
||||
border-color: #1d70b8;
|
||||
box-shadow: inset 0 0 0 1px #1d70b8;
|
||||
background: #eef4ff;
|
||||
}
|
||||
|
||||
.videoTabContent {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.thumbnailWrapper {
|
||||
position: relative;
|
||||
width: 120px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.videoThumbnail {
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
object-fit: cover;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #b1b4b6;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.playIcon {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 32px;
|
||||
color: white;
|
||||
text-shadow: 0 0 6px rgba(0, 0, 0, 0.7);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.durationBadge {
|
||||
position: absolute;
|
||||
bottom: 6px;
|
||||
right: 6px;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.watchedBadge {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
left: 6px;
|
||||
background: #00703c;
|
||||
color: white;
|
||||
font-size: 11px;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.videoTitle {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@media (max-width: 40.0625em) {
|
||||
.thumbnailWrapper {
|
||||
width: 90px;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user