33 < head >
44 < meta charset ="utf-8 " />
55 < meta name ="viewport " content ="width=device-width, initial-scale=1, shrink-to-fit=no " />
6- < meta name ="description " content / >
7- < meta name ="author " content / >
8- < title > Modern Business - Start Bootstrap Template </ title >
6+ < meta name ="description " content =" Contact Tran Huu Dat for collaborations or inquiries. " /> <!-- Cập nhật -- >
7+ < meta name ="author " content =" Tran Huu Dat " /> <!-- Cập nhật -- >
8+ < title > Contact Me - Tran Huu Dat </ title > <!-- Cập nhật -- >
99 <!-- Favicon-->
1010 < link rel ="icon " type ="image/x-icon " href ="assets/favicon.ico " />
1111 <!-- Custom Google font-->
1212 < link rel ="preconnect " href ="https://fonts.googleapis.com " />
1313 < link rel ="preconnect " href ="https://fonts.gstatic.com " crossorigin />
14- < link href ="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@100;200;300;400;500;600;700;800;900& display=swap " rel ="stylesheet " />
14+ < link href ="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@100;200;300;400;500;600;700;800;900&display=swap " rel ="stylesheet " />
1515 <!-- Bootstrap icons-->
1616 < link href ="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css " rel ="stylesheet " />
1717 <!-- Core theme CSS (includes Bootstrap)-->
1818 < link href ="css/styles.css " rel ="stylesheet " />
19+
20+ <!-- CSS cho Cursor -->
21+ < style >
22+ body {
23+ cursor : none;
24+ position : relative;
25+ }
26+
27+ .cursor-element {
28+ position : fixed;
29+ display : flex;
30+ align-items : center;
31+ pointer-events : none;
32+ z-index : 1070 ;
33+ opacity : 0 ;
34+ transition : opacity 0.3s ease-in-out;
35+ }
36+
37+ .cursor-element .visible {
38+ opacity : 1 ;
39+ }
40+
41+ .cursor-element img {
42+ width : 28px ;
43+ height : auto;
44+ margin-right : 8px ;
45+ }
46+
47+ .cursor-element .cursor-text {
48+ background-color : # 0d6efd ;
49+ color : white;
50+ padding : 6px 12px ;
51+ border-radius : 20px ;
52+ font-size : 0.95em ;
53+ box-shadow : 0 3px 7px rgba (0 , 0 , 0 , 0.15 );
54+ font-weight : bold;
55+ opacity : 1 ;
56+ transition : opacity 0.3s ease-in-out;
57+ }
58+
59+ .cursor-element .cursor-text .fade-out {
60+ opacity : 0 ;
61+ }
62+ </ style >
1963 </ head >
20- < body class ="d-flex flex-column ">
64+ < body class ="d-flex flex-column "> <!-- Bỏ h-100 và bg-light nếu không cần thiết cho trang contact đơn giản -->
2165 < main class ="flex-shrink-0 ">
2266 <!-- Navigation-->
2367 < nav class ="navbar navbar-expand-lg navbar-light bg-white py-3 ">
2468 < div class ="container px-5 ">
25- < a class ="navbar-brand " href ="index.html "> < span class ="fw-bolder text-primary "> Start Bootstrap </ span > </ a >
69+ < a class ="navbar-brand " href ="index.html "> < span class ="fw-bolder text-primary "> Tran Huu Dat </ span > </ a > <!-- Thay tên -- >
2670 < button class ="navbar-toggler " type ="button " data-bs-toggle ="collapse " data-bs-target ="#navbarSupportedContent " aria-controls ="navbarSupportedContent " aria-expanded ="false " aria-label ="Toggle navigation "> < span class ="navbar-toggler-icon "> </ span > </ button >
2771 < div class ="collapse navbar-collapse " id ="navbarSupportedContent ">
2872 < ul class ="navbar-nav ms-auto mb-2 mb-lg-0 small fw-bolder ">
4185 < div class ="bg-light rounded-4 py-5 px-4 px-md-5 ">
4286 < div class ="text-center mb-5 ">
4387 < div class ="feature bg-primary bg-gradient-primary-to-secondary text-white rounded-3 mb-3 "> < i class ="bi bi-envelope "> </ i > </ div >
44- < h1 class ="fw-bolder "> Get in touch </ h1 >
45- < p class ="lead fw-normal text-muted mb-0 "> Let's work together! </ p >
88+ < h1 class ="fw-bolder "> Get in Touch </ h1 >
89+ < p class ="lead fw-normal text-muted mb-0 "> I'd love to hear from you! Let's connect. </ p > <!-- Thay đổi text -- >
4690 </ div >
4791 < div class ="row gx-5 justify-content-center ">
4892 < div class ="col-lg-8 col-xl-6 ">
49- <!-- * * * * * * * * * * * * * * *-->
50- <!-- * * SB Forms Contact Form * *-->
51- <!-- * * * * * * * * * * * * * * *-->
52- <!-- This form is pre-integrated with SB Forms.-->
53- <!-- To make this form functional, sign up at-->
54- <!-- https://startbootstrap.com/solution/contact-forms-->
55- <!-- to get an API token!-->
56- < form id ="contactForm " data-sb-form-api-token ="API_TOKEN ">
93+ <!-- SB Forms Contact Form -->
94+ <!-- Để form này hoạt động, bạn CẦN thay thế API_TOKEN bằng token của bạn từ startbootstrap.com/solution/contact-forms -->
95+ <!-- Hoặc thay thế bằng dịch vụ khác/hiển thị thông tin liên hệ trực tiếp -->
96+ < form id ="contactForm " data-sb-form-api-token ="API_TOKEN_CUA_BAN "> <!-- THAY THẾ API_TOKEN -->
5797 <!-- Name input-->
5898 < div class ="form-floating mb-3 ">
5999 < input class ="form-control " id ="name " type ="text " placeholder ="Enter your name... " data-sb-validations ="required " />
@@ -67,11 +107,11 @@ <h1 class="fw-bolder">Get in touch</h1>
67107 < div class ="invalid-feedback " data-sb-feedback ="email:required "> An email is required.</ div >
68108 < div class ="invalid-feedback " data-sb-feedback ="email:email "> Email is not valid.</ div >
69109 </ div >
70- <!-- Phone number input-->
110+ <!-- Phone number input (Optional - bạn có thể xóa nếu không cần) -->
71111 < div class ="form-floating mb-3 ">
72- < input class ="form-control " id ="phone " type ="tel " placeholder ="(123) 456-7890 " data-sb-validations =" required " / >
73- < label for ="phone "> Phone number</ label >
74- < div class ="invalid-feedback " data-sb-feedback ="phone:required "> A phone number is required.</ div >
112+ < input class ="form-control " id ="phone " type ="tel " placeholder ="(123) 456-7890 " data-sb-validations /> <!-- Bỏ required nếu không bắt buộc -- >
113+ < label for ="phone "> Phone number (Optional) </ label >
114+ <!-- < div class="invalid-feedback" data-sb-feedback="phone:required">A phone number is required.</div> -- >
75115 </ div >
76116 <!-- Message input-->
77117 < div class ="form-floating mb-3 ">
@@ -80,25 +120,25 @@ <h1 class="fw-bolder">Get in touch</h1>
80120 < div class ="invalid-feedback " data-sb-feedback ="message:required "> A message is required.</ div >
81121 </ div >
82122 <!-- Submit success message-->
83- <!---->
84- <!-- This is what your users will see when the form-->
85- <!-- has successfully submitted-->
86123 < div class ="d-none " id ="submitSuccessMessage ">
87124 < div class ="text-center mb-3 ">
88- < div class ="fw-bolder "> Form submission successful!</ div >
89- To activate this form, sign up at
90- < br />
91- < a href ="https://startbootstrap.com/solution/contact-forms "> https://startbootstrap.com/solution/contact-forms</ a >
125+ < div class ="fw-bolder "> Form submission successful! Thank you.</ div >
126+ <!-- Bạn có thể xóa dòng về việc activate form nếu đã có token -->
92127 </ div >
93128 </ div >
94129 <!-- Submit error message-->
95- <!---->
96- <!-- This is what your users will see when there is-->
97- <!-- an error submitting the form-->
98- < div class ="d-none " id ="submitErrorMessage "> < div class ="text-center text-danger mb-3 "> Error sending message!</ div > </ div >
130+ < div class ="d-none " id ="submitErrorMessage "> < div class ="text-center text-danger mb-3 "> Error sending message! Please try again.</ div > </ div >
99131 <!-- Submit Button-->
100- < div class ="d-grid "> < button class ="btn btn-primary btn-lg disabled " id ="submitButton " type ="submit "> Submit</ button > </ div >
132+ < div class ="d-grid "> < button class ="btn btn-primary btn-lg " id ="submitButton " type ="submit "> Submit</ button > </ div > <!-- Bỏ disabled nếu bạn đã có API_TOKEN -- >
101133 </ form >
134+ < hr class ="my-5 "> <!-- Thêm đường kẻ ngang -->
135+ < div class ="text-center ">
136+ < p class ="lead fw-normal text-muted mb-2 "> Or reach out directly:</ p >
137+ < p class ="mb-1 "> < i class ="bi bi-envelope-fill text-primary me-2 "> </ i > < a href ="mailto:huudat.peashooer@gmail.com "> huudat.peashooer@gmail.com</ a > </ p >
138+ < p class ="mb-0 "> <!-- Thêm link LinkedIn nếu muốn -->
139+ < i class ="bi bi-linkedin text-primary me-2 "> </ i > < a href ="YOUR_LINKEDIN_URL " target ="_blank " rel ="noopener noreferrer "> Your LinkedIn Profile</ a >
140+ </ p >
141+ </ div >
102142 </ div >
103143 </ div >
104144 </ div >
@@ -109,25 +149,100 @@ <h1 class="fw-bolder">Get in touch</h1>
109149 < footer class ="bg-white py-4 mt-auto ">
110150 < div class ="container px-5 ">
111151 < div class ="row align-items-center justify-content-between flex-column flex-sm-row ">
112- < div class ="col-auto "> < div class ="small m-0 "> Copyright © Your Website 2023 </ div > </ div >
152+ < div class ="col-auto "> < div class ="small m-0 "> Copyright © Tran Huu Dat 2024 </ div > </ div > <!-- Cập nhật -- >
113153 < div class ="col-auto ">
114154 < a class ="small " href ="#! "> Privacy</ a >
115- < span class ="mx-1 "> · </ span >
155+ < span class ="mx-1 "> · </ span >
116156 < a class ="small " href ="#! "> Terms</ a >
117- < span class ="mx-1 "> · </ span >
118- < a class ="small " href ="#! "> Contact</ a >
157+ < span class ="mx-1 "> · </ span >
158+ < a class ="small " href ="contact.html "> Contact</ a >
119159 </ div >
120160 </ div >
121161 </ div >
122162 </ footer >
163+
164+ <!-- Cursor Element HTML -->
165+ < div class ="cursor-element ">
166+ < img src ="assets/cursor_blue.png " alt ="Custom Cursor Icon "> <!-- Đảm bảo có file này -->
167+ < span class ="cursor-text "> Huu Dat</ span >
168+ </ div >
169+
123170 <!-- Bootstrap core JS-->
124171 < script src ="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js "> </ script >
125172 <!-- Core theme JS-->
126- < script src ="js/scripts.js "> </ script >
127- <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->
128- <!-- * * SB Forms JS * *-->
129- <!-- * * Activate your form at https://startbootstrap.com/solution/contact-forms * *-->
130- <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->
173+ < script src ="js/scripts.js "> </ script > <!-- JS của template -->
174+ <!-- SB Forms JS -->
131175 < script src ="https://cdn.startbootstrap.com/sb-forms-latest.js "> </ script >
176+
177+ <!-- JavaScript cho Cursor -->
178+ < script >
179+ const cursorElement = document . querySelector ( '.cursor-element' ) ;
180+ const cursorTextElement = cursorElement . querySelector ( '.cursor-text' ) ;
181+ // Không cần gridItems trên trang contact này
182+ // const gridItems = document.querySelectorAll('.interactive-grid .grid-item');
183+
184+ let autoTextCurrentIndex = 0 ;
185+ let autoTextInterval ;
186+ let isTextFading = false ;
187+
188+ const autoTexts = [
189+ "Let's connect!" , // Thay đổi text cho phù hợp với trang contact
190+ "Ask me anything" ,
191+ "Project inquiry?" ,
192+ "Say Hello!"
193+ ] ;
194+
195+ function updateCursorPosition ( x , y ) {
196+ if ( ! cursorElement ) return ;
197+ cursorElement . style . left = x + 'px' ;
198+ cursorElement . style . top = y + 'px' ;
199+ if ( ! cursorElement . classList . contains ( 'visible' ) ) {
200+ cursorElement . classList . add ( 'visible' ) ;
201+ }
202+ }
203+
204+ function changeCursorTextWithFade ( newText ) {
205+ if ( ! cursorTextElement || isTextFading || cursorTextElement . textContent === newText ) {
206+ return ;
207+ }
208+ isTextFading = true ;
209+ cursorTextElement . classList . add ( 'fade-out' ) ;
210+
211+ setTimeout ( ( ) => {
212+ cursorTextElement . textContent = newText ;
213+ cursorTextElement . classList . remove ( 'fade-out' ) ;
214+ isTextFading = false ;
215+ } , 300 ) ;
216+ }
217+
218+ function updateAutoCursorText ( ) {
219+ // Trên trang contact, chúng ta không cần kiểm tra hover qua grid item
220+ const newTextToShow = autoTexts [ autoTextCurrentIndex ] ;
221+ autoTextCurrentIndex = ( autoTextCurrentIndex + 1 ) % autoTexts . length ;
222+ changeCursorTextWithFade ( newTextToShow ) ;
223+ }
224+
225+ if ( cursorElement ) {
226+ document . addEventListener ( 'mousemove' , ( e ) => {
227+ updateCursorPosition ( e . clientX , e . clientY ) ;
228+ } ) ;
229+ }
230+
231+ if ( cursorTextElement ) { // Chỉ chạy nếu có cursorTextElement
232+ updateAutoCursorText ( ) ; // Hiển thị text đầu tiên
233+ autoTextInterval = setInterval ( updateAutoCursorText , 3000 ) ;
234+ }
235+
236+ if ( cursorElement ) {
237+ function initialCursorShow ( ) {
238+ if ( ! cursorElement . classList . contains ( 'visible' ) ) {
239+ cursorElement . classList . add ( 'visible' ) ;
240+ }
241+ }
242+ setTimeout ( initialCursorShow , 100 ) ;
243+ } else {
244+ console . error ( "Cursor element not found for initial show!" ) ;
245+ }
246+ </ script >
132247 </ body >
133- </ html >
248+ </ html >
0 commit comments