mirror of
https://github.com/DIYgod/RSSHub-Radar.git
synced 2026-08-30 16:41:08 +08:00
feat: rules page
This commit is contained in:
@@ -54,7 +54,7 @@
|
||||
"message": "Full remote updates are disabled due to browser limitations"
|
||||
},
|
||||
"forMoreRulesJoinUs": {
|
||||
"message": "For more rules support, <a target=\"_blank\" href=\"https://docs.rsshub.app/en/joinus/quick-start.html\">join us</a>!"
|
||||
"message": "For more rules support, <a target=\"_blank\" href=\"https://docs.rsshub.app/joinus/quick-start.html\">join us</a>!"
|
||||
},
|
||||
"general": {
|
||||
"message": "General"
|
||||
@@ -78,7 +78,7 @@
|
||||
"message": "No RSS found"
|
||||
},
|
||||
"rules": {
|
||||
"message": "Rules"
|
||||
"message": "Radar Rules"
|
||||
},
|
||||
"rulesUpdate": {
|
||||
"message": "Rules update"
|
||||
@@ -118,5 +118,8 @@
|
||||
},
|
||||
"fillInstanceDomain": {
|
||||
"message": "Please fill in your instance domain"
|
||||
},
|
||||
"totalNumberOfRules": {
|
||||
"message": "Total number of rules"
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@
|
||||
"message": "由于浏览器限制,完整的远程更新被禁用"
|
||||
},
|
||||
"forMoreRulesJoinUs": {
|
||||
"message": "更多规则支持中,快来<a target=\"_blank\" href=\"https://docs.rsshub.app/joinus/quick-start.html\">参与我们</a>吧!"
|
||||
"message": "更多规则支持中,快来<a target=\"_blank\" href=\"https://docs.rsshub.app/zh/joinus/quick-start.html\">参与我们</a>吧!"
|
||||
},
|
||||
"general": {
|
||||
"message": "常规"
|
||||
@@ -78,7 +78,7 @@
|
||||
"message": "没有检测到 RSS"
|
||||
},
|
||||
"rules": {
|
||||
"message": "规则列表"
|
||||
"message": "Radar 规则"
|
||||
},
|
||||
"rulesUpdate": {
|
||||
"message": "规则更新"
|
||||
@@ -118,5 +118,8 @@
|
||||
},
|
||||
"fillInstanceDomain": {
|
||||
"message": "请填写你的实例域名"
|
||||
},
|
||||
"totalNumberOfRules": {
|
||||
"message": "规则总数"
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
"@iconify-json/mingcute": "^1.1.13",
|
||||
"@plasmohq/messaging": "^0.6.1",
|
||||
"@plasmohq/storage": "^1.9.0",
|
||||
"@radix-ui/react-accordion": "^1.1.2",
|
||||
"@radix-ui/react-label": "^2.0.2",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"@radix-ui/react-switch": "^1.0.3",
|
||||
|
||||
Generated
+135
@@ -14,6 +14,9 @@ dependencies:
|
||||
'@plasmohq/storage':
|
||||
specifier: ^1.9.0
|
||||
version: 1.9.0(react@18.2.0)
|
||||
'@radix-ui/react-accordion':
|
||||
specifier: ^1.1.2
|
||||
version: 1.1.2(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-label':
|
||||
specifier: ^2.0.2
|
||||
version: 2.0.2(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
|
||||
@@ -2411,6 +2414,87 @@ packages:
|
||||
'@babel/runtime': 7.23.5
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-accordion@1.1.2(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-fDG7jcoNKVjSK6yfmuAs0EnPDro0WMXIhMtXdTBWqEioVW206ku+4Lw07e+13lUkFkpoEQ2PdeMIAGpdqEAmDg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.5
|
||||
'@radix-ui/primitive': 1.0.1
|
||||
'@radix-ui/react-collapsible': 1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@radix-ui/react-context': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@radix-ui/react-direction': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@radix-ui/react-id': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@types/react': 18.2.37
|
||||
'@types/react-dom': 18.2.15
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-collapsible@1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.5
|
||||
'@radix-ui/primitive': 1.0.1
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@radix-ui/react-context': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@radix-ui/react-id': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@types/react': 18.2.37
|
||||
'@types/react-dom': 18.2.15
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.5
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@radix-ui/react-context': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.37)(react@18.2.0)
|
||||
'@types/react': 18.2.37
|
||||
'@types/react-dom': 18.2.15
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.37)(react@18.2.0):
|
||||
resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
|
||||
peerDependencies:
|
||||
@@ -2439,6 +2523,35 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-direction@1.0.1(@types/react@18.2.37)(react@18.2.0):
|
||||
resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.5
|
||||
'@types/react': 18.2.37
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-id@1.0.1(@types/react@18.2.37)(react@18.2.0):
|
||||
resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.5
|
||||
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@types/react': 18.2.37
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-label@2.0.2(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==}
|
||||
peerDependencies:
|
||||
@@ -2460,6 +2573,28 @@ packages:
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.5
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.37)(react@18.2.0)
|
||||
'@types/react': 18.2.37
|
||||
'@types/react-dom': 18.2.15
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==}
|
||||
peerDependencies:
|
||||
|
||||
@@ -26,6 +26,8 @@ const storage = new Storage({
|
||||
area: "local"
|
||||
})
|
||||
|
||||
export const getRules = () => storage.get("rules")
|
||||
|
||||
export const getRSS = async (tabId, url) => {
|
||||
console.debug("Get RSS", tabId, url)
|
||||
|
||||
@@ -52,7 +54,7 @@ export const getRSS = async (tabId, url) => {
|
||||
tabId,
|
||||
html,
|
||||
url,
|
||||
rules: await storage.get("rules"),
|
||||
rules: await getRules(),
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { PlasmoMessaging } from "@plasmohq/messaging"
|
||||
import { getRSS } from "~/background"
|
||||
|
||||
const handler: PlasmoMessaging.MessageHandler = async (req, res) => {
|
||||
const handler: PlasmoMessaging.MessageHandler = (req) => {
|
||||
console.debug("content ready", req)
|
||||
|
||||
getRSS(req.sender.tab.id, req.sender.tab.url)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { PlasmoMessaging } from "@plasmohq/messaging"
|
||||
import { getCachedRSS } from "~/background"
|
||||
|
||||
const handler: PlasmoMessaging.MessageHandler = async (req, res) => {
|
||||
const handler: PlasmoMessaging.MessageHandler = (req, res) => {
|
||||
console.debug("popup ready", req)
|
||||
|
||||
chrome.tabs.query({
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { PlasmoMessaging } from "@plasmohq/messaging"
|
||||
import { getRules } from "~/background"
|
||||
|
||||
const handler: PlasmoMessaging.MessageHandler = async (req, res) => {
|
||||
console.debug("request rules", req)
|
||||
|
||||
res.send(await getRules())
|
||||
}
|
||||
|
||||
export default handler
|
||||
@@ -0,0 +1,58 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as AccordionPrimitive from "@radix-ui/react-accordion"
|
||||
import { ChevronDown } from "lucide-react"
|
||||
|
||||
import { cn } from "~/lib/utils"
|
||||
|
||||
const Accordion = AccordionPrimitive.Root
|
||||
|
||||
const AccordionItem = React.forwardRef<
|
||||
React.ElementRef<typeof AccordionPrimitive.Item>,
|
||||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<AccordionPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn("border-b", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
AccordionItem.displayName = "AccordionItem"
|
||||
|
||||
const AccordionTrigger = React.forwardRef<
|
||||
React.ElementRef<typeof AccordionPrimitive.Trigger>,
|
||||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<AccordionPrimitive.Header className="flex">
|
||||
<AccordionPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex flex-1 items-center justify-between py-4 font-medium transition-all [&[data-state=open]>svg]:rotate-180",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
|
||||
</AccordionPrimitive.Trigger>
|
||||
</AccordionPrimitive.Header>
|
||||
))
|
||||
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
|
||||
|
||||
const AccordionContent = React.forwardRef<
|
||||
React.ElementRef<typeof AccordionPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<AccordionPrimitive.Content
|
||||
ref={ref}
|
||||
className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
|
||||
{...props}
|
||||
>
|
||||
<div className={cn("pb-4 pt-0", className)}>{children}</div>
|
||||
</AccordionPrimitive.Content>
|
||||
))
|
||||
|
||||
AccordionContent.displayName = AccordionPrimitive.Content.displayName
|
||||
|
||||
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
|
||||
+4
-21
@@ -1,12 +1,13 @@
|
||||
import _ from 'lodash';
|
||||
import { defaultRules } from './radar-rules';
|
||||
import { defaultConfig } from './config';
|
||||
import type { Rules } from './types';
|
||||
|
||||
export function parseRules(rules) {
|
||||
export function parseRules(rules: string, forceJSON?: boolean) {
|
||||
let incomeRules = rules;
|
||||
if (incomeRules) {
|
||||
if (typeof rules === 'string') {
|
||||
if (defaultConfig.enableFullRemoteRules) {
|
||||
if (defaultConfig.enableFullRemoteRules && !forceJSON) {
|
||||
incomeRules = window['lave'.split('').reverse().join('')](rules);
|
||||
} else {
|
||||
incomeRules = JSON.parse(rules);
|
||||
@@ -19,23 +20,5 @@ export function parseRules(rules) {
|
||||
} else if (_.isFunction(objValue)) {
|
||||
return objValue;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function getList(data) {
|
||||
const rules = parseRules(data.rules);
|
||||
for (const rule in rules) {
|
||||
for (const subrule in rules[rule]) {
|
||||
if (subrule[0] !== '_') {
|
||||
rules[rule][subrule].forEach((item) => {
|
||||
delete item.source;
|
||||
delete item.target;
|
||||
delete item.script;
|
||||
delete item.verification;
|
||||
delete item.test;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return rules;
|
||||
}) as Rules;
|
||||
}
|
||||
|
||||
@@ -73,4 +73,8 @@
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
|
||||
.content a {
|
||||
@apply underline text-orange-500;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,15 @@
|
||||
import { defaultConfig, setConfig } from "~/lib/config"
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "~/lib/components/Card"
|
||||
import { Switch } from "~/lib/components/Switch"
|
||||
import { quickSubscriptions } from "~/lib/quick-subscriptions"
|
||||
import { useStorage } from "@plasmohq/storage/hook"
|
||||
import _ from 'lodash';
|
||||
|
||||
function About() {
|
||||
const [config] = useStorage("config", (v) => _.merge({}, defaultConfig, v))
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-3xl font-medium leading-10 mb-6 text-orange-500 border-b pb-4">{chrome.i18n.getMessage("about")}</h1>
|
||||
<div className="space-y-4">
|
||||
<Card>
|
||||
<CardContent className="space-y-4 content">
|
||||
<style>{
|
||||
`
|
||||
.content a {
|
||||
text-decoration-line: underline;
|
||||
color: rgb(249 115 22);
|
||||
}
|
||||
`
|
||||
}</style>
|
||||
<CardContent className="space-y-4 content text-zinc-700 py-10">
|
||||
<p dangerouslySetInnerHTML={{
|
||||
__html: chrome.i18n.getMessage("RSSHubRadarInfo")
|
||||
}}></p>
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
import _ from "lodash"
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
import { sendToBackground } from "@plasmohq/messaging"
|
||||
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger
|
||||
} from "~/lib/components/Accordion"
|
||||
import { Card, CardContent } from "~/lib/components/Card"
|
||||
import { parseRules } from "~/lib/rules"
|
||||
import type { Rules as IRules } from "~/lib/types"
|
||||
|
||||
function Rules() {
|
||||
const [rules, setRules] = useState<IRules>({})
|
||||
useEffect(() => {
|
||||
sendToBackground({
|
||||
name: "requestRules"
|
||||
}).then((res) => setRules(parseRules(res, true)))
|
||||
}, [])
|
||||
|
||||
const [count, setCount] = useState(0)
|
||||
useEffect(() => {
|
||||
let index = 0;
|
||||
Object.keys(rules).map((key) => {
|
||||
const rule = rules[key]
|
||||
Object.keys(rule).map((item) => {
|
||||
if (Array.isArray(rule[item])) {
|
||||
index += rule[item].length
|
||||
}
|
||||
})
|
||||
})
|
||||
setCount(index)
|
||||
}, [rules])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-3xl font-medium leading-10 mb-6 text-orange-500 border-b pb-4">
|
||||
{chrome.i18n.getMessage("rules")}
|
||||
</h1>
|
||||
<div className="content mb-6 space-y-2">
|
||||
<p>{chrome.i18n.getMessage("totalNumberOfRules")}: {count}</p>
|
||||
<p dangerouslySetInnerHTML={{
|
||||
__html: chrome.i18n.getMessage("forMoreRulesJoinUs")
|
||||
}}></p>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<Card>
|
||||
<CardContent>
|
||||
{Object.keys(rules).map((key) => {
|
||||
const rule = rules[key]
|
||||
return (
|
||||
<div key={key}>
|
||||
<Accordion type="single" collapsible>
|
||||
<AccordionItem value="item-1">
|
||||
<AccordionTrigger>
|
||||
<div className="font-medium">
|
||||
{rule._name} - {key}
|
||||
</div>
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
<div className="space-y-2">
|
||||
{Object.keys(rule).map((item) => {
|
||||
const subdomainRules = rule[item]
|
||||
if (Array.isArray(subdomainRules)) {
|
||||
return subdomainRules.map(
|
||||
(subdomainRule, index) => {
|
||||
return (
|
||||
<div key={key + item + index}>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="flex-1">
|
||||
<p className="text-sm text-zinc-700">
|
||||
{subdomainRule.title}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export { Rules }
|
||||
@@ -1,11 +1,13 @@
|
||||
import { Route, Routes } from "react-router-dom"
|
||||
|
||||
import { About } from "./About"
|
||||
import { Rules } from "./Rules"
|
||||
import { General } from "./General"
|
||||
|
||||
export const Routing = () => (
|
||||
<Routes>
|
||||
<Route path="/" element={<General />} />
|
||||
<Route path="/rules" element={<Rules />} />
|
||||
<Route path="/about" element={<About />} />
|
||||
</Routes>
|
||||
)
|
||||
@@ -24,6 +24,20 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
extend: {
|
||||
keyframes: {
|
||||
"accordion-down": {
|
||||
from: { height: "0" },
|
||||
to: { height: "var(--radix-accordion-content-height)" },
|
||||
},
|
||||
"accordion-up": {
|
||||
from: { height: "var(--radix-accordion-content-height)" },
|
||||
to: { height: "0" },
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
"accordion-down": "accordion-down 0.2s ease-out",
|
||||
"accordion-up": "accordion-up 0.2s ease-out",
|
||||
},
|
||||
colors: {
|
||||
border: "hsl(var(--border))",
|
||||
input: "hsl(var(--input))",
|
||||
|
||||
Reference in New Issue
Block a user