Skip to content

Commit

Permalink
Merge branch '56/shared-rails-phoenix-session' of github.com:GSA/Chal…
Browse files Browse the repository at this point in the history
…lenge_gov into 56/shared-rails-phoenix-session

* '56/shared-rails-phoenix-session' of github.com:GSA/Challenge_gov: (32 commits)
  update postgrex, ecto_sql, ecto, wallabye versions
  Configure SSL option for database
  Set up eval space portal deploy
  NG can't submit or create new Challenges
  merge if/end issues
  closing if
  fix testing
  non-gov validation, logs and testing
  dependency diverge 3.4 -> 3.9.2
  remove code non-gov
  New yarn.lock
  Revert "Update jquery to 3.7.1"
  Update jquery to 3.7.1
  configure Nix to use default node version 20.15.1
  Update jquery to 3.7.1
  Non gov-mil users
  yarn update assets
  Dependencies: row 5 #1358 Upgrade yarn in staging
  phases start & end
  phases start & end
  ...
  • Loading branch information
cpreisinger committed Sep 13, 2024
2 parents cd13424 + 6cd6fdf commit d0526a9
Show file tree
Hide file tree
Showing 36 changed files with 891 additions and 912 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,5 @@ yarn.lock
/otp-OTP-24.0.2/
/otp-OTP-24.1.2/

.nix-hex
.nix-mix
/.nix-hex/
/.nix-mix/
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
elixir 1.16.3
erlang 26.2.5
nodejs 20.14.0
yarn 1.22.5
yarn 1.22.19
7 changes: 5 additions & 2 deletions assets/client/src/components/ChallengeAnnouncement.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import React from 'react';
import moment from 'moment';
import {formatDate, daysInMinutes, formatDateTime} from "../helpers/phaseHelpers"

export const ChallengeAnnouncement = ({challenge}) => {
const checkAnnouncementDate = ({announcement_datetime}) => {
return moment().diff(announcement_datetime, 'minutes') <= daysInMinutes(14)

let now = new Date();
let announcementDate = new Date(announcement_datetime);
let diffInMinutes = (now - announcementDate) / (1000 * 60);
return diffInMinutes <= daysInMinutes(14)
}

const renderAnnouncement = ({header, body}) => {
Expand Down
41 changes: 34 additions & 7 deletions assets/client/src/components/ChallengeDetails.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useContext, useEffect, useState } from 'react'
import moment from "moment"
import { stripHtml } from "string-strip-html";
import { Tooltip } from 'reactstrap';
import NumberFormat from 'react-number-format';
Expand Down Expand Up @@ -30,22 +29,50 @@ export const ChallengeDetails = ({challenge, challengePhases, preview, print, ta
const toggleShareTooltip = () => setShareTooltipOpen(!shareTooltipOpen)

const renderEndDate = (date) => {
const fiveDaysFromNow = moment().add(5,'d').utc().format()
const withinFiveDays = moment(date).diff(fiveDaysFromNow) <= 0

if (date > moment().utc().format()) {
let localTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;

let formatLocalDateTime = (date) => {
let dateObj = new Date(date);
let dateOptions = { year: 'numeric', month: '2-digit', day: '2-digit', timeZone: localTimeZone };
let timeOptions = { hour: '2-digit', minute: '2-digit', hour12: true, timeZone: localTimeZone };
let formattedDate = dateObj.toLocaleDateString('en-US', dateOptions);
let formattedTime = dateObj.toLocaleTimeString('en-US', timeOptions);
return `${formattedDate} ${formattedTime}`;
}

const fiveDaysFromNow = () => {
let now = new Date();
now.setDate(now.getDate() + 5);
let utcDate = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds()));
return utcDate.toDateString();
}

const withinFiveDays = (date) => {
let givenDate = new Date(date);
let now = new Date();
let futureDate = new Date(fiveDaysFromNow());
return givenDate <= futureDate;
}

let getUTCNow = () => {
let now = new Date();
return now.toISOString();
}

if (date > getUTCNow()) {
return (
<div className="item">
<p className="info-title">Open until:</p>
<p>{moment(date).local().format('L LT')}</p>
{ withinFiveDays && <p className="date-qualifier">Closing soon</p> }
<p>{formatLocalDateTime(date)}</p>
{ withinFiveDays() && <p className="date-qualifier">Closing soon</p> }
</div>
)
} else {
return (
<div className="item">
<p className="info-title">Closed on:</p>
<p>{moment(date).local().format('L LT')}</p>
<p>{formatLocalDateTime(date)}</p>
</div>
)
}
Expand Down
22 changes: 14 additions & 8 deletions assets/client/src/components/ChallengeTile.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import React, {useContext} from 'react'
import { Link } from "react-router-dom";
import moment from "moment"
import {getCurrentPhase, getNextPhase, phaseNumber, formatDateTime, formatTime, isSinglePhase, isPhaseless, daysInMinutes} from "../helpers/phaseHelpers"
import {truncateString} from '../helpers/stringHelpers'
import { ApiUrlContext } from '../ApiUrlContext'

export const ChallengeTile = ({challenge, preview}) => {
const { publicUrl, imageBase } = useContext(ApiUrlContext)

let diffMinutes = (d) =>{
let now = new Date();
let date = new Date(d);
return (now - date) / (1000 * 60)
}

const renderTags = ({is_archived, start_date, end_date, announcement_datetime}) => {
const startDateDiff = moment().diff(start_date, 'minutes')
const endDateDiff = moment().diff(end_date, 'minutes')
const announcementDateDiff = moment().diff(announcement_datetime, 'minutes')

const startDateDiff = diffMinutes(start_date);
const endDateDiff = diffMinutes(end_date);
const announcementDateDiff = diffMinutes(announcement_datetime);

let tags = []

Expand Down Expand Up @@ -40,8 +46,8 @@ export const ChallengeTile = ({challenge, preview}) => {

const renderDate = (challenge) => {
const {start_date, end_date, phases} = challenge
const startDateDiff = moment().diff(start_date, 'minutes')
const endDateDiff = moment().diff(end_date, 'minutes')
const startDateDiff = diffMinutes(start_date)
const endDateDiff = diffMinutes(end_date)

if (isPhaseless(challenge)) {
return handlePhaselessChallengeDate(challenge)
Expand Down Expand Up @@ -73,8 +79,8 @@ export const ChallengeTile = ({challenge, preview}) => {

// TODO: This is potentially temporary until the importer handles adding phases to imported challenges
const handlePhaselessChallengeDate = ({start_date, end_date}) => {
const startDateDiff = moment().diff(start_date, 'minutes')
const endDateDiff = moment().diff(end_date, 'minutes')
const startDateDiff = diffMinutes(start_date)
const endDateDiff = diffMinutes(end_date)

if (startDateDiff < 0) {
return `Opens on ${formatDateTime(start_date)}`
Expand Down
52 changes: 36 additions & 16 deletions assets/client/src/components/ChallengeTiles.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useState, useEffect } from 'react';
import moment from 'moment';
import { ChallengeTile } from './ChallengeTile';

const dateAddedOptions = [
Expand Down Expand Up @@ -75,6 +74,15 @@ export const ChallengeTiles = ({ data, loading, isArchived, selectedYear, handle
const [keyword, setKeyword] = useState('');
const [filteredChallenges, setFilteredChallenges] = useState([]);

const isBetween = (date, startDate, endDate) => {

let dateObj = new Date(date);
let startDateObj = new Date(startDate);
let endDateObj = new Date(endDate);
return dateObj >= startDateObj && dateObj < endDateObj;

}

useEffect(() => {
try {
if (data && data.collection) {
Expand All @@ -88,26 +96,32 @@ export const ChallengeTiles = ({ data, loading, isArchived, selectedYear, handle
}

if (dateAdded) {
const now = moment();
let fromDate = now.clone().subtract(1, "years");

const now = new Date();
let fromDate = new Date(now);
fromDate.setFullYear(fromDate.getFullYear() -1);


switch (dateAdded) {
case "Past Week":
fromDate = now.clone().subtract(7, "days");
fromDate = new Date(now);
fromDate.setDate(fromDate.getDate() -7);
break;
case "Past Month":
fromDate = now.clone().subtract(1, "months");
fromDate = new Date(now);
fromDate.setMonth(fromDate.getMonth() -1);
break;
case "Past 90 Days":
fromDate = now.clone().subtract(90, "days");
fromDate = new Date(now);
fromDate.setDate(fromDate.getDate() -90);
break;
default:
break;
}

filtered = filtered.filter((challenge) => {
const challengeDate = moment(challenge.inserted_at);
return challengeDate.isBetween(fromDate, now, null, "[)");
const challengeDate = new Date(challenge.inserted_at);
return isBetween(challengeDate, fromDate, now);
});
}

Expand All @@ -116,30 +130,35 @@ export const ChallengeTiles = ({ data, loading, isArchived, selectedYear, handle
}

if (lastDay) {
const now = moment();
const now = new Date();
let toDate;

switch (lastDay) {
case "Next Week":
toDate = now.clone().add(7, "days");
toDate = new Date(now);
toDate.setDate(toDate.getDate() +7);
break;
case "Next Month":
toDate = now.clone().add(1, "months");
toDate = new Date(now);
toDate.setMonth(toDate.getMonth()+1);
break;
case "Next 90 days":
toDate = new Date(now);
toDate = now.clone().add(90, "days");
break;
case "Within Year":
toDate = now.clone().add(1, "years");
toDate = new Date(now);
toDate.setFullYear(toDate.getFullYear()+1);
break;
default:
toDate = now.clone().add(1, "years");
toDate = new Date(now);
toDate.setFullYear(toDate.getFullYear()+1);
break;
}

filtered = filtered.filter((challenge) => {
const challengeEnd = moment(challenge.end_date);
return challengeEnd.isBetween(now, toDate, null, "[)");
const challengeEnd = new Date(challenge.end_date);
return isBetween(challengeEnd, now, toDate);
});
}

Expand Down Expand Up @@ -296,7 +315,8 @@ export const ChallengeTiles = ({ data, loading, isArchived, selectedYear, handle

const renderYearFilter = () => {
const startYear = 2010;
const currentYear = moment().year();
let year = new Date();
const currentYear = year.getFullYear();
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + (i * step));
const years = range(currentYear, startYear, -1);

Expand Down
19 changes: 17 additions & 2 deletions assets/client/src/components/PreviewBanner.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
import React, { useContext } from 'react'
import moment from 'moment'
import { ApiUrlContext } from '../ApiUrlContext'

export const PreviewBanner = ({challenge}) => {
const location = window.location.href.split('?')[0]
const { apiUrl } = useContext(ApiUrlContext)

const formatDateToLLLL = () => {

let now = new Date()
const options = {
weekday: 'short',
year: 'numeric',
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
hour12: true
};

return new Intl.DateTimeFormat('en-US', options).format(now);
}

return (
challenge ? (
Expand All @@ -20,7 +35,7 @@ export const PreviewBanner = ({challenge}) => {
</div>
<br/>
<div>
<span className="me-3">Preview generated on {moment().format("llll")}</span>
<span className="me-3">Preview generated on {formatDateToLLLL()}</span>
<a className="me-3" href={window.location.href}>Refresh page</a>
{!challenge.external_url &&
<a href={apiUrl + `/public/previews/challenges?challenge=${challenge.uuid}&print=true`} target="_blank">Print</a>
Expand Down
19 changes: 15 additions & 4 deletions assets/client/src/components/phase/AccordionSection.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import React, {useEffect, useState} from 'react'
import moment from 'moment'

import {phaseInPast, phaseIsCurrent, phaseInFuture} from "../../helpers/phaseHelpers"

export const AccordionSection = ({phase, index, section, children, print}) => {
const [expanded, setExpanded] = useState();
const [phaseClass, setPhaseClass] = useState();
const [phaseText, setPhaseText] = useState();

let localTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;

let formatLocalDateTime = (date) => {

let dateObj = new Date(date);
let month = (dateObj.getMonth() + 1).toString().padStart(2, '0');
let day = dateObj.getDate().toString().padStart(2, '0');
let year = dateObj.getFullYear().toString().slice(-2);

return `${month}/${day}/${year}`;
}

useEffect(() => {
setExpanded(() => {
return phaseIsCurrent(phase)
Expand All @@ -15,9 +26,9 @@ export const AccordionSection = ({phase, index, section, children, print}) => {
if (phaseInPast(phase)) {
return 'closed';
} else if (phaseIsCurrent(phase)) {
return `open until ${moment(phase.end_date).local().format("MM/DD/YY")}`;
return `open until ${formatLocalDateTime(phase.end_date)}`;
} else if (phaseInFuture(phase)) {
return `opens on ${moment(phase.start_date).local().format("MM/DD/YY")}`;
return `opens on ${formatLocalDateTime(phase.start_date)}`;
}
});
setPhaseClass(() => {
Expand Down
12 changes: 9 additions & 3 deletions assets/client/src/helpers/dateTimeHelpers.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
// TODO: Move date and timezone related functions to this file
// export const localDate = (datetime) => {

export const localDate = (datetime) => {
let timeZone = moment.tz.guess(true)
let local_time = moment.tz(datetime, timeZone).format("MM/DD/YYYY")

return local_time
let dateObj = new Date(datetime);
let month = (dateObj.getMonth() + 1).toString().padStart(2, '0');
let day = dateObj.getDate().toString().padStart(2, '0');
let year = dateObj.getFullYear();

return `${month}/${day}/${year}`;
}


export default {
localDate
}
Loading

0 comments on commit d0526a9

Please sign in to comment.