From 1411e37d8fa6bab98b8ab0a949f820d7677eecfd Mon Sep 17 00:00:00 2001 From: yudejp Date: Sat, 2 Oct 2021 12:45:12 +0900 Subject: [PATCH] Add sleep duration, heartrate on /profile --- pages/api/Fitbit/Heartrate.js | 42 +++++++++++++++++++++++++++ pages/api/Fitbit/Sleep.js | 43 ++++++++++++++++++++++++++++ pages/components/Fitbit/Heartrate.js | 36 +++++++++++++++++++++++ pages/components/Fitbit/Sleep.js | 42 +++++++++++++++++++++++++++ pages/profile.js | 4 +++ 5 files changed, 167 insertions(+) create mode 100644 pages/api/Fitbit/Heartrate.js create mode 100644 pages/api/Fitbit/Sleep.js create mode 100644 pages/components/Fitbit/Heartrate.js create mode 100644 pages/components/Fitbit/Sleep.js diff --git a/pages/api/Fitbit/Heartrate.js b/pages/api/Fitbit/Heartrate.js new file mode 100644 index 0000000..903846f --- /dev/null +++ b/pages/api/Fitbit/Heartrate.js @@ -0,0 +1,42 @@ +// React +import { format } from 'date-fns' + +const { + FITBIT_TOKEN: bearer + } = process.env; + +const today = format(new Date(), 'yyyy-MM-dd') + +export const getName = async (props) => { + const uuid = props; + return fetch( + 'https://api.fitbit.com/1/user/-/activities/heart/date/today/1d/1sec.json', + { + headers: { + Authorization: `Bearer ${bearer}`, + }, + } + ); +}; + +const FitbitHeartrate = async (req, res) => { + const { uuid } = req.query + const response = await getName(uuid); + const data = await response.json(); + if (response.status === 204 || response.status > 400) { + return res.status(200).send("404"); + } + const heartrate = data["activities-heart"].map((item, i) => { + if (item.dateTime = today) { + return item.value.restingHeartRate + } else { + return "Failed to retrieve data." + } + } + ) + return res.status(200).json({ + heartrate, + }); +}; + +export default FitbitHeartrate \ No newline at end of file diff --git a/pages/api/Fitbit/Sleep.js b/pages/api/Fitbit/Sleep.js new file mode 100644 index 0000000..86c058e --- /dev/null +++ b/pages/api/Fitbit/Sleep.js @@ -0,0 +1,43 @@ +// React +import { format } from 'date-fns' + +const { + FITBIT_TOKEN: bearer + } = process.env; + +const today = format(new Date(), 'yyyy-MM-dd') + +export const getName = async (props) => { + const uuid = props; + return fetch( + 'https://api.fitbit.com/1.2/user/-/sleep/date/' + today + '.json', + { + headers: { + Authorization: `Bearer ${bearer}`, + }, + } + ); +}; + +const FitbitSleep = async (req, res) => { + const { uuid } = req.query + const response = await getName(uuid); + const data = await response.json(); + if (response.status === 204 || response.status > 400) { + return res.status(200).send("404"); + } + // const duration = data["sleep"].map((item, i) => { + // if (item.dateOfSleep = today) { + // return item.duration + // } else { + // return "Failed to retrieve data." + // } + // } + // ) + const duration = data.summary.totalMinutesAsleep + return res.status(200).json({ + duration, + }); +}; + +export default FitbitSleep \ No newline at end of file diff --git a/pages/components/Fitbit/Heartrate.js b/pages/components/Fitbit/Heartrate.js new file mode 100644 index 0000000..4de566a --- /dev/null +++ b/pages/components/Fitbit/Heartrate.js @@ -0,0 +1,36 @@ +// Data fetching +import useSwr from 'swr' + +// Font Awesome +import { faHeartbeat } from '@fortawesome/free-solid-svg-icons' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' + +// Data fetching implements +const fetcher = (url) => fetch(url).then((res) => res.json()) + +function App (props) { + const { data, error } = useSwr( + '/api/Fitbit/Heartrate', + fetcher + ) + + if (error) { + return ( + <>エラーが発生しました。 + ) + } else { + if (!data) { + return ( + <>読み込み中... + ) + } else { + return ( + <> + {data.heartrate} + + ) + } + } +} + +export default App; \ No newline at end of file diff --git a/pages/components/Fitbit/Sleep.js b/pages/components/Fitbit/Sleep.js new file mode 100644 index 0000000..1e3da7d --- /dev/null +++ b/pages/components/Fitbit/Sleep.js @@ -0,0 +1,42 @@ +// Data fetching +import useSwr from 'swr' + +// Font Awesome +import { faBed } from '@fortawesome/free-solid-svg-icons' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' + +// Data fetching implements +const fetcher = (url) => fetch(url).then((res) => res.json()) + +function App (props) { + const { data, error } = useSwr( + '/api/Fitbit/Sleep', + fetcher + ) + + if (error) { + return ( + <>エラーが発生しました。 + ) + } else { + if (!data) { + return ( + <>読み込み中... + ) + } else { + const duration = data.duration + const hours = Math.floor(duration / 60) + let minutes = duration % 60 + if (minutes <= 9) { + minutes = '0' + minutes + } + return ( + <> + {hours}:{minutes} + + ) + } + } +} + +export default App; \ No newline at end of file diff --git a/pages/profile.js b/pages/profile.js index 165e5ad..e469b15 100644 --- a/pages/profile.js +++ b/pages/profile.js @@ -25,6 +25,8 @@ import PublicKeys from './components/Profile/PublicKeys' import Button from './components/Profile/Button' import Contact from './components/Profile/Contact' import NintendoSW from "./components/Profile/NintendoSW" +import FitbitSleep from "./components/Fitbit/Sleep" +import FitbitHeartrate from "./components/Fitbit/Heartrate" // next-seo import { NextSeo } from 'next-seo'; @@ -61,6 +63,8 @@ export default function Profile(props) {
+ +