go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/analysis/frontend/ui/src/views/home/home_page.tsx (about)

     1  // Copyright 2022 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  import {
    16    LinkProps,
    17    Link as RouterLink,
    18  } from 'react-router-dom';
    19  
    20  import Container from '@mui/material/Container';
    21  import Grid from '@mui/material/Grid';
    22  import { styled } from '@mui/material/styles';
    23  import {
    24    Alert,
    25    AlertTitle,
    26    Link,
    27  } from '@mui/material';
    28  
    29  import CentralizedProgress from '@/components/centralized_progress/centralized_progress';
    30  import LoadErrorAlert from '@/components/load_error_alert/load_error_alert';
    31  import PageHeading from '@/components/headings/page_heading/page_heading';
    32  
    33  import useFetchProjects from '@/hooks/use_fetch_projects';
    34  import { loginLink } from '@/tools/urlHandling/links';
    35  
    36  const ProjectCard = styled(RouterLink)<LinkProps>(() => ({
    37    'padding-top': '2rem',
    38    'padding-bottom': '2rem',
    39    'display': 'flex',
    40    'justify-content': 'center',
    41    'align-items': 'center',
    42    'box-shadow': '0px 2px 1px -1px rgb(0 0 0 / 20%), 0px 1px 1px 0px rgb(0 0 0 / 14%), 0px 1px 3px 0px rgb(0 0 0 / 12%)',
    43    'font-size': '1.5rem',
    44    'text-decoration': 'none',
    45    'color': 'black',
    46    'border-radius': '4px',
    47    'transition': 'transform .2s',
    48    '&:hover': {
    49      'transform': 'scale(1.1)',
    50    },
    51  }));
    52  
    53  const HomePage = () => {
    54    const { error, isLoading, data: projects } = useFetchProjects();
    55    return (
    56      <Container maxWidth="xl">
    57        <PageHeading>
    58          Projects
    59        </PageHeading>
    60        {
    61          window.isAnonymous && (
    62            <Alert
    63              severity="info"
    64              sx={{ mb: 2 }}>
    65              <AlertTitle>Some projects may be hidden</AlertTitle>
    66              Please <Link href={loginLink('/')}>log in</Link> to view all projects you have access to.
    67            </Alert>
    68          )
    69        }
    70        {
    71          isLoading && (
    72            <CentralizedProgress />
    73          )
    74        }
    75        {
    76          error && (
    77            <Grid container item>
    78              <LoadErrorAlert
    79                entityName="projects"
    80                error={error} />
    81            </Grid>
    82          )
    83        }
    84        <Grid container spacing={2} id="project-cards">
    85          {
    86            projects && projects.map((project) => (
    87              <Grid
    88                key={project.name}
    89                item xs={2}>
    90                <ProjectCard
    91                  to={`/p/${project.project}/clusters`}
    92                >
    93                  {project.displayName}
    94                </ProjectCard>
    95              </Grid>
    96            ))
    97          }
    98        </Grid>
    99      </Container>
   100    );
   101  };
   102  
   103  export default HomePage;