初始化
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
.index {
|
||||
position: relative;
|
||||
.actions {
|
||||
position: fixed;
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.action + .action {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.action {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--color-primary);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0px 1px 2px -2px rgba($color: #000000, $alpha: 0.16);
|
||||
transition: all 0.3s;
|
||||
&:hover {
|
||||
// background-color: rgba($color: var(--color-primary), $alpha: 0.9);
|
||||
box-shadow: 0px 5px 12px 4px rgba($color: #000000, $alpha: 0.09);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
padding-bottom: 100px;
|
||||
.item,
|
||||
.item > .lbox,
|
||||
.item > .rbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.item + .item {
|
||||
border-top: 1px solid #efefef;
|
||||
}
|
||||
.item {
|
||||
line-height: 1;
|
||||
padding: 24px 16px;
|
||||
color: #999;
|
||||
&:hover {
|
||||
background: rgba($color: var(--color-primary), $alpha: 0.09);
|
||||
}
|
||||
.lbox {
|
||||
flex: 1;
|
||||
> * + * {
|
||||
margin-left: 16px;
|
||||
}
|
||||
.state {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background-color: #dfdfdf;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.name {
|
||||
font-weight: bold;
|
||||
}
|
||||
.url {
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
&:hover {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rbox {
|
||||
margin: -8px;
|
||||
button {
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 0;
|
||||
color: var(--color-primary);
|
||||
margin: 8px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
.del {
|
||||
color: var(--color-third);
|
||||
}
|
||||
button:disabled {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #333;
|
||||
.lbox {
|
||||
.state {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import classNames from 'classnames'
|
||||
import { Observer } from 'mobx-react'
|
||||
import React from 'react'
|
||||
import { Icon } from '../../components/icon'
|
||||
import { NatState } from '../../model/nat'
|
||||
import { StoreServer } from '../../store/server'
|
||||
import styles from './index.module.scss'
|
||||
|
||||
export const IndexPage = () => {
|
||||
return (
|
||||
<Observer>
|
||||
{() => (
|
||||
<div className={styles.index}>
|
||||
<div className={styles.actions}>
|
||||
<div
|
||||
className={styles.action}
|
||||
onClick={() => utools.shellOpenExternal('https://github.com/lblblong/nat-utools')}
|
||||
>
|
||||
<Icon value="github-line" />
|
||||
</div>
|
||||
<div className={styles.action} onClick={() => StoreServer.openHelp()}>
|
||||
<Icon value="question-mark" />
|
||||
</div>
|
||||
<div className={styles.action} onClick={() => StoreServer.add()}>
|
||||
<Icon value="add-line" />
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.list}>
|
||||
{StoreServer.natList.map((it) => {
|
||||
return (
|
||||
<div className={classNames(styles.item, { [styles.active]: it.state === NatState.on })} key={it.id}>
|
||||
<div className={styles.lbox}>
|
||||
<span className={styles.state}></span>
|
||||
<span className={styles.name}>
|
||||
{it.port}
|
||||
{it.subdomain ? ` - ${it.subdomain}` : ''}
|
||||
</span>
|
||||
<span className={styles.url}>{it.url}</span>
|
||||
</div>
|
||||
|
||||
<div className={styles.rbox}>
|
||||
<button
|
||||
disabled={it.state === NatState.loading}
|
||||
className={classNames(styles.btn, styles.del)}
|
||||
onClick={() => StoreServer.del(it.id)}
|
||||
>
|
||||
删除
|
||||
</button>
|
||||
<button
|
||||
disabled={it.state === NatState.loading}
|
||||
className={classNames(styles.btn)}
|
||||
onClick={() => StoreServer.edit(it.id)}
|
||||
>
|
||||
编辑
|
||||
</button>
|
||||
<button className={classNames(styles.btn)} onClick={() => StoreServer.showLog(it.id)}>
|
||||
查看日志
|
||||
</button>
|
||||
<button
|
||||
disabled={!it.url}
|
||||
className={classNames(styles.btn)}
|
||||
onClick={() => {
|
||||
utools.copyText(it.url!)
|
||||
utools.showNotification('地址已成功复制到剪切板')
|
||||
}}
|
||||
>
|
||||
复制地址
|
||||
</button>
|
||||
<button
|
||||
disabled={it.state === NatState.loading}
|
||||
className={styles.btn}
|
||||
onClick={() => StoreServer.toggle(it.id)}
|
||||
>
|
||||
{it.state === NatState.on ? '关闭服务' : '启动服务'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Observer>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user