Skip to content

Commit 9b1f3b7

Browse files
authoredOct 24, 2024··
Merge pull request #49 from TheSevenPlusPlus/v2/fixbug
V2/fixbug
2 parents 09aa2a2 + af488da commit 9b1f3b7

31 files changed

+497
-457
lines changed
 

‎FU.OJ.Server/Controllers/AuthController.cs

+251-270
Large diffs are not rendered by default.

‎FU.OJ.Server/Controllers/ContestController.cs

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public async Task<IActionResult> CreateContestAsync([FromBody] CreateContestRequ
3636
}
3737

3838
[HttpGet(ContestRoute.Action.GetByCode)]
39+
[AllowAnonymous]
3940
public async Task<IActionResult> GetContestByCodeAsync([FromRoute] string contestCode)
4041
{
4142
try
@@ -123,6 +124,7 @@ public async Task<IActionResult> GetContestParticipant([FromRoute] string contes
123124
}
124125

125126
[HttpGet(ContestRoute.Action.IsRegistered)]
127+
[AllowAnonymous]
126128
public async Task<IActionResult> IsRegistered([FromRoute] string contestCode)
127129
{
128130
try

‎FU.OJ.Server/Controllers/SubmissionController.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ public async Task<IActionResult> SubmitCode([FromBody] CreateSubmissionRequest r
2020
return HandleException(ex);
2121
}
2222
} [HttpGet(SubmissionRoute.Action.Get)]
23+
[AllowAnonymous]
2324
public async Task<IActionResult> GetSubmissionDetails([FromRoute] string id)
2425
{
2526
try
2627
{
27-
SubmissionView submission = await _submissionService.GetByIdAsync(UserHeader.UserId, id);
28+
SubmissionView submission = await _submissionService.GetByIdAsync(UserHeader.UserId, UserHeader.Role, id);
2829
return Ok(submission);
2930
}
3031
catch (Exception ex)

‎FU.OJ.Server/Controllers/UserController.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ public async Task<IActionResult> GetAllUsers([FromQuery] Paging query)
8282
}
8383
}
8484
[Authorize(Roles = RoleAuthorize.OnlyAdmin)]
85-
[HttpGet(UserRoute.Action.GetDetail)]
86-
public async Task<IActionResult> GetUserByUserName()
85+
[HttpGet(UserRoute.Action.GetByUsername)]
86+
public async Task<IActionResult> GetUserByUserName([FromRoute] string userName)
8787
{
88-
var user = await _userService.GetUserByIdAsync(UserHeader.UserId);
88+
var user = await _userService.GetUserByUsernameAsync(userName);
8989
if (user == null) return NotFound("Không tìm thấy người dùng");
9090

9191
var userResponse = new UserView

‎FU.OJ.Server/Service/ContestService.cs

+1
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ public async Task<List<ContestParticipantView>> GetRank(string contestCode)
437437
ContestCode = participant.ContestCode,
438438
Score = participant.Score
439439
})
440+
.OrderByDescending(participant => participant.Score)
440441
.ToListAsync();
441442

442443
// Step 2: Fetch contest problems for the contest code

‎FU.OJ.Server/Service/SubmissionService.cs

+3-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace FU.OJ.Server.Service
1414
public interface ISubmissionService
1515
{
1616
Task<string> CreateAsync(string userId, CreateSubmissionRequest request, string? contestCode = null, bool? base64Encoded = false, bool? wait = true); //
17-
Task<SubmissionView> GetByIdAsync(string userId, string id);//
17+
Task<SubmissionView> GetByIdAsync(string userId, string userRole, string id);//
1818
Task<(List<SubmissionView> submissions, int totalPages)> GetAllSubmissionsAsync(Paging query, string? problemCode = null, string? userId = null, string? isMine = "false", string? contestCode = "null");//
1919
}
2020

@@ -216,7 +216,7 @@ public async Task<string> GetByTokenAsync(string token, bool base64Encoded = fal
216216
return submission;
217217
}
218218

219-
public async Task<SubmissionView> GetByIdAsync(string userId, string id)
219+
public async Task<SubmissionView> GetByIdAsync(string userId, string userRole, string id)
220220
{
221221
var submission = await _context.Submissions
222222
.Where(s => s.Id == id)
@@ -228,14 +228,13 @@ public async Task<SubmissionView> GetByIdAsync(string userId, string id)
228228
throw new Exception(ErrorMessage.NotFound);
229229

230230
bool isAc = await _problemService.IsAccepted(userId, submission.ProblemId);
231-
var (userName, role) = await _generalService.GetUserRoleByUserIdAsync(userId);
232231

233232
return new SubmissionView
234233
{
235234
Id = submission.Id,
236235
ProblemId = submission.ProblemId,
237236
ProblemName = submission.ProblemCode,
238-
SourceCode = (submission.UserId == userId || isAc == true || role == "Admin") ? submission.SourceCode : null,
237+
SourceCode = (submission.UserId == userId || isAc == true || userRole == "Admin") ? submission.SourceCode : null,
239238
LanguageName = submission.LanguageName,
240239
SubmittedAt = submission.SubmittedAt,
241240
UserName = submission.UserName,

‎fu.oj.client/src/components/Auth/ForgotPassword.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/com
66
import { Alert, AlertDescription } from "@/components/ui/alert";
77
import { forgotPassword } from "../../api/auth";
88
import { Helmet } from 'react-helmet-async';
9+
import Loading from "../Loading"
910

1011
const ForgotPassword: React.FC = () => {
1112
const [email, setEmail] = useState('');
@@ -50,6 +51,10 @@ const ForgotPassword: React.FC = () => {
5051
}
5152
};
5253

54+
if (isLoading) {
55+
return < Loading />;
56+
}
57+
5358
return (
5459
<Card className="w-[350px] mx-auto mt-20">
5560
<Helmet>

‎fu.oj.client/src/components/Auth/ResetPassword.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { resetPassword } from '../../api/auth';
88
import { Eye, EyeOff } from 'lucide-react';
99
import { Alert, AlertDescription } from "@/components/ui/alert";
1010
import { Helmet } from 'react-helmet-async';
11+
import Loading from "../Loading"
1112

1213
const ResetPassword: React.FC = () => {
1314
const [email, setEmail] = useState('');
@@ -77,6 +78,10 @@ const ResetPassword: React.FC = () => {
7778
setShowPassword(!showPassword);
7879
};
7980

81+
if (isLoading) {
82+
return < Loading />;
83+
}
84+
8085
return (
8186
<>
8287
<Helmet>

‎fu.oj.client/src/components/Blog/BlogList.tsx

+2-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import ItemsPerPageSelector from '../Pagination/ItemsPerPageSelector';
1515
import { UserView } from "../../models/UserDTO";
1616
import { getProfile } from "../../api/profile";
1717
import { Helmet } from "react-helmet-async";
18+
import Loading from "../Loading";
1819

1920
interface Blog {
2021
id: number;
@@ -72,12 +73,7 @@ export default function BlogList() {
7273
};
7374

7475
if (loading) {
75-
return (
76-
<div className="flex flex-col items-center justify-center h-full">
77-
<div className="animate-spin rounded-full h-32 w-32 border-b-2 border-primary"></div>
78-
<p className="text-center text-lg mt-4">Loading blogs...</p>
79-
</div>
80-
);
76+
return < Loading />;
8177
}
8278

8379
if (error) {

‎fu.oj.client/src/components/Blog/BlogPost.tsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { BlogDetail } from "../../models/BlogDTO";
1515
import ItemsPerPageSelector from '../Pagination/ItemsPerPageSelector';
1616
import Pagination from '../Pagination/Pagination';
1717
import { Helmet } from "react-helmet-async";
18-
18+
import Loading from "../Loading"
1919
export default function BlogPost() {
2020
const { blog_id } = useParams<{ blog_id: string }>();
2121
const navigate = useNavigate();
@@ -58,7 +58,10 @@ export default function BlogPost() {
5858
fetchData();
5959
}, [blog_id, pageIndex, pageSize]);
6060

61-
if (loading) return <div>Loading...</div>;
61+
if (loading) {
62+
return < Loading />;
63+
}
64+
6265
if (error) return <div>{error}</div>;
6366
if (!blogPost) return <div>Blog post not found</div>;
6467

‎fu.oj.client/src/components/Contest/ContestHome.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Button } from "@/components/ui/button";
66
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card";
77
import { ContestNavbar } from "./ContestNavbar";
88
import { Helmet } from "react-helmet-async";
9+
import Loading from "../Loading"
910

1011
export function ContestHome() {
1112
const { contestCode } = useParams<{ contestCode: string }>();
@@ -53,7 +54,10 @@ export function ContestHome() {
5354
}
5455
};
5556

56-
if (loading) return <div>Loading contest...</div>;
57+
if (loading) {
58+
return < Loading />;
59+
}
60+
5761
if (error) return <div>{error}</div>;
5862
if (!contest) return <div>No contest found</div>;
5963

‎fu.oj.client/src/components/Contest/ContestList.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import ItemsPerPageSelector from '../Pagination/ItemsPerPageSelector';
2121
import { getAllContests, deleteContest } from "../../api/contest"; // Import API methods
2222
import { ContestView } from "../../models/ContestModel"
2323
import { Helmet } from "react-helmet-async";
24+
import Loading from "../Loading"
2425

2526
const ContestList: React.FC = () => {
2627
const navigate = useNavigate();
@@ -83,7 +84,10 @@ const ContestList: React.FC = () => {
8384
});
8485
};
8586

86-
if (loading) return <div>Loading...</div>;
87+
if (loading) {
88+
return < Loading />;
89+
}
90+
8791
if (error) return <div>Error: {error}</div>;
8892

8993
return (

‎fu.oj.client/src/components/Contest/ContestProblem.tsx

+2-6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import ItemsPerPageSelector from '../Pagination/ItemsPerPageSelector';
1717
import { ContestNavbar } from "./ContestNavbar";
1818
import { ContestView } from "../../models/ContestModel";
1919
import { Helmet } from "react-helmet-async";
20+
import Loading from "../Loading"
2021

2122
export default function ContestProblem() {
2223
const navigate = useNavigate();
@@ -89,12 +90,7 @@ export default function ContestProblem() {
8990
};
9091

9192
if (loading) {
92-
return (
93-
<div className="flex flex-col items-center justify-center h-full">
94-
<div className="spinner"></div>
95-
<p className="text-center text-lg mt-2">Loading problems...</p>
96-
</div>
97-
);
93+
return < Loading />;
9894
}
9995

10096
if (error) {

‎fu.oj.client/src/components/Contest/ContestRank.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { getRank, getContestByCode, isRegisteredContest } from "../../api/contes
44
import { ContestParticipantView, ContestView } from "../../models/ContestModel";
55
import { ContestNavbar } from "./ContestNavbar";
66
import { Helmet } from "react-helmet-async";
7-
7+
import Loading from "../Loading"
88
export function ContestRank() {
99
const { contestCode } = useParams<{ contestCode: string }>();
1010
const [rankings, setRankings] = useState<ContestParticipantView[]>([]);
@@ -57,7 +57,9 @@ export function ContestRank() {
5757
fetchRankings();
5858
}, [contestCode]);
5959

60-
if (loading) return <div className="text-center py-10 text-xl">Loading contest...</div>;
60+
if (loading) {
61+
return < Loading />;
62+
}
6163
if (error) return <div className="text-center py-10 text-xl text-red-600">{error}</div>;
6264

6365
return (
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
3+
4+
import { Loader2 } from "lucide-react"
5+
6+
export default function Loading() {
7+
return (
8+
<div className="fixed inset-0 flex items-center justify-center">
9+
<Loader2 className="h-12 w-12 animate-spin text-primary" />
10+
</div>
11+
)
12+
}

‎fu.oj.client/src/components/Management/Blog/BlogForm.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { BlogDetail, CreateBlogRequest, UpdateBlogRequest } from '../../../model
77
import { createBlog, updateBlog, getBlogById } from '../../../api/blog';
88
import { useToast } from '../../../hooks/use-toast';
99
import { Helmet } from 'react-helmet-async';
10-
10+
import Loading from "../../Loading"
1111
interface BlogFormProps {
1212
blog?: BlogDetail | null;
1313
}
@@ -116,7 +116,7 @@ export default function BlogForm({ blog: initialBlog }: BlogFormProps) {
116116
};
117117

118118
if (isLoading) {
119-
return <div className="mt-8 flex justify-center">Loading...</div>;
119+
return < Loading />;
120120
}
121121

122122
return (

‎fu.oj.client/src/components/Management/Blog/BlogManagement.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { Toast } from "./Toast";
1010
import { getAllBlogs, deleteBlog } from "../../../api/blog";
1111
import { BlogDetail, GetAllBlogsResponse } from "../../../models/BlogDTO";
1212
import { Helmet } from "react-helmet-async";
13-
13+
import Loading from "../../Loading"
1414
export default function BlogManagement() {
1515
const [blogs, setBlogs] = useState<BlogDetail[]>([]);
1616
const [currentPage, setCurrentPage] = useState<number>(1);
@@ -61,6 +61,10 @@ export default function BlogManagement() {
6161
navigate(`/blog/${id}`);
6262
};
6363

64+
if (isLoading) {
65+
return < Loading />;
66+
}
67+
6468
return (
6569
<Card className="w-full max-w-4xl mx-auto">
6670
<Helmet>

‎fu.oj.client/src/components/Management/Contest/ContestManagement.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import ItemsPerPageSelector from '../../Pagination/ItemsPerPageSelector';
2121
import { getAllContests, deleteContest } from "../../../api/contest"; // Import API methods
2222
import { ContestView } from "../../../models/ContestModel"
2323
import { Helmet } from "react-helmet-async";
24+
import Loading from "../../Loading"
2425

2526
const ContestManagement: React.FC = () => {
2627
const navigate = useNavigate();
@@ -83,7 +84,9 @@ const ContestManagement: React.FC = () => {
8384
});
8485
};
8586

86-
if (loading) return <div>Loading...</div>;
87+
if (loading) {
88+
return < Loading />;
89+
}
8790
if (error) return <div>Error: {error}</div>;
8891

8992
return (

‎fu.oj.client/src/components/Management/Problem/CreateProblem.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ const CreateProblem: React.FC = () => {
189189
<Label>Example Input {index + 1}</Label>
190190
<Textarea
191191
value={example.input}
192-
onChange={(e) => handleExampleChange(index, 'exampleInput', e.target.value)}
192+
onChange={(e) => handleExampleChange(index, 'input', e.target.value)} // đổi 'exampleInput' thành 'input'
193193
placeholder="Enter example input"
194194
rows={2}
195195
required
@@ -199,7 +199,7 @@ const CreateProblem: React.FC = () => {
199199
<Label>Example Output {index + 1}</Label>
200200
<Textarea
201201
value={example.output}
202-
onChange={(e) => handleExampleChange(index, 'exampleOutput', e.target.value)}
202+
onChange={(e) => handleExampleChange(index, 'output', e.target.value)} // đổi 'exampleOutput' thành 'output'
203203
placeholder="Enter example output"
204204
rows={2}
205205
required

‎fu.oj.client/src/components/Management/Problem/ProblemManagement.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ import Pagination from '../../Pagination/Pagination';
3535
import ItemsPerPageSelector from '../../Pagination/ItemsPerPageSelector';
3636
import { Badge } from "@/components/ui/badge";
3737
import { Helmet } from "react-helmet-async";
38+
import Loading from "../../Loading"
39+
3840
interface Problem {
3941
id: string;
4042
code: string;
@@ -117,7 +119,10 @@ const ProblemManagement: React.FC = () => {
117119
return hasSolution ? <i className="fas fa-check-circle text-green-500"></i> : null;
118120
};
119121

120-
if (loading) return <div>Loading...</div>;
122+
if (loading) {
123+
return < Loading />;
124+
}
125+
121126
if (error) return <div>Error: {error}</div>;
122127

123128
return (

0 commit comments

Comments
 (0)
Please sign in to comment.