Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
463 changes: 462 additions & 1 deletion package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"@chakra-ui/react": "^1.8.6",
"@emotion/react": "^11.8.1",
"@emotion/styled": "^11.8.1",
"@fontsource/be-vietnam-pro": "^4.5.2",
"axios": "^0.26.1",
"date-fns": "^2.28.0",
"framer-motion": "^6.2.8",
Expand Down
8 changes: 7 additions & 1 deletion src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ const App = () => {
minH="100vh"
backgroundColor="gray.900"
templateColumns="minmax(15em, 1fr) 3fr"
>
sx={{
'@media (max-width: 450px)': {
display: 'flex',
flexDirection: 'column'
},
}}
>
Comment on lines 12 to +19
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ça fonctionne. Comme on a un Grid au-dessus, on peut aussi utiliser une prop responsive sur le container, pour qu’il n’y ait 2 colonnes dans la grille qu’à partir d’un certain endpoint.

templateColumns={{ md: 'minmax(15em, 1fr) 3fr' }}

<Sidebar />
<MainContent>
<Forecast />
Expand Down
2 changes: 1 addition & 1 deletion src/components/Forecast.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const Forecast = () => {

return (
<Grid templateColumns="repeat(auto-fit, minmax(120px, 1fr))" gap={4}>
{daysForecasts.slice(0, 4).map(forecast => (
{daysForecasts.slice(1, 6).map(forecast => (
<ForecastCard key={forecast.id} forecast={forecast} />
))}
</Grid>
Expand Down
3 changes: 2 additions & 1 deletion src/components/ForecastCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { HStack, Text, Skeleton } from '@chakra-ui/react';
import { round } from 'lodash';
import Card from './Card';
import WeatherIcon from './WeatherIcon';
import { formatDate } from '../utils/index';

const ForecastCard = ({ forecast }) => {
return (
<Card alignItems="center" shouldShowSkeleton isLoaded={!forecast.isLoading}>
<Text>{forecast?.applicableDate}</Text>
<Text>{formatDate(forecast?.applicableDate)}</Text>
<WeatherIcon abbr={forecast?.weatherStateAbbr} />
<HStack width="100%" justifyContent="space-between">
<Text>{round(forecast?.maxTemp)} °C</Text>
Expand Down
3 changes: 2 additions & 1 deletion src/components/Highlights.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useWeather } from '../hooks';
import HighlightCard from './HighlightCard';
import { round } from 'lodash';
import WindHeading from './Icons/WindHeading';
import { angle } from '../utils/angle';

const Highlights = () => {
const { data, isLoading } = useWeather();
Expand All @@ -26,7 +27,7 @@ const Highlights = () => {
}
footer={
<HStack>
<WindHeading />
<WindHeading angle={angle(today?.windDirectionCompass)} />
<Text color="gray.500">{today?.windDirectionCompass}</Text>
</HStack>
}
Expand Down
4 changes: 4 additions & 0 deletions src/components/Icons/WindHeading.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { memo } from 'react';


const WindHeading = props => (

<svg
transform={`rotate (${props.angle})`}
width="1em"
height="1em"
viewBox="0 0 24 24"
Expand All @@ -18,6 +21,7 @@ const WindHeading = props => (
strokeLinejoin="round"
/>
</svg>

);

export default memo(WindHeading);
21 changes: 16 additions & 5 deletions src/components/Sidebar.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { Box, Heading, Stack, Text } from '@chakra-ui/react';
import { Box, Heading, Stack, Text, Select } from '@chakra-ui/react';
import WeatherIcon from './WeatherIcon';
import { useWeather } from '../hooks';
import { round } from 'lodash';
import { formatDate } from '../utils/index';

const Sidebar = () => {
const { data } = useWeather();
const today = data?.data?.consolidatedWeather?.[0];

return (
<Box backgroundColor="gray.800" color="gray.500">
<Stack
Expand All @@ -13,19 +19,24 @@ const Sidebar = () => {
>
<span /> {/* Intentionnaly left blank */}
<Stack alignItems="center" spacing={0}>
<WeatherIcon width="100%" />
<Select placeholder="Choose your city" variant="flushed">
<option value="option1">Lille</option>
<option value="option2">Lyon</option>
<option value="option3">Bordeaux</option>
</Select>
Comment on lines +22 to +26
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Du coup pour ça, dans AppProvider on a une constante const CITIES,

Tu peux l’exposer dans ton contexte, genre

<AppContext.Provider value={{ 
  availableCities: CITIES, 
  selectedCity, 
  onSelectCity: setSelectedCity 
}}>

Dans Sidebar.jsx,

const { availableCities } = useApp();
// [...]
<Select
  placeholder="Choose your city"
  variant="flushed"
  onChange={e => handleSelectCity(e.target.value)}
>
  {availableCities.map(({ id, label }) => (
    <option key={id} value={id}>
      {label}
    </option>
  ))}
</Select>

Dans useWeather.js

import { useQuery } from 'react-query';
import api from '../api';
import useApp from './useApp';

const useWeather = () => {
  const { selectedCity } = useApp();
  // const locationId = 608105;

  const response = useQuery(
    ['weather', selectedCity],
    () => api.get(`/location/${selectedCity}/`),
    {
      enabled: Boolean(selectedCity),
    },
  );

  return response;
};

export default useWeather;

Quelque chose comme ça. 🎉

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow merci pour tous ces retours très constructifs et détaillés ! Je m'entrainerai à les appliquer sur l'appli 💯

<WeatherIcon width="100%" abbr={today?.weatherStateAbbr} />
<Heading as="h1" fontSize="8xl" color="white">
20
{Boolean(today?.maxTemp) ? round(today?.maxTemp) : undefined}
<Text fontSize="4xl" display="inline" color="gray.500">
°C
</Text>
</Heading>
<Text fontSize="4xl" display="inline">
Sunny
{today?.weatherStateName}
</Text>
</Stack>
<Stack alignItems="center" spacing={0}>
<Text>Today • Sun 13 Mar</Text>
<Text>Today • {formatDate(today?.applicableDate)}</Text>
<Text>Lille</Text>
</Stack>
</Stack>
Expand Down
2 changes: 2 additions & 0 deletions src/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { ChakraProvider } from '@chakra-ui/react';
import { QueryClient, QueryClientProvider } from 'react-query';
import AppProvider from './providers/AppProvider';
import { theme } from './ui';
import '@fontsource/be-vietnam-pro'


const queryClient = new QueryClient();

Expand Down
5 changes: 5 additions & 0 deletions src/ui/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const theme = extendTheme({
},
},

fonts: {
heading: 'Be Vietnam Pro, sans-serif',
body: 'Be Vietnam Pro, sans-serif',
},

components: {
Progress: {
baseStyle: {
Expand Down
41 changes: 41 additions & 0 deletions src/utils/angle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// ternary operators to determine the angle of the compass

export function angle(windDirection) {
try {
return windDirection == 'N' // direction
? 0 // degree
: windDirection == 'NNE'
? 30
: windDirection == 'NE'
? 50
: windDirection == 'ENE'
? 70
: windDirection == 'E'
? 90
: windDirection == 'ESE'
? 120
: windDirection == 'SE'
? 140
: windDirection == 'SSE'
? 160
: windDirection == 'S'
? 180
: windDirection == 'SSW'
? 210
: windDirection == 'SW'
? 230
: windDirection == 'WSW'
? 250
: windDirection == 'W'
? 270
: windDirection == 'WNW'
? 300
: windDirection == 'NW'
? 320
: windDirection == 'NNW'
? 340
: 0; // goes to 0° if the value is undefined
Comment on lines +5 to +37
Copy link
Copy Markdown
Contributor

@Uptip Uptip Mar 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ici j’ai 3 remarques,

  1. On a, sur today, la windDirection en degrés, plus précis qu’en points cardinaux
  2. La direction du vent, c’est là d’où il vient, mais la flèche représente souvent là où il va, du coup si on utilise les points cardinaux, S c’est vers le haut, E vers la gauche, W vers la droite, etc. (du coup si utilise today?. windDirection, il suffit d’ajouter 180)
  3. Pour une longue ternaire comme ça, n’hésite pas à utiliser des switch case, plus lisibles
    e.g.
export const angle = windDirection => {
  switch (windDirection) {
    case 'N':
      return 180;
    case 'NNE':
      return 202.5;
    case 'NE': 
      return 225;
    // […]
    case 'S':
    default:
      return 0;
  }
}

} catch (err) {
return '';
}
}
10 changes: 9 additions & 1 deletion src/utils/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
export const formatDate = () => {};
import { format } from 'date-fns';

export function formatDate(date) {
try {
return format(new Date(date), 'eee d MMM');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙌

} catch (err) {
return '';
} // this date formatting exemple : Fri 18 Mar
}