Skip to content

Commit bdb93b2

Browse files
committed
feat(repository): Optimize time display format and add repository clone function
1 parent 98c77d0 commit bdb93b2

File tree

5 files changed

+102
-19
lines changed

5 files changed

+102
-19
lines changed

script/nginx.conf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ http {
3838
proxy_read_timeout 60s;
3939
}
4040

41+
location /git/ {
42+
proxy_pass http://localhost:8080;
43+
proxy_set_header Host $host;
44+
proxy_set_header X-Real-IP $remote_addr;
45+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
46+
proxy_set_header X-Forwarded-Proto $scheme;
47+
proxy_connect_timeout 60s;
48+
proxy_send_timeout 60s;
49+
proxy_read_timeout 60s;
50+
}
51+
4152
location / {
4253
try_files $uri $uri/ /index.html;
4354
}

views/src/app/repository/files.tsx

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ export const RepoFiles = () => {
173173
<div className="flex items-center">
174174
{commits[idx] && (
175175
<>
176-
{new Date(commits[idx].timestamp * 1000).toString()}
176+
{getTimeStr(commits[idx].timestamp * 1000)}
177177
</>
178178
)}
179179
</div>
@@ -276,4 +276,27 @@ export const RepoFiles = () => {
276276
</div>
277277
</div>
278278
);
279-
};
279+
};
280+
281+
282+
export function getTimeStr(timestamp:number) {
283+
const now = new Date();
284+
const date = new Date(timestamp);
285+
// @ts-ignore
286+
const diff = (now - date) / 1000;
287+
288+
if (diff < 60) {
289+
return "just";
290+
} else if (diff < 3600) {
291+
return Math.floor(diff / 60) + " minutes ago";
292+
} else if (diff < 86400) {
293+
return Math.floor(diff / 3600) + " hours ago";
294+
} else if (diff < 604800) {
295+
return Math.floor(diff / 86400) + " days ago";
296+
} else {
297+
const year = date.getFullYear();
298+
const month = date.getMonth() + 1;
299+
const day = date.getDate();
300+
return `${year}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day : day}`;
301+
}
302+
}

views/src/app/repository/layout.tsx

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ import { useEffect, useState } from "react";
22
import {Outlet, useNavigate, useParams,} from "react-router-dom";
33
import { HeaderShell } from "@/component/shell/Header.tsx";
44
import axios from "axios";
5-
import { Tabs } from "@mantine/core";
5+
import {Tabs} from "@mantine/core";
66
import { Box, Card, Text, Button, Group } from "@mantine/core";
7-
import { AlertCircle, Loader2 } from "lucide-react";
7+
import {AlertCircle, CopyIcon, Loader2} from "lucide-react";
8+
import {useClipboard} from "@mantine/hooks";
9+
import {notifications} from "@mantine/notifications";
810

911
interface RepoApiResponse {
1012
code: number;
@@ -42,6 +44,7 @@ export const Repolayout = () => {
4244
const [repoData, setRepoData] = useState<RepoData | null>(null);
4345
const nav = useNavigate();
4446
const [type, setType] = useState('files');
47+
const clip = useClipboard()
4548
useEffect(() => {
4649
const urls = window.location.href.split("/");
4750
setType("files")
@@ -121,19 +124,56 @@ export const Repolayout = () => {
121124
}
122125

123126
const { repo: repository } = repoData;
127+
128+
function copyText(arg0: string) {
129+
clip.copy(arg0)
130+
notifications.show({
131+
message: "Copy Success",
132+
color: "green"
133+
})
134+
}
135+
124136
return (
125137
<>
126138
<HeaderShell />
127139
<Box mt={64} p={4} style={{ maxWidth: '1200px', margin: '0 auto', width: '100%' }}>
128-
<Card mb={4}>
140+
<Card mb={4} >
129141
<Box p={4}>
130142
<Group justify="space-between" mb={2}>
131143
<Text size="2xl">{owner}/{repository.name}</Text>
132144
<Text color="dimmed">
133145
{new Date(repository.updated_at).toLocaleDateString()}
134146
</Text>
135147
</Group>
136-
<Text color="dimmed" mb={4}>{repository.description || 'No description provided'}</Text>
148+
<Box style={{
149+
justifyContent: "space-between",
150+
display: "flex",
151+
alignItems: "center",
152+
}}>
153+
<Text color="dimmed" mb={4}>{repository.description || 'No description provided'}</Text>
154+
<div style={{
155+
display: "flex",
156+
alignItems: "center",
157+
gap: "1rem",
158+
}}>
159+
<div style={{
160+
border: "1px solid #ccc",
161+
borderRadius: "4px",
162+
padding: "0.5rem",
163+
display: "flex",
164+
backgroundColor: "#f5f5f5",
165+
alignItems: "center",
166+
justifyContent: "space-between",
167+
marginBottom: "0.5rem",
168+
gap: "0.5rem"
169+
}}>
170+
{window.location.protocol + "//"}{window.location.host + "/git/" + owner + "/" + repository.name + ".git"}
171+
<CopyIcon onClick={() => {
172+
copyText(window.location.protocol + "//" + window.location.host + "/git/" + owner + "/" + repository.name + ".git");
173+
}}/>
174+
</div>
175+
</div>
176+
</Box>
137177
</Box>
138178
</Card>
139179
<Tabs defaultValue={type} value={type} onChange={(value) => {

views/src/app/root/RepoList.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {Input, Pagination} from "@mantine/core";
22
import {useEffect, useState} from "react";
33
import axios from "axios";
44
import {useNavigate} from "react-router-dom";
5+
import {getTimeStr} from "@/app/repository/files.tsx";
56
export interface RepoListTypes {
67
name: string,
78
description: string,
@@ -98,10 +99,10 @@ export const RootRepoList = () => {
9899
color: '#999'
99100
}}>
100101
<span>
101-
Created: {new Date(repo.created_at).toString()}
102+
Created: {getTimeStr(new Date(repo.created_at).getTime())}
102103
</span>
103104
<span>
104-
Updated: {new Date(repo.updated_at).toString()}
105+
Updated: {getTimeStr(new Date(repo.updated_at).getTime())}
105106
</span>
106107
</div>
107108
</div>

views/src/component/shell/Header.tsx

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {Link, useNavigate} from "react-router-dom";
22
import useUserContext from "@/store/useUserContext.tsx";
3-
import {useEffect} from "react";
3+
import {useEffect, useState} from "react";
44
import {Button} from "@mantine/core";
55

66
export const HeaderShell = () => {
@@ -9,6 +9,10 @@ export const HeaderShell = () => {
99
useEffect(() => {
1010
user.refresh();
1111
}, []);
12+
const [Width, setWidth] = useState(window.innerWidth);
13+
useEffect(() => {
14+
setWidth(window.innerWidth)
15+
}, [window.innerWidth]);
1216
return(
1317
<div style={{
1418
background: "white",
@@ -17,16 +21,20 @@ export const HeaderShell = () => {
1721
display: "flex",
1822
borderBottom: "0.1rem solid rgb(217, 217, 217)",
1923
}}>
20-
<div style={{
21-
display: "flex",
22-
justifyContent: "center",
23-
alignItems: "center",
24-
padding: "0 1rem",
25-
}}>
26-
<img src="/jzflow-logo-rust.png" alt="logo" style={{
27-
height: "32px",
28-
}}/>
29-
</div>
24+
{
25+
Width > 768 && (
26+
<div style={{
27+
display: "flex",
28+
justifyContent: "center",
29+
alignItems: "center",
30+
padding: "0 1rem",
31+
}}>
32+
<img src="/jzflow-logo-rust.png" alt="logo" style={{
33+
height: "32px",
34+
}}/>
35+
</div>
36+
)
37+
}
3038
<div style={{
3139
display: "flex",
3240
alignItems: "center",

0 commit comments

Comments
 (0)