EventCard.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import React, { useState } from "react";
  2. import styled from "styled-components";
  3. import { Event } from "./EventsContext";
  4. type CardProps = {
  5. event: Event;
  6. selectEvent: (id: number) => void;
  7. };
  8. const getReadableDate = (s: string) => {
  9. let ts = new Date(s);
  10. let date = ts.toLocaleDateString();
  11. let time = ts.toLocaleTimeString([], {
  12. hour: "numeric",
  13. minute: "2-digit",
  14. });
  15. return `${time} ${date}`;
  16. };
  17. // Rename to Event Card
  18. const EventCard: React.FunctionComponent<CardProps> = ({
  19. event,
  20. selectEvent,
  21. }) => {
  22. const [showTooltip, setShowTooltip] = useState(false);
  23. return (
  24. <StyledCard>
  25. <ContentContainer>
  26. <Icon status={event.event_type} className="material-icons-outlined">
  27. {event.event_type === "critical" ? "report_problem" : "info"}
  28. </Icon>
  29. <EventInformation>
  30. <EventName>
  31. <Helper>{event.resource_type}:</Helper>
  32. {event.name}
  33. </EventName>
  34. <EventReason>
  35. <Helper>Reason:</Helper>
  36. {event.reason}
  37. </EventReason>
  38. </EventInformation>
  39. </ContentContainer>
  40. <ActionContainer hasOneChild={event.event_type === "normal"}>
  41. {event.event_type === "critical" && (
  42. <HistoryButton
  43. onClick={() => selectEvent(event.id)}
  44. onMouseEnter={() => setShowTooltip(true)}
  45. onMouseLeave={() => setShowTooltip(false)}
  46. >
  47. <span className="material-icons-outlined">manage_search</span>
  48. {showTooltip && <Tooltip>Open logs</Tooltip>}
  49. </HistoryButton>
  50. )}
  51. <TimestampContainer>
  52. <TimestampIcon className="material-icons-outlined">
  53. access_time
  54. </TimestampIcon>
  55. <span>{getReadableDate(event.timestamp)}</span>
  56. </TimestampContainer>
  57. </ActionContainer>
  58. </StyledCard>
  59. );
  60. };
  61. export default EventCard;
  62. const StyledCard = styled.div`
  63. background: #26282f;
  64. min-height: 100px;
  65. width: 100%;
  66. display: flex;
  67. justify-content: space-between;
  68. align-items: center;
  69. border: 1px solid #26282f;
  70. box-shadow: 0 4px 15px 0px #00000055;
  71. border-radius: 8px;
  72. padding: 14px;
  73. animation: fadeIn 0.5s;
  74. @keyframes fadeIn {
  75. from {
  76. opacity: 0;
  77. }
  78. to {
  79. opacity: 1;
  80. }
  81. }
  82. `;
  83. const ContentContainer = styled.div`
  84. display: flex;
  85. height: 100%;
  86. width: 100%;
  87. align-items: center;
  88. `;
  89. const Icon = styled.span`
  90. font-size: 35px;
  91. margin-right: 14px;
  92. color: ${({ status }: { status: "critical" | "normal" }) =>
  93. status === "critical" ? "red" : "green"};
  94. `;
  95. const EventInformation = styled.div`
  96. display: flex;
  97. flex-direction: column;
  98. justify-content: space-around;
  99. height: 100%;
  100. `;
  101. const EventName = styled.div`
  102. font-size: 14px;
  103. font-family: "Work Sans", sans-serif;
  104. font-weight: 500;
  105. color: #ffffff;
  106. `;
  107. const Helper = styled.span`
  108. font-size: 14px;
  109. text-transform: capitalize;
  110. color: #ffffff44;
  111. margin-right: 5px;
  112. `;
  113. const EventReason = styled.div`
  114. font-size: 18px;
  115. font-family: "Work Sans", sans-serif;
  116. color: #ffffff;
  117. margin-top: 8px;
  118. `;
  119. const ActionContainer = styled.div`
  120. width: max-content;
  121. display: flex;
  122. align-items: center;
  123. white-space: nowrap;
  124. height: 100%;
  125. flex-direction: column;
  126. justify-content: ${(props: { hasOneChild: boolean }) => {
  127. return props.hasOneChild ? "flex-end" : "space-between";
  128. }};
  129. `;
  130. const HistoryButton = styled.button`
  131. position: relative;
  132. border: none;
  133. background: none;
  134. color: white;
  135. padding: 5px;
  136. display: flex;
  137. justify-content: center;
  138. align-items: center;
  139. border-radius: 50%;
  140. color: #ffffff44;
  141. :hover {
  142. background: #32343a;
  143. cursor: pointer;
  144. }
  145. `;
  146. const Tooltip = styled.div`
  147. position: absolute;
  148. left: 0px;
  149. word-wrap: break-word;
  150. top: 38px;
  151. min-height: 18px;
  152. padding: 5px 7px;
  153. background: #272731;
  154. z-index: 999;
  155. display: flex;
  156. flex-direction: column;
  157. justify-content: center;
  158. flex: 1;
  159. color: white;
  160. text-transform: none;
  161. font-size: 12px;
  162. font-family: "Work Sans", sans-serif;
  163. outline: 1px solid #ffffff55;
  164. opacity: 0;
  165. animation: faded-in 0.2s 0.15s;
  166. animation-fill-mode: forwards;
  167. @keyframes faded-in {
  168. from {
  169. opacity: 0;
  170. }
  171. to {
  172. opacity: 1;
  173. }
  174. }
  175. `;
  176. const TimestampContainer = styled.div`
  177. display: flex;
  178. white-space: nowrap;
  179. align-items: center;
  180. justify-self: flex-end;
  181. `;
  182. const TimestampIcon = styled.span`
  183. margin-right: 5px;
  184. `;