mirror of
				https://github.com/karl0ss/homepage.git
				synced 2025-10-31 06:24:02 +00:00 
			
		
		
		
	cleanup
This commit is contained in:
		
							parent
							
								
									34f7bd4341
								
							
						
					
					
						commit
						62188ffdc7
					
				| @ -1,14 +1,15 @@ | |||||||
| import { Fragment } from "react"; | import { Fragment } from "react"; | ||||||
| import { Menu, Transition } from "@headlessui/react"; | import { Menu, Transition } from "@headlessui/react"; | ||||||
| import { BiCog } from "react-icons/bi"; | import { BiCog } from "react-icons/bi"; | ||||||
|  | import classNames from "classnames"; | ||||||
| 
 | 
 | ||||||
| export default function Dropdown({ options, state }) { | export default function Dropdown({ options, value, setValue }) { | ||||||
|   return ( |   return ( | ||||||
|     <Menu as="div" className="relative inline-block text-left"> |     <Menu as="div" className="relative inline-block text-left"> | ||||||
|       <div> |       <div> | ||||||
|         <Menu.Button className="inline-flex w-full justify-center rounded-md border border-gray-300 bg-theme-600/40 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-theme-600/40 focus:outline-none"> |         <Menu.Button className="text-xs inline-flex w-full items-center rounded bg-theme-200/50 dark:bg-theme-900/20 px-3 py-1.5"> | ||||||
|           {state.value.label} |           {options.find((option) => option.value === value).label} | ||||||
|           <BiCog className="-mr-1 ml-2 h-5 w-5" aria-hidden="true" /> |           <BiCog className="-mr-1 ml-2 h-4 w-4" aria-hidden="true" /> | ||||||
|         </Menu.Button> |         </Menu.Button> | ||||||
|       </div> |       </div> | ||||||
| 
 | 
 | ||||||
| @ -21,18 +22,21 @@ export default function Dropdown({ options, state }) { | |||||||
|         leaveFrom="transform opacity-100 scale-100" |         leaveFrom="transform opacity-100 scale-100" | ||||||
|         leaveTo="transform opacity-0 scale-95" |         leaveTo="transform opacity-0 scale-95" | ||||||
|       > |       > | ||||||
|         <Menu.Items className="absolute right-0 z-10 mt-2 w-56 origin-top-right rounded-md bg-theme-600/40 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"> |         <Menu.Items className="absolute right-0 z-10 mt-2 w-56 origin-top-right rounded-md bg-theme-200/50 dark:bg-theme-900/50 backdrop-blur shadow-md focus:outline-none text-theme-700 dark:text-theme-200"> | ||||||
|           <div className="py-1"> |           <div className="py-1"> | ||||||
|             {options.map((i) => ( |             {options.map((option) => ( | ||||||
|               <Menu.Item key={i.value}> |               <Menu.Item key={option.value} as={Fragment}> | ||||||
|                 <button |                 <button | ||||||
|                   onClick={() => { |                   onClick={() => { | ||||||
|                     state.set(i); |                     setValue(option.value); | ||||||
|                   }} |                   }} | ||||||
|                   type="button" |                   type="button" | ||||||
|                   className="text-white block px-4 py-2 text-sm" |                   className={classNames( | ||||||
|  |                     value === option.value ? "bg-theme-300/40 dark:bg-theme-900/40" : "", | ||||||
|  |                     "w-full block px-3 py-1.5 text-sm hover:bg-theme-300/70 hover:dark:bg-theme-900/70 text-left" | ||||||
|  |                   )} | ||||||
|                 > |                 > | ||||||
|                   {i.label} |                   {option.label} | ||||||
|                 </button> |                 </button> | ||||||
|               </Menu.Item> |               </Menu.Item> | ||||||
|             ))} |             ))} | ||||||
|  | |||||||
| @ -33,19 +33,6 @@ export default function Item({ service }) { | |||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const cmcValues = [ |  | ||||||
|     { label: t("coinmarketcap.1hour"), value: "1h" }, |  | ||||||
|     { label: t("coinmarketcap.1day"), value: "24h" }, |  | ||||||
|     { label: t("coinmarketcap.7days"), value: "7d" }, |  | ||||||
|     { label: t("coinmarketcap.30days"), value: "30d" }, |  | ||||||
|   ]; |  | ||||||
| 
 |  | ||||||
|   const [cmcV, cmcSet] = useState(cmcValues[0]); |  | ||||||
| 
 |  | ||||||
|   const states = { |  | ||||||
|     coinmarketcap: { value: cmcV, set: cmcSet }, |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   const hasLink = service.href && service.href !== "#"; |   const hasLink = service.href && service.href !== "#"; | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
| @ -100,7 +87,6 @@ export default function Item({ service }) { | |||||||
|                 <Status service={service} /> |                 <Status service={service} /> | ||||||
|               </Disclosure.Button> |               </Disclosure.Button> | ||||||
|             )} |             )} | ||||||
|             {service?.widget?.type === "coinmarketcap" && <Dropdown state={states.coinmarketcap} options={cmcValues} />} |  | ||||||
|           </div> |           </div> | ||||||
| 
 | 
 | ||||||
|           <Disclosure.Panel> |           <Disclosure.Panel> | ||||||
| @ -109,7 +95,7 @@ export default function Item({ service }) { | |||||||
|             </div> |             </div> | ||||||
|           </Disclosure.Panel> |           </Disclosure.Panel> | ||||||
| 
 | 
 | ||||||
|           {service.widget && <Widget state={states[service?.widget?.type]} service={service} />} |           {service.widget && <Widget service={service} />} | ||||||
|         </div> |         </div> | ||||||
|       </Disclosure> |       </Disclosure> | ||||||
|     </li> |     </li> | ||||||
|  | |||||||
| @ -48,13 +48,13 @@ const widgetMappings = { | |||||||
|   prowlarr: Prowlarr, |   prowlarr: Prowlarr, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export default function Widget({ service, state }) { | export default function Widget({ service }) { | ||||||
|   const { t } = useTranslation("common"); |   const { t } = useTranslation("common"); | ||||||
| 
 | 
 | ||||||
|   const ServiceWidget = widgetMappings[service.widget.type]; |   const ServiceWidget = widgetMappings[service.widget.type]; | ||||||
| 
 | 
 | ||||||
|   if (ServiceWidget) { |   if (ServiceWidget) { | ||||||
|     return <ServiceWidget state={state} service={service} />; |     return <ServiceWidget service={service} />; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|  | |||||||
| @ -1,14 +1,26 @@ | |||||||
| import useSWR from "swr"; | import useSWR from "swr"; | ||||||
|  | import { useState } from "react"; | ||||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||||
| 
 | 
 | ||||||
| import Widget from "../widget"; | import Widget from "../widget"; | ||||||
| import Block from "../block"; | import Block from "../block"; | ||||||
| 
 | 
 | ||||||
|  | import Dropdown from "components/services/dropdown"; | ||||||
| import { formatApiUrl } from "utils/api-helpers"; | import { formatApiUrl } from "utils/api-helpers"; | ||||||
|  | import classNames from "classnames"; | ||||||
| 
 | 
 | ||||||
| export default function CoinMarketCap({ service, state }) { | export default function CoinMarketCap({ service }) { | ||||||
|   const { t } = useTranslation(); |   const { t } = useTranslation(); | ||||||
| 
 | 
 | ||||||
|  |   const dateRangeOptions = [ | ||||||
|  |     { label: t("coinmarketcap.1hour"), value: "1h" }, | ||||||
|  |     { label: t("coinmarketcap.1day"), value: "24h" }, | ||||||
|  |     { label: t("coinmarketcap.7days"), value: "7d" }, | ||||||
|  |     { label: t("coinmarketcap.30days"), value: "30d" }, | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|  |   const [dateRange, setDateRange] = useState(dateRangeOptions[0].value); | ||||||
|  | 
 | ||||||
|   const config = service.widget; |   const config = service.widget; | ||||||
|   const currencyCode = config.currency ?? "USD"; |   const currencyCode = config.currency ?? "USD"; | ||||||
|   const { symbols } = config; |   const { symbols } = config; | ||||||
| @ -29,7 +41,7 @@ export default function CoinMarketCap({ service, state }) { | |||||||
|     return <Widget error={t("widget.api_error")} />; |     return <Widget error={t("widget.api_error")} />; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (!statsData) { |   if (!statsData || !dateRange) { | ||||||
|     return ( |     return ( | ||||||
|       <Widget> |       <Widget> | ||||||
|         <Block value={t("coinmarketcap.configure")} /> |         <Block value={t("coinmarketcap.configure")} /> | ||||||
| @ -41,29 +53,33 @@ export default function CoinMarketCap({ service, state }) { | |||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <Widget> |     <Widget> | ||||||
|  |       <div className={classNames(service.description ? "-top-10" : "-top-8", "absolute right-1")}> | ||||||
|  |         <Dropdown options={dateRangeOptions} value={dateRange} setValue={setDateRange} /> | ||||||
|  |       </div> | ||||||
|  | 
 | ||||||
|       <div className="flex flex-col w-full"> |       <div className="flex flex-col w-full"> | ||||||
|         {symbols.map((key) => ( |         {symbols.map((symbol) => ( | ||||||
|           <div |           <div | ||||||
|             key={data[key].symbol} |             key={data[symbol].symbol} | ||||||
|             className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-row items-center justify-between p-1 text-xs" |             className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-row items-center justify-between p-1 text-xs" | ||||||
|           > |           > | ||||||
|             <div className="font-thin pl-2">{data[key].name}</div> |             <div className="font-thin pl-2">{data[symbol].name}</div> | ||||||
|             <div className="flex flex-row text-right"> |             <div className="flex flex-row text-right"> | ||||||
|               <div className="font-bold mr-2"> |               <div className="font-bold mr-2"> | ||||||
|                 {t("common.number", { |                 {t("common.number", { | ||||||
|                   value: data[key].quote[currencyCode].price, |                   value: data[symbol].quote[currencyCode].price, | ||||||
|                   style: "currency", |                   style: "currency", | ||||||
|                   currency: currencyCode, |                   currency: currencyCode, | ||||||
|                 })} |                 })} | ||||||
|               </div> |               </div> | ||||||
|               <div |               <div | ||||||
|                 className={`font-bold w-10 mr-2 ${ |                 className={`font-bold w-10 mr-2 ${ | ||||||
|                   data[key].quote[currencyCode][`percent_change_${state.value.value}`] > 0 |                   data[symbol].quote[currencyCode][`percent_change_${dateRange}`] > 0 | ||||||
|                     ? "text-emerald-300" |                     ? "text-emerald-300" | ||||||
|                     : "text-rose-300" |                     : "text-rose-300" | ||||||
|                 }`} |                 }`} | ||||||
|               > |               > | ||||||
|                 {data[key].quote[currencyCode][`percent_change_${state.value.value}`].toFixed(2)}% |                 {data[symbol].quote[currencyCode][`percent_change_${dateRange}`].toFixed(2)}% | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
|  | |||||||
| @ -7,5 +7,5 @@ export default function Widget({ error = false, children }) { | |||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return <div className="flex flex-row w-full">{children}</div>; |   return <div className="relative flex flex-row w-full">{children}</div>; | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Ben Phelps
						Ben Phelps