project-list-root.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import {
  2. ProjectListProvider,
  3. useProjectListContext,
  4. } from '../context/project-list-context'
  5. import * as eventTracking from '../../../infrastructure/event-tracking'
  6. import { Col, Row } from 'react-bootstrap'
  7. import { useTranslation } from 'react-i18next'
  8. import useWaitForI18n from '../../../shared/hooks/use-wait-for-i18n'
  9. import CurrentPlanWidget from './current-plan-widget/current-plan-widget'
  10. import NewProjectButton from './new-project-button'
  11. import ProjectListTable from './table/project-list-table'
  12. import SidebarFilters from './sidebar/sidebar-filters'
  13. import SurveyWidget from './survey-widget'
  14. import WelcomeMessage from './welcome-message'
  15. import LoadingBranded from '../../../shared/components/loading-branded'
  16. import SystemMessages from './notifications/system-messages'
  17. import UserNotifications from './notifications/user-notifications'
  18. import SearchForm from './search-form'
  19. import ProjectsDropdown from './dropdown/projects-dropdown'
  20. import SortByDropdown from './dropdown/sort-by-dropdown'
  21. import ProjectTools from './table/project-tools/project-tools'
  22. import LoadMore from './load-more'
  23. import { useEffect } from 'react'
  24. function ProjectListRoot() {
  25. const { isReady } = useWaitForI18n()
  26. return isReady ? (
  27. <ProjectListProvider>
  28. <ProjectListPageContent />
  29. </ProjectListProvider>
  30. ) : null
  31. }
  32. function ProjectListPageContent() {
  33. const {
  34. totalProjectsCount,
  35. error,
  36. isLoading,
  37. loadProgress,
  38. searchText,
  39. setSearchText,
  40. selectedProjects,
  41. } = useProjectListContext()
  42. useEffect(() => {
  43. eventTracking.sendMB('loads_v2_dash', {})
  44. }, [])
  45. return isLoading ? (
  46. <div className="loading-container">
  47. <LoadingBranded loadProgress={loadProgress} />
  48. </div>
  49. ) : (
  50. <>
  51. <SystemMessages />
  52. <div className="project-list-wrapper clearfix">
  53. {totalProjectsCount > 0 ? (
  54. <>
  55. <div className="project-list-sidebar-wrapper-react hidden-xs">
  56. <div className="project-list-sidebar-subwrapper">
  57. <aside className="project-list-sidebar-react">
  58. <NewProjectButton id="new-project-button-sidebar" />
  59. <SidebarFilters />
  60. </aside>
  61. </div>
  62. </div>
  63. <div className="project-list-main-react">
  64. {error ? <DashApiError /> : ''}
  65. <Row>
  66. <Col xs={12}>
  67. <UserNotifications />
  68. </Col>
  69. </Row>
  70. <Row>
  71. <Col md={7} className="hidden-xs">
  72. <SearchForm
  73. inputValue={searchText}
  74. setInputValue={setSearchText}
  75. />
  76. </Col>
  77. <Col md={5}>
  78. <div className="project-tools">
  79. <div className="hidden-xs">
  80. {selectedProjects.length === 0 ? (
  81. <CurrentPlanWidget />
  82. ) : (
  83. <ProjectTools />
  84. )}
  85. </div>
  86. <div className="visible-xs">
  87. <CurrentPlanWidget />
  88. </div>
  89. </div>
  90. </Col>
  91. </Row>
  92. <div className="project-list-sidebar-survey-wrapper">
  93. <SurveyWidget />
  94. </div>
  95. <div className="visible-xs mt-1">
  96. <div role="toolbar" className="projects-toolbar">
  97. <ProjectsDropdown />
  98. <SortByDropdown />
  99. </div>
  100. </div>
  101. <Row className="row-spaced">
  102. <Col xs={12}>
  103. <div className="card project-list-card">
  104. <div className="visible-xs pt-2 pb-3">
  105. <div className="clearfix">
  106. <NewProjectButton
  107. id="new-project-button-projects-table"
  108. className="pull-left me-2"
  109. />
  110. <SearchForm
  111. inputValue={searchText}
  112. setInputValue={setSearchText}
  113. className="overflow-hidden"
  114. formGroupProps={{ className: 'mb-0' }}
  115. />
  116. </div>
  117. </div>
  118. <ProjectListTable />
  119. </div>
  120. </Col>
  121. </Row>
  122. <Row className="row-spaced">
  123. <Col xs={12}>
  124. <LoadMore />
  125. </Col>
  126. </Row>
  127. </div>
  128. </>
  129. ) : (
  130. <div className="project-list-welcome-wrapper">
  131. {error ? <DashApiError /> : ''}
  132. <Row className="row-spaced">
  133. <Col
  134. xs={8}
  135. xsOffset={2}
  136. md={8}
  137. mdOffset={2}
  138. className="project-list-empty-col"
  139. >
  140. <Row>
  141. <Col xs={12}>
  142. <UserNotifications />
  143. </Col>
  144. </Row>
  145. <WelcomeMessage />
  146. </Col>
  147. </Row>
  148. </div>
  149. )}
  150. </div>
  151. </>
  152. )
  153. }
  154. function DashApiError() {
  155. const { t } = useTranslation()
  156. return (
  157. <Row className="row-spaced">
  158. <Col xs={8} xsOffset={2} aria-live="polite" className="text-center">
  159. <div className="alert alert-danger">
  160. {t('generic_something_went_wrong')}
  161. </div>
  162. </Col>
  163. </Row>
  164. )
  165. }
  166. export default ProjectListRoot